PageSourceSearch

https://senoo-cl.com/js/swiper.js

js senoo-cl.com collected 2026-10-06 08:58:31 UTC 240,080 bytes, 5,296 lines download raw bytes

1/**
2 * Swiper 3.4.0
3 * Most modern mobile touch slider and framework with hardware accelerated transitions
4 * 
5 * https://www.idangero.us/swiper/
6 * 
7 * Copyright 2016, Vladimir Kharlampidi
8 * The iDangero.us
9 * https://www.idangero.us/
10 * 
11 * Licensed under MIT
12 * 
13 * Released on: October 16, 2016
14 */
15(function () {
16    'use strict';
17    var $;
18    /*===========================
19    Swiper
20    ===========================*/
21    var Swiper = function (container, params) {
22        if (!(this instanceof Swiper)) return new Swiper(container, params);
23
24        var defaults = {
25            direction: 'horizontal',
26            touchEventsTarget: 'container',
27            initialSlide: 0,
28            speed: 300,
29            // autoplay
30            autoplay: false,
31            autoplayDisableOnInteraction: true,
32            autoplayStopOnLast: false,
33            // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).
34            iOSEdgeSwipeDetection: false,
35            iOSEdgeSwipeThreshold: 20,
36            // Free mode
37            freeMode: false,
38            freeModeMomentum: true,
39            freeModeMomentumRatio: 1,
40            freeModeMomentumBounce: true,
41            freeModeMomentumBounceRatio: 1,
42            freeModeMomentumVelocityRatio: 1,
43            freeModeSticky: false,
44            freeModeMinimumVelocity: 0.02,
45            // Autoheight
46            autoHeight: false,
47            // Set wrapper width
48            setWrapperSize: false,
49            // Virtual Translate
50            virtualTranslate: false,
51            // Effects
52            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
53            coverflow: {
54                rotate: 50,
55                stretch: 0,
56                depth: 100,
57                modifier: 1,
58                slideShadows : true
59            },
60            flip: {
61                slideShadows : true,
62                limitRotation: true
63            },
64            cube: {
65                slideShadows: true,
66                shadow: true,
67                shadowOffset: 20,
68                shadowScale: 0.94
69            },
70            fade: {
71                crossFade: false
72            },
73            // Parallax
74            parallax: false,
75            // Zoom
76            zoom: false,
77            zoomMax: 3,
78            zoomMin: 1,
79            zoomToggle: true,
80            // Scrollbar
81            scrollbar: null,
82            scrollbarHide: true,
83            scrollbarDraggable: false,
84            scrollbarSnapOnRelease: false,
85            // Keyboard Mousewheel
86            keyboardControl: false,
87            mousewheelControl: false,
88            mousewheelReleaseOnEdges: false,
89            mousewheelInvert: false,
90            mousewheelForceToAxis: false,
91            mousewheelSensitivity: 1,
92            mousewheelEventsTarged: 'container',
93            // Hash Navigation
94            hashnav: false,
95            hashnavWatchState: false,
96            // History
97            history: false,
98            // Commong Nav State
99            replaceState: false,
100            // Breakpoints
101            breakpoints: undefined,
102            // Slides grid
103            spaceBetween: 0,
104            slidesPerView: 1,
105            slidesPerColumn: 1,
106            slidesPerColumnFill: 'column',
107            slidesPerGroup: 1,
108            centeredSlides: false,
109            slidesOffsetBefore: 0, // in px
110            slidesOffsetAfter: 0, // in px
111            // Round length
112            roundLengths: false,
113            // Touches
114            touchRatio: 1,
115            touchAngle: 45,
116            simulateTouch: true,
117            shortSwipes: true,
118            longSwipes: true,
119            longSwipesRatio: 0.5,
120            longSwipesMs: 300,
121            followFinger: true,
122            onlyExternal: false,
123            threshold: 0,
124            touchMoveStopPropagation: true,
125            touchReleaseOnEdges: false,
126            // Unique Navigation Elements
127            uniqueNavElements: true,
128            // Pagination
129            pagination: null,
130            paginationElement: 'span',
131            paginationClickable: false,
132            paginationHide: false,
133            paginationBulletRender: null,
134            paginationProgressRender: null,
135            paginationFractionRender: null,
136            paginationCustomRender: null,
137            paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'
138            // Resistance
139            resistance: true,
140            resistanceRatio: 0.85,
141            // Next/prev buttons
142            nextButton: null,
143            prevButton: null,
144            // Progress
145            watchSlidesProgress: false,
146            watchSlidesVisibility: false,
147            // Cursor
148            grabCursor: false,
149            // Clicks
150            preventClicks: true,
151            preventClicksPropagation: true,
152            slideToClickedSlide: false,
153            // Lazy Loading
154            lazyLoading: false,
155            lazyLoadingInPrevNext: false,
156            lazyLoadingInPrevNextAmount: 1,
157            lazyLoadingOnTransitionStart: false,
158            // Images
159            preloadImages: true,
160            updateOnImagesReady: true,
161            // loop
162            loop: false,
163            loopAdditionalSlides: 0,
164            loopedSlides: null,
165            // Control
166            control: undefined,
167            controlInverse: false,
168            controlBy: 'slide', //or 'container'
169            normalizeSlideIndex: true,
170            // Swiping/no swiping
171            allowSwipeToPrev: true,
172            allowSwipeToNext: true,
173            swipeHandler: null, //'.swipe-handler',
174            noSwiping: true,
175            noSwipingClass: 'swiper-no-swiping',
176            // Passive Listeners
177            passiveListeners: true,
178            // NS
179            containerModifierClass: 'swiper-container-', // NEW
180            slideClass: 'swiper-slide',
181            slideActiveClass: 'swiper-slide-active',
182            slideDuplicateActiveClass: 'swiper-slide-duplicate-active',
183            slideVisibleClass: 'swiper-slide-visible',
184            slideDuplicateClass: 'swiper-slide-duplicate',
185            slideNextClass: 'swiper-slide-next',
186            slideDuplicateNextClass: 'swiper-slide-duplicate-next',
187            slidePrevClass: 'swiper-slide-prev',
188            slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',
189            wrapperClass: 'swiper-wrapper',
190            bulletClass: 'swiper-pagination-bullet',
191            bulletActiveClass: 'swiper-pagination-bullet-active',
192            buttonDisabledClass: 'swiper-button-disabled',
193            paginationCurrentClass: 'swiper-pagination-current',
194            paginationTotalClass: 'swiper-pagination-total',
195            paginationHiddenClass: 'swiper-pagination-hidden',
196            paginationProgressbarClass: 'swiper-pagination-progressbar',
197            paginationClickableClass: 'swiper-pagination-clickable', // NEW
198            paginationModifierClass: 'swiper-pagination-', // NEW
199            lazyLoadingClass: 'swiper-lazy',
200            lazyStatusLoadingClass: 'swiper-lazy-loading',
201            lazyStatusLoadedClass: 'swiper-lazy-loaded',
202            lazyPreloaderClass: 'swiper-lazy-preloader',
203            notificationClass: 'swiper-notification',
204            preloaderClass: 'preloader',
205            zoomContainerClass: 'swiper-zoom-container',
206        
207            // Observer
208            observer: false,
209            observeParents: false,
210            // Accessibility
211            a11y: false,
212            prevSlideMessage: 'Previous slide',
213            nextSlideMessage: 'Next slide',
214            firstSlideMessage: 'This is the first slide',
215            lastSlideMessage: 'This is the last slide',
216            paginationBulletMessage: 'Go to slide {{index}}',
217            // Callbacks
218            runCallbacksOnInit: true
219            /*
220            Callbacks:
221            onInit: function (swiper)
222            onDestroy: function (swiper)
223            onClick: function (swiper, e)
224            onTap: function (swiper, e)
225            onDoubleTap: function (swiper, e)
226            onSliderMove: function (swiper, e)
227            onSlideChangeStart: function (swiper)
228            onSlideChangeEnd: function (swiper)
229            onTransitionStart: function (swiper)
230            onTransitionEnd: function (swiper)
231            onImagesReady: function (swiper)
232            onProgress: function (swiper, progress)
233            onTouchStart: function (swiper, e)
234            onTouchMove: function (swiper, e)
235            onTouchMoveOpposite: function (swiper, e)
236            onTouchEnd: function (swiper, e)
237            onReachBeginning: function (swiper)
238            onReachEnd: function (swiper)
239            onSetTransition: function (swiper, duration)
240            onSetTranslate: function (swiper, translate)
241            onAutoplayStart: function (swiper)
242            onAutoplayStop: function (swiper),
243            onLazyImageLoad: function (swiper, slide, image)
244            onLazyImageReady: function (swiper, slide, image)
245            */
246        
247        };
248        var initialVirtualTranslate = params && params.virtualTranslate;
249        
250        params = params || {};
251        var originalParams = {};
252        for (var param in params) {
253            if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {
254                originalParams[param] = {};
255                for (var deepParam in params[param]) {
256                    originalParams[param][deepParam] = params[param][deepParam];
257                }
258            }
259            else {
260                originalParams[param] = params[param];
261            }
262        }
263        for (var def in defaults) {
264            if (typeof params[def] === 'undefined') {
265                params[def] = defaults[def];
266            }
267            else if (typeof params[def] === 'object') {
268                for (var deepDef in defaults[def]) {
269                    if (typeof params[def][deepDef] === 'undefined') {
270                        params[def][deepDef] = defaults[def][deepDef];
271                    }
272                }
273            }
274        }
275        
276        // Swiper
277        var s = this;
278        
279        // Params
280        s.params = params;
281        s.originalParams = originalParams;
282        
283        // Classname
284        s.classNames = [];
285        /*=========================
286          Dom Library and plugins
287          ===========================*/
288        if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){
289            $ = Dom7;
290        }
291        if (typeof $ === 'undefined') {
292            if (typeof Dom7 === 'undefined') {
293                $ = window.Dom7 || window.Zepto || window.jQuery;
294            }
295            else {
296                $ = Dom7;
297            }
298            if (!$) return;
299        }
300        // Export it to Swiper instance
301        s.$ = $;
302        
303        /*=========================
304          Breakpoints
305          ===========================*/
306        s.currentBreakpoint = undefined;
307        s.getActiveBreakpoint = function () {
308            //Get breakpoint for window width
309            if (!s.params.breakpoints) return false;
310            var breakpoint = false;
311            var points = [], point;
312            for ( point in s.params.breakpoints ) {
313                if (s.params.breakpoints.hasOwnProperty(point)) {
314                    points.push(point);
315                }
316            }
317            points.sort(function (a, b) {
318                return parseInt(a, 10) > parseInt(b, 10);
319            });
320            for (var i = 0; i < points.length; i++) {
321                point = points[i];
322                if (point >= window.innerWidth && !breakpoint) {
323                    breakpoint = point;
324                }
325            }
326            return breakpoint || 'max';
327        };
328        s.setBreakpoint = function () {
329            //Set breakpoint for window width and update parameters
330            var breakpoint = s.getActiveBreakpoint();
331            if (breakpoint && s.currentBreakpoint !== breakpoint) {
332                var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;
333                var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);
334                for ( var param in breakPointsParams ) {
335                    s.params[param] = breakPointsParams[param];
336                }
337                s.currentBreakpoint = breakpoint;
338                if(needsReLoop && s.destroyLoop) {
339                    s.reLoop(true);
340                }
341            }
342        };
343        // Set breakpoint on load
344        if (s.params.breakpoints) {
345            s.setBreakpoint();
346        }
347        
348        /*=========================
349          Preparation - Define Container, Wrapper and Pagination
350          ===========================*/
351        s.container = $(container);
352        if (s.container.length === 0) return;
353        if (s.container.length > 1) {
354            var swipers = [];
355            s.container.each(function () {
356                var container = this;
357                swipers.push(new Swiper(this, params));
358            });
359            return swipers;
360        }
361        
362        // Save instance in container HTML Element and in data
363        s.container[0].swiper = s;
364        s.container.data('swiper', s);
365        
366        s.classNames.push(s.params.containerModifierClass + s.params.direction);
367        
368        if (s.params.freeMode) {
369            s.classNames.push(s.params.containerModifierClass + 'free-mode');
370        }
371        if (!s.support.flexbox) {
372            s.classNames.push(s.params.containerModifierClass + 'no-flexbox');
373            s.params.slidesPerColumn = 1;
374        }
375        if (s.params.autoHeight) {
376            s.classNames.push(s.params.containerModifierClass + 'autoheight');
377        }
378        // Enable slides progress when required
379        if (s.params.parallax || s.params.watchSlidesVisibility) {
380            s.params.watchSlidesProgress = true;
381        }
382        // Max resistance when touchReleaseOnEdges
383        if (s.params.touchReleaseOnEdges) {
384            s.params.resistanceRatio = 0;
385        }
386        // Coverflow / 3D
387        if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {
388            if (s.support.transforms3d) {
389                s.params.watchSlidesProgress = true;
390                s.classNames.push(s.params.containerModifierClass + '3d');
391            }
392            else {
393                s.params.effect = 'slide';
394            }
395        }
396        if (s.params.effect !== 'slide') {
397            s.classNames.push(s.params.containerModifierClass + s.params.effect);
398        }
399        if (s.params.effect === 'cube') {
400            s.params.resistanceRatio = 0;
401            s.params.slidesPerView = 1;
402            s.params.slidesPerColumn = 1;
403            s.params.slidesPerGroup = 1;
404            s.params.centeredSlides = false;
405            s.params.spaceBetween = 0;
406            s.params.virtualTranslate = true;
407            s.params.setWrapperSize = false;
408        }
409        if (s.params.effect === 'fade' || s.params.effect === 'flip') {
410            s.params.slidesPerView = 1;
411            s.params.slidesPerColumn = 1;
412            s.params.slidesPerGroup = 1;
413            s.params.watchSlidesProgress = true;
414            s.params.spaceBetween = 0;
415            s.params.setWrapperSize = false;
416            if (typeof initialVirtualTranslate === 'undefined') {
417                s.params.virtualTranslate = true;
418            }
419        }
420        
421        // Grab Cursor
422        if (s.params.grabCursor && s.support.touch) {
423            s.params.grabCursor = false;
424        }
425        
426        // Wrapper
427        s.wrapper = s.container.children('.' + s.params.wrapperClass);
428        
429        // Pagination
430        if (s.params.pagination) {
431            s.paginationContainer = $(s.params.pagination);
432            if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {
433                s.paginationContainer = s.container.find(s.params.pagination);
434            }
435        
436            if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {
437                s.paginationContainer.addClass(s.params.paginationModifierClass + 'clickable');
438            }
439            else {
440                s.params.paginationClickable = false;
441            }
442            s.paginationContainer.addClass(s.params.paginationModifierClass + s.params.paginationType);
443        }
444        // Next/Prev Buttons
445        if (s.params.nextButton || s.params.prevButton) {
446            if (s.params.nextButton) {
447                s.nextButton = $(s.params.nextButton);
448                if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {
449                    s.nextButton = s.container.find(s.params.nextButton);
450                }
451            }
452            if (s.params.prevButton) {
453                s.prevButton = $(s.params.prevButton);
454                if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {
455                    s.prevButton = s.container.find(s.params.prevButton);
456                }
457            }
458        }
459        
460        // Is Horizontal
461        s.isHorizontal = function () {
462            return s.params.direction === 'horizontal';
463        };
464        // s.isH = isH;
465        
466        // RTL
467        s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');
468        if (s.rtl) {
469            s.classNames.push(s.params.containerModifierClass + 'rtl');
470        }
471        
472        // Wrong RTL support
473        if (s.rtl) {
474            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';
475        }
476        
477        // Columns
478        if (s.params.slidesPerColumn > 1) {
479            s.classNames.push(s.params.containerModifierClass + 'multirow');
480        }
481        
482        // Check for Android
483        if (s.device.android) {
484            s.classNames.push(s.params.containerModifierClass + 'android');
485        }
486        
487        // Add classes
488        s.container.addClass(s.classNames.join(' '));
489        
490        // Translate
491        s.translate = 0;
492        
493        // Progress
494        s.progress = 0;
495        
496        // Velocity
497        s.velocity = 0;
498        
499        /*=========================
500          Locks, unlocks
501          ===========================*/
502        s.lockSwipeToNext = function () {
503            s.params.allowSwipeToNext = false;
504            if (s.params.allowSwipeToPrev === false && s.params.grabCursor) {
505                s.unsetGrabCursor();
506            }
507        };
508        s.lockSwipeToPrev = function () {
509            s.params.allowSwipeToPrev = false;
510            if (s.params.allowSwipeToNext === false && s.params.grabCursor) {
511                s.unsetGrabCursor();
512            }
513        };
514        s.lockSwipes = function () {
515            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;
516            if (s.params.grabCursor) s.unsetGrabCursor();
517        };
518        s.unlockSwipeToNext = function () {
519            s.params.allowSwipeToNext = true;
520            if (s.params.allowSwipeToPrev === true && s.params.grabCursor) {
521                s.setGrabCursor();
522            }
523        };
524        s.unlockSwipeToPrev = function () {
525            s.params.allowSwipeToPrev = true;
526            if (s.params.allowSwipeToNext === true && s.params.grabCursor) {
527                s.setGrabCursor();
528            }
529        };
530        s.unlockSwipes = function () {
531            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;
532            if (s.params.grabCursor) s.setGrabCursor();
533        };
534        
535        /*=========================
536          Round helper
537          ===========================*/
538        function round(a) {
539            return Math.floor(a);
540        }
541        /*=========================
542          Set grab cursor
543          ===========================*/
544        s.setGrabCursor = function(moving) {
545            s.container[0].style.cursor = 'move';
546            s.container[0].style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab';
547            s.container[0].style.cursor = moving ? '-moz-grabbin' : '-moz-grab';
548            s.container[0].style.cursor = moving ? 'grabbing': 'grab';
549        };
550        s.unsetGrabCursor = function () {
551            s.container[0].style.cursor = '';
552        };
553        if (s.params.grabCursor) {
554            s.setGrabCursor();
555        }
556        /*=========================
557          Update on Images Ready
558          ===========================*/
559        s.imagesToLoad = [];
560        s.imagesLoaded = 0;
561        
562        s.loadImage = function (imgElement, src, srcset, sizes, checkForComplete, callback) {
563            var image;
564            function onReady () {
565                if (callback) callback();
566            }
567            if (!imgElement.complete || !checkForComplete) {
568                if (src) {
569                    image = new window.Image();
570                    image.onload = onReady;
571                    image.onerror = onReady;
572                    if (sizes) {
573                        image.sizes = sizes;
574                    }
575                    if (srcset) {
576                        image.srcset = srcset;
577                    }
578                    if (src) {
579                        image.src = src;
580                    }
581                } else {
582                    onReady();
583                }
584        
585            } else {//image already loaded...
586                onReady();
587            }
588        };
589        s.preloadImages = function () {
590            s.imagesToLoad = s.container.find('img');
591            function _onReady() {
592                if (typeof s === 'undefined' || s === null) return;
593                if (s.imagesLoaded !== undefined) s.imagesLoaded++;
594                if (s.imagesLoaded === s.imagesToLoad.length) {
595                    if (s.params.updateOnImagesReady) s.update();
596                    s.emit('onImagesReady', s);
597                }
598            }
599            for (var i = 0; i < s.imagesToLoad.length; i++) {
600                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), s.imagesToLoad[i].sizes || s.imagesToLoad[i].getAttribute('sizes'), true, _onReady);
601            }
602        };
603        
604        /*=========================
605          Autoplay
606          ===========================*/
607        s.autoplayTimeoutId = undefined;
608        s.autoplaying = false;
609        s.autoplayPaused = false;
610        function autoplay() {
611            var autoplayDelay = s.params.autoplay;
612            var activeSlide = s.slides.eq(s.activeIndex);
613            if (activeSlide.attr('data-swiper-autoplay')) {
614                autoplayDelay = activeSlide.attr('data-swiper-autoplay') || s.params.autoplay;
615            }
616            s.autoplayTimeoutId = setTimeout(function () {
617                if (s.params.loop) {
618                    s.fixLoop();
619                    s._slideNext();
620                    s.emit('onAutoplay', s);
621                }
622                else {
623                    if (!s.isEnd) {
624                        s._slideNext();
625                        s.emit('onAutoplay', s);
626                    }
627                    else {
628                        if (!params.autoplayStopOnLast) {
629                            s._slideTo(0);
630                            s.emit('onAutoplay', s);
631                        }
632                        else {
633                            s.stopAutoplay();
634                        }
635                    }
636                }
637            }, autoplayDelay);
638        }
639        s.startAutoplay = function () {
640            if (typeof s.autoplayTimeoutId !== 'undefined') return false;
641            if (!s.params.autoplay) return false;
642            if (s.autoplaying) return false;
643            s.autoplaying = true;
644            s.emit('onAutoplayStart', s);
645            autoplay();
646        };
647        s.stopAutoplay = function (internal) {
648            if (!s.autoplayTimeoutId) return;
649            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
650            s.autoplaying = false;
651            s.autoplayTimeoutId = undefined;
652            s.emit('onAutoplayStop', s);
653        };
654        s.pauseAutoplay = function (speed) {
655            if (s.autoplayPaused) return;
656            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
657            s.autoplayPaused = true;
658            if (speed === 0) {
659                s.autoplayPaused = false;
660                autoplay();
661            }
662            else {
663                s.wrapper.transitionEnd(function () {
664                    if (!s) return;
665                    s.autoplayPaused = false;
666                    if (!s.autoplaying) {
667                        s.stopAutoplay();
668                    }
669                    else {
670                        autoplay();
671                    }
672                });
673            }
674        };
675        /*=========================
676          Min/Max Translate
677          ===========================*/
678        s.minTranslate = function () {
679            return (-s.snapGrid[0]);
680        };
681        s.maxTranslate = function () {
682            return (-s.snapGrid[s.snapGrid.length - 1]);
683        };
684        /*=========================
685          Slider/slides sizes
686          ===========================*/
687        s.updateAutoHeight = function () {
688            var activeSlides = [];
689            var newHeight = 0;
690        
691            // Find slides currently in view
692            if(s.params.slidesPerView !== 'auto' && s.params.slidesPerView > 1) {
693                for (i = 0;
693 i < Math.ceil(s.params.slidesPerView); i++) {
694                    var index = s.activeIndex + i;
695                    if(index > s.slides.length) break;
696                    activeSlides.push(s.slides.eq(index)[0]);
697                }
698            } else {
699                activeSlides.push(s.slides.eq(s.activeIndex)[0]);
700            }
701        
702            // Find new height from heighest slide in view
703            for (i = 0; i < activeSlides.length; i++) {
704                if (typeof activeSlides[i] !== 'undefined') {
705                    var height = activeSlides[i].offsetHeight;
706                    newHeight = height > newHeight ? height : newHeight;
707                }
708            }
709        
710            // Update Height
711            if (newHeight) s.wrapper.css('height', newHeight + 'px');
712        };
713        s.updateContainerSize = function () {
714            var width, height;
715            if (typeof s.params.width !== 'undefined') {
716                width = s.params.width;
717            }
718            else {
719                width = s.container[0].clientWidth;
720            }
721            if (typeof s.params.height !== 'undefined') {
722                height = s.params.height;
723            }
724            else {
725                height = s.container[0].clientHeight;
726            }
727            if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {
728                return;
729            }
730        
731            //Subtract paddings
732            width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);
733            height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);
734        
735            // Store values
736            s.width = width;
737            s.height = height;
738            s.size = s.isHorizontal() ? s.width : s.height;
739        };
740        
741        s.updateSlidesSize = function () {
742            s.slides = s.wrapper.children('.' + s.params.slideClass);
743            s.snapGrid = [];
744            s.slidesGrid = [];
745            s.slidesSizesGrid = [];
746        
747            var spaceBetween = s.params.spaceBetween,
748                slidePosition = -s.params.slidesOffsetBefore,
749                i,
750                prevSlideSize = 0,
751                index = 0;
752            if (typeof s.size === 'undefined') return;
753            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
754                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;
755            }
756        
757            s.virtualSize = -spaceBetween;
758            // reset margins
759            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});
760            else s.slides.css({marginRight: '', marginBottom: ''});
761        
762            var slidesNumberEvenToRows;
763            if (s.params.slidesPerColumn > 1) {
764                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {
765                    slidesNumberEvenToRows = s.slides.length;
766                }
767                else {
768                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;
769                }
770                if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {
771                    slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);
772                }
773            }
774        
775            // Calc slides
776            var slideSize;
777            var slidesPerColumn = s.params.slidesPerColumn;
778            var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
779            var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);
780            for (i = 0; i < s.slides.length; i++) {
781                slideSize = 0;
782                var slide = s.slides.eq(i);
783                if (s.params.slidesPerColumn > 1) {
784                    // Set slides order
785                    var newSlideOrderIndex;
786                    var column, row;
787                    if (s.params.slidesPerColumnFill === 'column') {
788                        column = Math.floor(i / slidesPerColumn);
789                        row = i - column * slidesPerColumn;
790                        if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {
791                            if (++row >= slidesPerColumn) {
792                                row = 0;
793                                column++;
794                            }
795                        }
796                        newSlideOrderIndex = column + row * slidesNumber
796EvenToRows / slidesPerColumn;
797                        slide
798                            .css({
799                                '-webkit-box-ordinal-group': newSlideOrderIndex,
800                                '-moz-box-ordinal-group': newSlideOrderIndex,
801                                '-ms-flex-order': newSlideOrderIndex,
802                                '-webkit-order': newSlideOrderIndex,
803                                'order': newSlideOrderIndex
804                            });
805                    }
806                    else {
807                        row = Math.floor(i / slidesPerRow);
808                        column = i - row * slidesPerRow;
809                    }
810                    slide
811                        .css(
812                            'margin-' + (s.isHorizontal() ? 'top' : 'left'),
813                            (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')
814                        )
815                        .attr('data-swiper-column', column)
816                        .attr('data-swiper-row', row);
817        
818                }
819                if (slide.css('display') === 'none') continue;
820                if (s.params.slidesPerView === 'auto') {
821                    slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);
822                    if (s.params.roundLengths) slideSize = round(slideSize);
823                }
824                else {
825                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;
826                    if (s.params.roundLengths) slideSize = round(slideSize);
827        
828                    if (s.isHorizontal()) {
829                        s.slides[i].style.width = slideSize + 'px';
830                    }
831                    else {
832                        s.slides[i].style.height = slideSize + 'px';
833                    }
834                }
835                s.slides[i].swiperSlideSize = slideSize;
836                s.slidesSizesGrid.push(slideSize);
837        
838        
839                if (s.params.centeredSlides) {
840                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
841                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;
842                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
843                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
844                    s.slidesGrid.push(slidePosition);
845                }
846                else {
847                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
848                    s.slidesGrid.push(slidePosition);
849                    slidePosition = slidePosition + slideSize + spaceBetween;
850                }
851        
852                s.virtualSize += slideSize + spaceBetween;
853        
854                prevSlideSize = slideSize;
855        
856                index ++;
857            }
858            s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;
859            var newSlidesGrid;
860        
861            if (
862                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {
863                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
864            }
865            if (!s.support.flexbox || s.params.setWrapperSize) {
866                if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
867                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
868            }
869        
870            if (s.params.slidesPerColumn > 1) {
871                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;
872                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;
873                if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
874                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
875                if (s.params.centeredSlides) {
876                    newSlidesGrid = [];
877                    for (i = 0; i < s.snapGrid.length; i++) {
878                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);
879                    }
880                    s.snapGrid = newSlidesGrid;
881                }
882            }
883        
884            // Remove last grid elements depending on width
885            if (!s.params.centeredSlides) {
886                newSlidesGrid = [];
887                for (i = 0; i < s.snapGrid.length; i++) {
888                    if (s.snapGrid[i] <= s.virtualSize - s.size) {
889                        newSlidesGrid.push(s.snapGrid[i]);
890                    }
891                }
892                s.snapGrid = newSlidesGrid;
893                if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {
894                    s.snapGrid.push(s.virtualSize - s.size);
895                }
896            }
897            if (s.snapGrid.length === 0) s.snapGrid = [0];
898        
899            if (s.params.spaceBetween !== 0) {
900                if (s.isHorizontal()) {
901                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});
902                    else s.slides.css({marginRight: spaceBetween + 'px'});
903                }
904                else s.slides.css({marginBottom: spaceBetween + 'px'});
905            }
906            if (s.params.watchSlidesProgress) {
907                s.updateSlidesOffset();
908            }
909        };
910        s.updateSlidesOffset = function () {
911            for (var i = 0; i < s.slides.length; i++) {
912                s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;
913            }
914        };
915        
916        /*=========================
917          Slider/slides progress
918          ===========================*/
919        s.updateSlidesProgress = function (translate) {
920            if (typeof translate === 'undefined') {
921                translate = s.translate || 0;
922            }
923            if (s.slides.length === 0) return;
924            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();
925        
926            var offsetCenter = -translate;
927            if (s.rtl) offsetCenter = translate;
928        
929            // Visible Slides
930            s.slides.removeClass(s.params.slideVisibleClass);
931            for (var i = 0; i < s.slides.length; i++) {
932                var slide = s.slides[i];
933                var slideProgress = (offsetCenter + (s.params.centeredSlides ? s.minTranslate() : 0) - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);
934                if (s.params.watchSlidesVisibility) {
935                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset);
936                    var slideAfter = slideBefore + s.slidesSizesGrid[i];
937                    var isVisible =
938                        (slideBefore >= 0 && slideBefore < s.size) ||
939                        (slideAfter > 0 && slideAfter <= s.size) ||
940                        (slideBefore <= 0 && slideAfter >= s.size);
941                    if (isVisible) {
942                        s.slides.eq(i).addClass(s.params.slideVisibleClass);
943                    }
944                }
945                slide.progress = s.rtl ? -slideProgress : slideProgress;
946            }
947        };
948        s.updateProgress = function (translate) {
949            if (typeof translate === 'undefined') {
950                translate = s.translate || 0;
951            }
952            var translatesDiff = s.maxTranslate() - s.minTranslate();
953            var wasBeginning = s.isBeginning;
954            var wasEnd = s.isEnd;
955            if (translatesDiff === 0) {
956                s.progress = 0;
957                s.isBeginning = s.isEnd = true;
958            }
959            else {
960                s.progress = (translate - s.minTranslate()) / (translatesDiff);
961                s.isBeginning = s.progress <= 0;
962                s.isEnd = s.progress >= 1;
963            }
964            if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);
965            if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);
966        
967            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);
968            s.emit('onProgress', s, s.progress);
969        };
970        s.updateActiveIndex = function () {
971            var translate = s.rtl ? s.translate : -s.translate;
972            var newActiveIndex, i, snapIndex;
973            for (i = 0; i < s.slidesGrid.length; i ++) {
974                if (typeof s.slidesGrid[i + 1] !== 'undefined') {
975                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {
976                        newActiveIndex = i;
977                    }
978                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {
979                        newActiveIndex = i + 1;
980                    }
981                }
982                else {
983                    if (translate >= s.slidesGrid[i]) {
984                        newActiveIndex = i;
985                    }
986                }
987            }
988            // Normalize slideIndex
989            if(s.params.normalizeSlideIndex){
990                if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;
991            }
992            // for (i = 0; i < s.slidesGrid.length; i++) {
993                // if (- translate >= s.slidesGrid[i]) {
994                    // newActiveIndex = i;
995                // }
996            // }
997            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);
998            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;
999        
1000            if (newActiveIndex === s.activeIndex) {
1001                return;
1002            }
1003            s.snapIndex = snapIndex;
1004            s.previousIndex = s.activeIndex;
1005            s.activeIndex = newActiveIndex;
1006            s.updateClasses();
1007            s.updateRealIndex();
1008        };
1009        s.updateRealIndex = function(){
1010            s.realIndex = s.slides.eq(s.activeIndex).attr('data-swiper-slide-index') || s.activeIndex;
1011        };
1012        
1013        /*=========================
1014          Classes
1015          ===========================*/
1016        s.updateClasses = function () {
1017            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass + ' ' + s.params.slideDuplicateActiveClass + ' ' + s.params.slideDuplicateNextClass + ' ' + s.params.slideDuplicatePrevClass);
1018            var activeSlide = s.slides.eq(s.activeIndex);
1019            // Active classes
1020            activeSlide.addClass(s.params.slideActiveClass);
1021            if (params.loop) {
1022                // Duplicate to all looped slides
1023                if (activeSlide.hasClass(s.params.slideDuplicateClass)) {
1024                    s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + s.realIndex + '"]').addClass(s.params.slideDuplicateActiveClass);
1025                }
1026                else {
1027                    s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + s.realIndex + '"]').addClass(s.params.slideDuplicateActiveClass);
1028                }
1029            }
1030            // Next Slide
1031            var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);
1032            if (s.params.loop && nextSlide.length === 0) {
1033                nextSlide = s.slides.eq(0);
1034                nextSlide.addClass(s.params.slideNextClass);
1035            }
1036            // Prev Slide
1037            var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);
1038            if (s.params.loop && prevSlide.length === 0) {
1039                prevSlide = s.slides.eq(-1);
1040                prevSlide.addClass(s.params.slidePrevClass);
1041            }
1042            if (params.loop) {
1043                // Duplicate to all looped slides
1044                if (nextSlide.hasClass(s.params.slideDuplicateClass)) {
1045                    s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + nextSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicateNextClass);
1046                }
1047                else {
1048                    s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + nextSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicateNextClass);
1049                }
1050                if (prevSlide.hasClass(s.params.slideDuplicateClass)) {
1051                    s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + prevSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicatePrevClass);
1052                }
1053                else {
1054                    s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + prevSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicatePrevClass);
1055                }
1056            }
1057        
1058            // Pagination
1059            if (s.paginationContainer && s.paginationContainer.length > 0) {
1060                // Current/Total
1061                var current,
1062                    total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
1063                if (s.params.loop) {
1064                    current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);
1065                    if (current > s.slides.length - 1 - s.loopedSlides * 2) {
1066                        current = current - (s.slides.length - s.loopedSlides * 2);
1067                    }
1068                    if (current > total - 1) current = current - total;
1069                    if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;
1070                }
1071                else {
1072                    if (typeof s.snapIndex !== 'undefined') {
1073                        current = s.snapIndex;
1074                    }
1075                    else {
1076                        current = s.activeIndex || 0;
1077                    }
1078                }
1079                // Types
1080                if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {
1081                    s.bullets.removeClass(s.params.bulletActiveClass);
1082                    if (s.paginationContainer.length > 1) {
1083                        s.bullets.each(function () {
1084                            if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);
1085                        });
1086                    }
1087                    else {
1088                        s.bullets.eq(current).addClass(s.params.bulletActiveClass);
1089                    }
1090                }
1091                if (s.params.paginationType === 'fraction') {
1092                    s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);
1093                    s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);
1094                }
1095                if (s.params.paginationType === 'progress') {
1096                    var scale = (current + 1) / total,
1097                        scaleX = scale,
1098                        scaleY = 1;
1099                    if (!s.isHorizontal()) {
1100                        scaleY = scale;
1101                        scaleX = 1;
1102                    }
1103                    s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);
1104                }
1105                if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {
1106                    s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));
1107                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);
1108                }
1109            }
1110        
1111            // Next/active buttons
1112            if (!s.params.loop) {
1113                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
1114                    if (s.isBeginning) {
1115                        s.prevButton.addClass(s.params.buttonDisabledClass);
1116                        if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);
1117                    }
1118                    else {
1119                        s.prevButton.removeClass(s.params.buttonDisabledClass);
1120                        if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);
1121                    }
1122                }
1123                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
1124                    if (s.isEnd) {
1125                        s.nextButton.addClass(s.params.buttonDisabledClass);
1126                        if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);
1127                    }
1128                    else {
1129                        s.nextButton.removeClass(s.params.buttonDisabledClass);
1130                        if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);
1131                    }
1132                }
1133            }
1134        };
1135        
1136        /*=========================
1137          Pagination
1138          ===========================*/
1139        s.updatePagination = function () {
1140            if (!s.params.pagination) return;
1141            if (s.paginationContainer && s.paginationContainer.length > 0) {
1142                var paginationHTML = '';
1143                if (s.params.paginationType === 'bullets') {
1144                    var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
1145                    for (var i = 0; i < numberOfBullets; i++) {
1146                        if (s.params.paginationBulletRender) {
1147                            paginationHTML += s.params.paginationBulletRender(s, i, s.params.bulletClass);
1148                        }
1149                        else {
1150                            paginationHTML += '<' + s.params.paginationElement+' class="' + s.params.bulletClass + '"></' + s.params.paginationElement + '>';
1151                        }
1152                    }
1153                    s.paginationContainer.html(paginationHTML);
1154                    s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);
1155                    if (s.params.paginationClickable && s.params.a11y && s.a11y) {
1156                        s.a11y.initPagination();
1157                    }
1158                }
1159                if (s.params.paginationType === 'fraction') {
1160                    if (s.params.paginationFractionRender) {
1161                        paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);
1162                    }
1163                    else {
1164                        paginationHTML =
1165                            '<span class="' + s.params.paginationCurrentClass + '"></span>' +
1166                            ' / ' +
1167                            '<span class="' + s.params.paginationTotalClass+'"></span>';
1168                    }
1169                    s.paginationContainer.html(paginationHTML);
1170                }
1171                if (s.params.paginationType === 'progress') {
1172                    if (s.params.paginationProgressRender) {
1173                        paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);
1174                    }
1175                    else {
1176                        paginationHTML = '<span class="' + s.params.paginationProgressbarClass + '"></span>';
1177                    }
1178                    s.paginationContainer.html(paginationHTML);
1179                }
1180                if (s.params.paginationType !== 'custom') {
1181                    s.emit('onPaginationRendered', s, s.paginationContainer[0]);
1182                }
1183            }
1184        };
1185        /*=========================
1186          Common update method
1187          ===========================*/
1188        s.update = function (updateTranslate) {
1189            s.updateContainerSize();
1190            s.updateSlidesSize();
1191            s.updateProgress();
1192            s.updatePagination();
1193            s.updateClasses();
1194            if (s.params.scrollbar && s.scrollbar) {
1195                s.scrollbar.set();
1196            }
1197            function forceSetTranslate() {
1198                var translate = s.rtl ? -s.translate : s.translate;
1199                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
1200                s.setWrapperTranslate(newTranslate);
1201                s.updateActiveIndex();
1202                s.updateClasses();
1203            }
1204            if (updateTranslate) {
1205                var translated, newTranslate;
1206                if (s.controller && s.controller.spline) {
1207                    s.controller.spline = undefined;
1208                }
1209                if (s.params.freeMode) {
1210                    forceSetTranslate();
1211                    if (s.params.autoHeight) {
1212                        s.updateAutoHeight();
1213                    }
1214                }
1215                else {
1216                    if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {
1217                        translated = s.slideTo(s.slides.length - 1, 0, false, true);
1218                    }
1219                    else {
1220                        translated = s.slideTo(s.activeIndex, 0, false, true);
1221                    }
1222                    if (!translated) {
1223                        forceSetTranslate();
1224                    }
1225                }
1226            }
1227            else if (s.params.autoHeight) {
1228                s.updateAutoHeight();
1229            }
1230        };
1231        
1232        /*=========================
1233          Resize Handler
1234          ===========================*/
1235        s.onResize = function (forceUpdatePagination) {
1236            //Breakpoints
1237            if (s.params.breakpoints) {
1238                s.setBreakpoint();
1239            }
1240        
1241            // Disable locks on resize
1242            var allowSwipeToPrev = s.params.allowSwipeToPrev;
1243            var allowSwipeToNext = s.params.allowSwipeToNext;
1244            s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;
1245        
1246            s.updateContainerSize();
1247            s.updateSlidesSize();
1248            if (s.params.slidesPerView === 'auto' || s.params.freeMode || force
1248UpdatePagination) s.updatePagination();
1249            if (s.params.scrollbar && s.scrollbar) {
1250                s.scrollbar.set();
1251            }
1252            if (s.controller && s.controller.spline) {
1253                s.controller.spline = undefined;
1254            }
1255            var slideChangedBySlideTo = false;
1256            if (s.params.freeMode) {
1257                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
1258                s.setWrapperTranslate(newTranslate);
1259                s.updateActiveIndex();
1260                s.updateClasses();
1261        
1262                if (s.params.autoHeight) {
1263                    s.updateAutoHeight();
1264                }
1265            }
1266            else {
1267                s.updateClasses();
1268                if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {
1269                    slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);
1270                }
1271                else {
1272                    slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);
1273                }
1274            }
1275            if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {
1276                s.lazy.load();
1277            }
1278            // Return locks after resize
1279            s.params.allowSwipeToPrev = allowSwipeToPrev;
1280            s.params.allowSwipeToNext = allowSwipeToNext;
1281        };
1282        
1283        /*=========================
1284          Events
1285          ===========================*/
1286        
1287        //Define Touch Events
1288        s.touchEventsDesktop = {start: 'mousedown', move: 'mousemove', end: 'mouseup'};
1289        if (window.navigator.pointerEnabled) s.touchEventsDesktop = {start: 'pointerdown', move: 'pointermove', end: 'pointerup'};
1290        else if (window.navigator.msPointerEnabled) s.touchEventsDesktop = {start: 'MSPointerDown', move: 'MSPointerMove', end: 'MSPointerUp'};
1291        s.touchEvents = {
1292            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : s.touchEventsDesktop.start,
1293            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : s.touchEventsDesktop.move,
1294            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : s.touchEventsDesktop.end
1295        };
1296        
1297        
1298        // WP8 Touch Events Fix
1299        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {
1300            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);
1301        }
1302        
1303        // Attach/detach events
1304        s.initEvents = function (detach) {
1305            var actionDom = detach ? 'off' : 'on';
1306            var action = detach ? 'removeEventListener' : 'addEventListener';
1307            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];
1308            var target = s.support.touch ? touchEventsTarget : document;
1309        
1310            var moveCapture = s.params.nested ? true : false;
1311        
1312            //Touch Events
1313            if (s.browser.ie) {
1314                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
1315                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);
1316                target[action](s.touchEvents.end, s.onTouchEnd, false);
1317            }
1318            else {
1319                if (s.support.touch) {
1320                    var passiveListener = s.touchEvents.start === 'touchstart' && s.support.passiveListener && s.params.passiveListeners ? {passive: true, capture: false} : false;
1321                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, passiveListener);
1322                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);
1323                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, passiveListener);
1324                }
1325                if ((params.simulateTouch && !s.device.ios && !s.device.android) || (params.simulateTouch && !s.support.touch && s.device.ios)) {
1326                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);
1327                    document[action]('mousemove', s.onTouchMove, moveCapture);
1328                    document[action]('mouseup', s.onTouchEnd, false);
1329                }
1330            }
1331            window[action]('resize', s.onResize);
1332        
1333            // Next, Prev, Index
1334            if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
1335                s.nextButton[actionDom]('click', s.onClickNext);
1336                if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);
1337            }
1338            if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
1339                s.prevButton[actionDom]('click', s.onClickPrev);
1340                if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);
1341            }
1342            if (s.params.pagination && s.params.paginationClickable) {
1343                s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);
1344                if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);
1345            }
1346        
1347            // Prevent Links Clicks
1348            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);
1349        };
1350        s.attachEvents = function () {
1351            s.initEvents();
1352        };
1353        s.detachEvents = function () {
1354            s.initEvents(true);
1355        };
1356        
1357        /*=========================
1358          Handle Clicks
1359          ===========================*/
1360        // Prevent Clicks
1361        s.allowClick = true;
1362        s.preventClicks = function (e) {
1363            if (!s.allowClick) {
1364                if (s.params.preventClicks) e.preventDefault();
1365                if (s.params.preventClicksPropagation && s.animating) {
1366                    e.stopPropagation();
1367                    e.stopImmediatePropagation();
1368                }
1369            }
1370        };
1371        // Clicks
1372        s.onClickNext = function (e) {
1373            e.preventDefault();
1374            if (s.isEnd && !s.params.loop) return;
1375            s.slideNext();
1376        };
1377        s.onClickPrev = function (e) {
1378            e.preventDefault();
1379            if (s.isBeginning && !s.params.loop) return;
1380            s.slidePrev();
1381        };
1382        s.onClickIndex = function (e) {
1383            e.preventDefault();
1384            var index = $(this).index() * s.params.slidesPerGroup;
1385            if (s.params.loop) index = index + s.loopedSlides;
1386            s.slideTo(index);
1387        };
1388        
1389        /*=========================
1390          Handle Touches
1391          ===========================*/
1392        function findElementInEvent(e, selector) {
1393            var el = $(e.target);
1394            if (!el.is(selector)) {
1395                if (typeof selector === 'string') {
1396                    el = el.parents(selector);
1397                }
1398                else if (selector.nodeType) {
1399                    var found;
1400                    el.parents().each(function (index, _el) {
1401                        if (_el === selector) found = selector;
1402                    });
1403                    if (!found) return undefined;
1404                    else return selector;
1405                }
1406            }
1407            if (el.length === 0) {
1408                return undefined;
1409            }
1410            return el[0];
1411        }
1412        s.updateClickedSlide = function (e) {
1413            var slide = findElementInEvent(e, '.' + s.params.slideClass);
1414            var slideFound = false;
1415            if (slide) {
1416                for (var i = 0; i < s.slides.length; i++) {
1417                    if (s.slides[i] === slide) slideFound = true;
1418                }
1419            }
1420        
1421            if (slide && slideFound) {
1422                s.clickedSlide = slide;
1423                s.clickedIndex = $(slide).index();
1424            }
1425            else {
1426                s.clickedSlide = undefined;
1427                s.clickedIndex = undefined;
1428                return;
1429            }
1430            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {
1431                var slideToIndex = s.clickedIndex,
1432                    realIndex,
1433                    duplicatedSlides;
1434                if (s.params.loop) {
1435                    if (s.animating) return;
1436                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');
1437                    if (s.params.centeredSlides) {
1438                        if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {
1439                            s.fixLoop();
1440                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + s.params.slideDuplicateClass + ')').eq(0).index();
1441                            setTimeout(function () {
1442                                s.slideTo(slideToIndex);
1443                            }, 0);
1444                        }
1445                        else {
1446                            s.slideTo(slideToIndex);
1447                        }
1448                    }
1449                    else {
1450                        if (slideToIndex > s.slides.length - s.params.slidesPerView) {
1451                            s.fixLoop();
1452                            slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + s.params.slideDuplicateClass + ')').eq(0).index();
1453                            setTimeout(function () {
1454                                s.slideTo(slideToIndex);
1455                            }, 0);
1456                        }
1457                        else {
1458                            s.slideTo(slideToIndex);
1459                        }
1460                    }
1461                }
1462                else {
1463                    s.slideTo(slideToIndex);
1464                }
1465            }
1466        };
1467        
1468        var isTouched,
1469            isMoved,
1470            allowTouchCallbacks,
1471            touchStartTime,
1472            isScrolling,
1473            currentTranslate,
1474            startTranslate,
1475            allowThresholdMove,
1476            // Form elements to match
1477            formElements = 'input, select, textarea, button, video',
1478            // Last click time
1479            lastClickTime = Date.now(), clickTimeout,
1480            //Velocities
1481            velocities = [],
1482            allowMomentumBounce;
1483        
1484        // Animating Flag
1485        s.animating = false;
1486        
1487        // Touches information
1488        s.touches = {
1489            startX: 0,
1490            startY: 0,
1491            currentX: 0,
1492            currentY: 0,
1493            diff: 0
1494        };
1495        
1496        // Touch handlers
1497        var isTouchEvent, startMoving;
1498        s.onTouchStart = function (e) {
1499            if (e.originalEvent) e = e.originalEvent;
1500            isTouchEvent = e.type === 'touchstart';
1501            if (!isTouchEvent && 'which' in e && e.which === 3) return;
1502            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {
1503                s.allowClick = true;
1504                return;
1505            }
1506            if (s.params.swipeHandler) {
1507                if (!findElementInEvent(e, s.params.swipeHandler)) return;
1508            }
1509        
1510            var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
1511            var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
1512        
1513            // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore
1514            if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {
1515                return;
1516            }
1517        
1518            isTouched = true;
1519            isMoved = false;
1520            allowTouchCallbacks = true;
1521            isScrolling = undefined;
1522            startMoving = undefined;
1523            s.touches.startX = startX;
1524            s.touches.startY = startY;
1525            touchStartTime = Date.now();
1526            s.allowClick = true;
1527            s.updateContainerSize();
1528            s.swipeDirection = undefined;
1529            if (s.params.threshold > 0) allowThresholdMove = false;
1530            if (e.type !== 'touchstart') {
1531                var preventDefault = true;
1532                if ($(e.target).is(formElements)) preventDefault = false;
1533                if (document.activeElement && $(document.activeElement).is(formElements)) {
1534                    document.activeElement.blur();
1535                }
1536                if (preventDefault) {
1537                    e.preventDefault();
1538                }
1539            }
1540            s.emit('onTouchStart', s, e);
1541        };
1542        
1543        s.onTouchMove = function (e) {
1544            if (e.originalEvent) e = e.originalEvent;
1545            if (isTouchEvent && e.type === 'mousemove') return;
1546            if (e.preventedByNestedSwiper) {
1547                s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
1548                s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
1549                return;
1550            }
1551            if (s.params.onlyExternal) {
1552                // isMoved = true;
1553                s.allowClick = false;
1554                if (isTouched) {
1555                    s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
1556                    s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
1557                    touchStartTime = Date.now();
1558                }
1559                return;
1560            }
1561            if (isTouchEvent && s.params.touchReleaseOnEdges && !s.params.loop) {
1562                if (!s.isHorizontal()) {
1563                    // Vertical
1564                    if (
1565                        (s.touches.currentY < s.touches.startY && s.translate <= s.maxTranslate()) ||
1566                        (s.touches.currentY > s.touches.startY && s.translate >= s.minTranslate())
1567                        ) {
1568                        return;
1569                    }
1570                }
1571                else {
1572                    if (
1573                        (s.touches.currentX < s.touches.startX && s.translate <= s.maxTranslate()) ||
1574                        (s.touches.currentX > s.touches.startX && s.translate >= s.minTranslate())
1575                        ) {
1576                        return;
1577                    }
1578                }
1579            }
1580            if (isTouchEvent && document.activeElement) {
1581                if (e.target === document.activeElement && $(e.target).is(formElements)) {
1582                    isMoved = true;
1583                    s.allowClick = false;
1584                    return;
1585                }
1586            }
1587            if (allowTouchCallbacks) {
1588                s.emit('onTouchMove', s, e);
1589            }
1590            if (e.targetTouches && e.targetTouches.length > 1) return;
1591        
1592            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
1593            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
1594        
1595            if (typeof isScrolling === 'undefined') {
1596                var touchAngle;
1597                if (s.isHorizontal() && s.touches.currentY === s.touches.startY || !s.isHorizontal() && s.touches.currentX !== s.touches.startX) {
1598                    isScrolling = false;
1599                }
1600                else {
1601                    touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;
1602                    isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);
1603                }
1604            }
1605            if (isScrolling) {
1606           
1606     s.emit('onTouchMoveOpposite', s, e);
1607            }
1608            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {
1609                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {
1610                    startMoving = true;
1611                }
1612            }
1613            if (!isTouched) return;
1614            if (isScrolling)  {
1615                isTouched = false;
1616                return;
1617            }
1618            if (!startMoving && s.browser.ieTouch) {
1619                return;
1620            }
1621            s.allowClick = false;
1622            s.emit('onSliderMove', s, e);
1623            e.preventDefault();
1624            if (s.params.touchMoveStopPropagation && !s.params.nested) {
1625                e.stopPropagation();
1626            }
1627        
1628            if (!isMoved) {
1629                if (params.loop) {
1630                    s.fixLoop();
1631                }
1632                startTranslate = s.getWrapperTranslate();
1633                s.setWrapperTransition(0);
1634                if (s.animating) {
1635                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');
1636                }
1637                if (s.params.autoplay && s.autoplaying) {
1638                    if (s.params.autoplayDisableOnInteraction) {
1639                        s.stopAutoplay();
1640                    }
1641                    else {
1642                        s.pauseAutoplay();
1643                    }
1644                }
1645                allowMomentumBounce = false;
1646                //Grab Cursor
1647                if (s.params.grabCursor && (s.params.allowSwipeToNext === true || s.params.allowSwipeToPrev === true)) {
1648                    s.setGrabCursor(true);
1649                }
1650            }
1651            isMoved = true;
1652        
1653            var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
1654        
1655            diff = diff * s.params.touchRatio;
1656            if (s.rtl) diff = -diff;
1657        
1658            s.swipeDirection = diff > 0 ? 'prev' : 'next';
1659            currentTranslate = diff + startTranslate;
1660        
1661            var disableParentSwiper = true;
1662            if ((diff > 0 && currentTranslate > s.minTranslate())) {
1663                disableParentSwiper = false;
1664                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);
1665            }
1666            else if (diff < 0 && currentTranslate < s.maxTranslate()) {
1667                disableParentSwiper = false;
1668                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);
1669            }
1670        
1671            if (disableParentSwiper) {
1672                e.preventedByNestedSwiper = true;
1673            }
1674        
1675            // Directions locks
1676            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {
1677                currentTranslate = startTranslate;
1678            }
1679            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {
1680                currentTranslate = startTranslate;
1681            }
1682        
1683        
1684            // Threshold
1685            if (s.params.threshold > 0) {
1686                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {
1687                    if (!allowThresholdMove) {
1688                        allowThresholdMove = true;
1689                        s.touches.startX = s.touches.currentX;
1690                        s.touches.startY = s.touches.currentY;
1691                        currentTranslate = startTranslate;
1692                        s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
1693                        return;
1694                    }
1695                }
1696                else {
1697                    currentTranslate = startTranslate;
1698                    return;
1699                }
1700            }
1701        
1702            if (!s.params.followFinger) return;
1703        
1704            // Update active index in free mode
1705            if (s.params.freeMode || s.params.watchSlidesProgress) {
1706                s.updateActiveIndex();
1707            }
1708            if (s.params.freeMode) {
1709                //Velocity
1710                if (velocities.length === 0) {
1711                    velocities.push({
1712                        position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],
1713                        time: touchStartTime
1714                    });
1715                }
1716                velocities.push({
1717                    position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],
1718                    time: (new window.Date()).getTime()
1719                });
1720            }
1721            // Update progress
1722            s.updateProgress(currentTranslate);
1723            // Update translate
1724            s.setWrapperTranslate(currentTranslate);
1725        };
1726        s.onTouchEnd = function (e) {
1727            if (e.originalEvent) e = e.originalEvent;
1728            if (allowTouchCallbacks) {
1729                s.emit('onTouchEnd', s, e);
1730            }
1731            allowTouchCallbacks = false;
1732            if (!isTouched) return;
1733            //Return Grab Cursor
1734            if (s.params.grabCursor && isMoved && isTouched  && (s.params.allowSwipeToNext === true || s.params.allowSwipeToPrev === true)) {
1735                s.setGrabCursor(false);
1736            }
1737        
1738            // Time diff
1739            var touchEndTime = Date.now();
1740            var timeDiff = touchEndTime - touchStartTime;
1741        
1742            // Tap, doubleTap, Click
1743            if (s.allowClick) {
1744                s.updateClickedSlide(e);
1745                s.emit('onTap', s, e);
1746                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {
1747                    if (clickTimeout) clearTimeout(clickTimeout);
1748                    clickTimeout = setTimeout(function () {
1749                        if (!s) return;
1750                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {
1751                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);
1752                        }
1753                        s.emit('onClick', s, e);
1754                    }, 300);
1755        
1756                }
1757                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {
1758                    if (clickTimeout) clearTimeout(clickTimeout);
1759                    s.emit('onDoubleTap', s, e);
1760                }
1761            }
1762        
1763            lastClickTime = Date.now();
1764            setTimeout(function () {
1765                if (s) s.allowClick = true;
1766            }, 0);
1767        
1768            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {
1769                isTouched = isMoved = false;
1770                return;
1771            }
1772            isTouched = isMoved = false;
1773        
1774            var currentPos;
1775            if (s.params.followFinger) {
1776                currentPos = s.rtl ? s.translate : -s.translate;
1777            }
1778            else {
1779                currentPos = -currentTranslate;
1780            }
1781            if (s.params.freeMode) {
1782                if (currentPos < -s.minTranslate()) {
1783                    s.slideTo(s.activeIndex);
1784                    return;
1785                }
1786                else if (currentPos > -s.maxTranslate()) {
1787                    if (s.slides.length < s.snapGrid.length) {
1788                        s.slideTo(s.snapGrid.length - 1);
1789                    }
1790                    else {
1791                        s.slideTo(s.slides.length - 1);
1792                    }
1793                    return;
1794                }
1795        
1796                if (s.params.freeModeMomentum) {
1797                    if (velocities.length > 1) {
1798                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();
1799        
1800                        var distance = lastMoveEvent.position - velocityEvent.position;
1801                        var time = lastMoveEvent.time - velocityEvent.time;
1802                        s.velocity = distance / time;
1803                        s.velocity = s.velocity / 2;
1804                        if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {
1805                            s.velocity = 0;
1806                        }
1807                        // this implies that the user stopped moving a finger then released.
1808                        // There would be no events with distance zero, so the last event is stale.
1809                        if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {
1810                            s.velocity = 0;
1811                        }
1812                    } else {
1813                        s.velocity = 0;
1814                    }
1815                    s.velocity = s.velocity * s.params.freeModeMomentumVelocityRatio;
1816        
1817                    velocities.length = 0;
1818                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;
1819                    var momentumDistance = s.velocity * momentumDuration;
1820        
1821                    var newPosition = s.translate + momentumDistance;
1822                    if (s.rtl) newPosition = - newPosition;
1823                    var doBounce = false;
1824                    var afterBouncePosition;
1825                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;
1826                    if (newPosition < s.maxTranslate()) {
1827                        if (s.params.freeModeMomentumBounce) {
1828                            if (newPosition + s.maxTranslate() < -bounceAmount) {
1829                                newPosition = s.maxTranslate() - bounceAmount;
1830                            }
1831                            afterBouncePosition = s.maxTranslate();
1832                            doBounce = true;
1833                            allowMomentumBounce = true;
1834                        }
1835                        else {
1836                            newPosition = s.maxTranslate();
1837                        }
1838                    }
1839                    else if (newPosition > s.minTranslate()) {
1840                        if (s.params.freeModeMomentumBounce) {
1841                            if (newPosition - s.minTranslate() > bounceAmount) {
1842                                newPosition = s.minTranslate() + bounceAmount;
1843                            }
1844                            afterBouncePosition = s.minTranslate();
1845                            doBounce = true;
1846                            allowMomentumBounce = true;
1847                        }
1848                        else {
1849                            newPosition = s.minTranslate();
1850                        }
1851                    }
1852                    else if (s.params.freeModeSticky) {
1853                        var j = 0,
1854                            nextSlide;
1855                        for (j = 0; j < s.snapGrid.length; j += 1) {
1856                            if (s.snapGrid[j] > -newPosition) {
1857                                nextSlide = j;
1858                                break;
1859                            }
1860        
1861                        }
1862                        if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {
1863                            newPosition = s.snapGrid[nextSlide];
1864                        } else {
1865                            newPosition = s.snapGrid[nextSlide - 1];
1866                        }
1867                        if (!s.rtl) newPosition = - newPosition;
1868                    }
1869                    //Fix duration
1870                    if (s.velocity !== 0) {
1871                        if (s.rtl) {
1872                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);
1873                        }
1874                        else {
1875                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);
1876                        }
1877                    }
1878                    else if (s.params.freeModeSticky) {
1879                        s.slideReset();
1880                        return;
1881                    }
1882        
1883                    if (s.params.freeModeMomentumBounce && doBounce) {
1884                        s.updateProgress(afterBouncePosition);
1885                        s.setWrapperTransition(momentumDuration);
1886                        s.setWrapperTranslate(newPosition);
1887                        s.onTransitionStart();
1888                        s.animating = true;
1889                        s.wrapper.transitionEnd(function () {
1890                            if (!s || !allowMomentumBounce) return;
1891                            s.emit('onMomentumBounce', s);
1892        
1893                            s.setWrapperTransition(s.params.speed);
1894                            s.setWrapperTranslate(afterBouncePosition);
1895                            s.wrapper.transitionEnd(function () {
1896                                if (!s) return;
1897                                s.onTransitionEnd();
1898                            });
1899                        });
1900                    } else if (s.velocity) {
1901                        s.updateProgress(newPosition);
1902                        s.setWrapperTransition(momentumDuration);
1903                        s.setWrapperTranslate(newPosition);
1904                        s.onTransitionStart();
1905                        if (!s.animating) {
1906                            s.animating = true;
1907                            s.wrapper.transitionEnd(function () {
1908                                if (!s) return;
1909                                s.onTransitionEnd();
1910                            });
1911                        }
1912        
1913                    } else {
1914                        s.updateProgress(newPosition);
1915                    }
1916        
1917                    s.updateActiveIndex();
1918                }
1919                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {
1920                    s.updateProgress();
1921                    s.updateActiveIndex();
1922                }
1923                return;
1924            }
1925        
1926            // Find current slide
1927            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];
1928            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {
1929                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {
1930                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {
1931                        stopIndex = i;
1932                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];
1933                    }
1934                }
1935                else {
1936                    if (currentPos >= s.slidesGrid[i]) {
1937                        stopIndex = i;
1938                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];
1939                    }
1940                }
1941            }
1942        
1943            // Find current slide size
1944            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;
1945        
1946            if (timeDiff > s.params.longSwipesMs) {
1947                // Long touches
1948                if (!s.params.longSwipes) {
1949                    s.slideTo(s.activeIndex);
1950                    return;
1951                }
1952                if (s.swipeDirection === 'next') {
1953                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);
1954                    else s.slideTo(stopIndex);
1955        
1956                }
1957                if (s.swipeDirection === 'prev') {
1958                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);
1959                    else s.slideTo(stopIndex);
1960                }
1961            }
1962            else {
1963                // Short swipes
1964                if (!s.params.shortSwipes) {
1965                    s.slideTo(s.activeIndex);
1966                    return;
1967                }
1968                if (s.swipeDirection === 'next') {
1969                    s.slideTo(stopIndex + s.params.slidesPerGroup);
1970        
1971                }
1972                if (s.swipeDirection === 'prev') {
1973                    s.slideTo(stopIndex);
1974                }
1975            }
1976        };
1977        /*=========================
1978          Transitions
1979          ===========================*/
1980        s._slideTo = function (slideIndex, speed) {
1981            return s.slideTo(slideIndex, speed, true, true);
1982        };
1983        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {
1984            if (typeof runCallbacks === 'undefined') runCallbacks = true;
1985            if (typeof slideIndex === 'undefined') slideIndex = 0;
1986            if (slideIndex < 0) slideIndex = 0;
1987            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);
1988            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;
1989        
1990            var translate = - s.snapGrid[s.snapIndex];
1991            // Stop autoplay
1992            if (s.params.autoplay && s.autoplaying) {
1993                if (internal || !s.params.autoplayDisableOnInteraction) {
1994                    s.pauseAutoplay(speed);
1995                }
1996                else {
1997                    s.stopAutoplay();
1998                }
1999            }
2000            // Update progress
2001            s.updateProgress(translate);
2002        
2003            // Normalize slideIndex
2004            if(s.params.normalizeSlideIndex){
2005                for (var i = 0; i < s.slidesGrid.length; i++) {
2006                    if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {
2007                        slideIndex = i;
2008                    }
2009                }
2010            }
2011        
2012            // Directions locks
2013            if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {
2014                return false;
2015            }
2016            if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {
2017                if ((s.activeIndex || 0) !== slideIndex ) return false;
2018            }
2019        
2020            // Update Index
2021            if (typeof speed === 'undefined') speed = s.params.speed;
2022            s.previousIndex = s.activeIndex || 0;
2023            s.activeIndex = slideIndex;
2024            s.updateRealIndex();
2025            if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {
2026                // Update Height
2027                if (s.params.autoHeight) {
2028                    s.updateAutoHeight();
2029                }
2030                s.updateClasses();
2031                if (s.params.effect !== 'slide') {
2032                    s.setWrapperTranslate(translate);
2033                }
2034                return false;
2035            }
2036            s.updateClasses();
2037            s.onTransitionStart(runCallbacks);
2038        
2039            if (speed === 0 || s.browser.lteIE9) {
2040                s.setWrapperTranslate(translate);
2041                s.setWrapperTransition(0);
2042                s.onTransitionEnd(runCallbacks);
2043            }
2044            else {
2045                s.setWrapperTranslate(translate);
2046                s.setWrapperTransition(speed);
2047                if (!s.animating) {
2048                    s.animating = true;
2049                    s.wrapper.transitionEnd(function () {
2050                        if (!s) return;
2051                        s.onTransitionEnd(runCallbacks);
2052                    });
2053                }
2054        
2055            }
2056        
2057            return true;
2058        };
2059        
2060        s.onTransitionStart = function (runCallbacks) {
2061            if (typeof runCallbacks === 'undefined') runCallbacks = true;
2062            if (s.params.autoHeight) {
2063                s.updateAutoHeight();
2064            }
2065            if (s.lazy) s.lazy.onTransitionStart();
2066            if (runCallbacks) {
2067                s.emit('onTransitionStart', s);
2068                if (s.activeIndex !== s.previousIndex) {
2069                    s.emit('onSlideChangeStart', s);
2070                    if (s.activeIndex > s.previousIndex) {
2071                        s.emit('onSlideNextStart', s);
2072                    }
2073                    else {
2074                        s.emit('onSlidePrevStart', s);
2075                    }
2076                }
2077        
2078            }
2079        };
2080        s.onTransitionEnd = function (runCallbacks) {
2081            s.animating = false;
2082            s.setWrapperTransition(0);
2083            if (typeof runCallbacks === 'undefined') runCallbacks = true;
2084            if (s.lazy) s.lazy.onTransitionEnd();
2085            if (runCallbacks) {
2086                s.emit('onTransitionEnd', s);
2087                if (s.activeIndex !== s.previousIndex) {
2088                    s.emit('onSlideChangeEnd', s);
2089                    if (s.activeIndex > s.previousIndex) {
2090                        s.emit('onSlideNextEnd', s);
2091                    }
2092                    else {
2093                        s.emit('onSlidePrevEnd', s);
2094                    }
2095                }
2096            }
2097            if (s.params.history && s.history) {
2098                s.history.setHistory(s.params.history, s.activeIndex);
2099            }
2100            if (s.params.hashnav && s.hashnav) {
2101                s.hashnav.setHash();
2102            }
2103        
2104        };
2105        s.slideNext = function (runCallbacks, speed, internal) {
2106            if (s.params.loop) {
2107                if (s.animating) return false;
2108                s.fixLoop();
2109                var clientLeft = s.container[0].clientLeft;
2110                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
2111            }
2112            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
2113        };
2114        s._slideNext = function (speed) {
2115            return s.slideNext(true, speed, true);
2116        };
2117        s.slidePrev = function (runCallbacks, speed, internal) {
2118            if (s.params.loop) {
2119                if (s.animating) return false;
2120                s.fixLoop();
2121                var clientLeft = s.container[0].clientLeft;
2122                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
2123            }
2124            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
2125        };
2126        s._slidePrev = function (speed) {
2127            return s.slidePrev(true, speed, true);
2128        };
2129        s.slideReset = function (runCallbacks, speed, internal) {
2130            return s.slideTo(s.activeIndex, speed, runCallbacks);
2131        };
2132        
2133        s.disableTouchControl = function () {
2134            s.params.onlyExternal = true;
2135            return true;
2136        };
2137        s.enableTouchControl = function () {
2138            s.params.onlyExternal = false;
2139            return true;
2140        };
2141        
2142        /*=========================
2143          Translate/transition helpers
2144          ===========================*/
2145        s.setWrapperTransition = function (duration, byController) {
2146            s.wrapper.transition(duration);
2147            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
2148                s.effects[s.params.effect].setTransition(duration);
2149            }
2150            if (s.params.parallax && s.parallax) {
2151                s.parallax.setTransition(duration);
2152            }
2153            if (s.params.scrollbar && s.scrollbar) {
2154                s.scrollbar.setTransition(duration);
2155            }
2156            if (s.params.control && s.controller) {
2157                s.controller.setTransition(duration, byController);
2158            }
2159            s.emit('onSetTransition', s, duration);
2160        };
2161        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {
2162            var x = 0, y = 0, z = 0;
2163            if (s.isHorizontal()) {
2164                x = s.rtl ? -translate : translate;
2165            }
2166            else {
2167                y = translate;
2168            }
2169        
2170            if (s.params.roundLengths) {
2171                x = round(x);
2172                y = round(y);
2173            }
2174        
2175            if (!s.params.virtualTranslate) {
2176                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');
2177                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');
2178            }
2179        
2180            s.translate = s.isHorizontal() ? x : y;
2181        
2182            // Check if we need to update progress
2183            var progress;
2184            var translatesDiff = s.maxTranslate() - s.minTranslate();
2185            if (translatesDiff === 0) {
2186                progress = 0;
2187            }
2188            else {
2189                progress = (translate - s.minTranslate()) / (translatesDiff);
2190            }
2191            if (progress !== s.progress) {
2192                s.updateProgress(translate);
2193            }
2194        
2195            if (updateActiveIndex) s.updateActiveIndex();
2196            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
2197                s.effects[s.params.effect].setTranslate(s.translate);
2198            }
2199            if (s.params.parallax && s.parallax) {
2200                s.parallax.setTranslate(s.translate);
2201            }
2202            if (s.params.scrollbar && s.scrollbar) {
2203                s.scrollbar.setTranslate(s.translate);
2204            }
2205            if (s.params.control && s.controller) {
2206                s.controller.setTranslate(s.translate, byController);
2207            }
2208            s.emit('onSetTranslate', s, s.translate);
2209        };
2210        
2211        s.getTranslate = function (el, axis) {
2212            var matrix, curTransform, curStyle, transformMatrix;
2213        
2214            // automatic axis detection
2215            if (typeof axis === 'undefined') {
2216                axis = 'x';
2217            }
2218        
2219            if (s.params.virtualTranslate) {
2220                return s.rtl ? -s.translate : s.translate;
2221            }
2222        
2223            curStyle = window.getComputedStyle(el, null);
2224            if (window.WebKitCSSMatrix) {
2225                curTransform = curStyle.transform || curStyle.webkitTransform;
2226                if (curTransform.split(',').length > 6) {
2227                    curTransform = curTransform.split(', ').map(function(a){
2228                        return a.replace(',','.');
2229                    }).join(', ');
2230                }
2231                // Some old versions of Webkit choke when 'none' is passed; pass
2232                // empty string instead in this case
2233                transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
2234            }
2235            else {
2236                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
2237                matrix = transformMatrix.toString().split(',');
2238            }
2239        
2240            if (axis === 'x') {
2241                //Latest Chrome and webkits Fix
2242                if (window.WebKitCSSMatrix)
2243                    curTransform = transformMatrix.m41;
2244                //Crazy IE10 Matrix
2245                else if (matrix.length === 16)
2246                    curTransform = parseFloat(matrix[12]);
2247                //Normal Browsers
2248                else
2249                    curTransform = parseFloat(matrix[4]);
2250            }
2251            if (axis === 'y') {
2252                //Latest Chrome and webkits Fix
2253                if (window.WebKitCSSMatrix)
2254                    curTransform = transformMatrix.m42;
2255                //Crazy 
2255IE10 Matrix
2256                else if (matrix.length === 16)
2257                    curTransform = parseFloat(matrix[13]);
2258                //Normal Browsers
2259                else
2260                    curTransform = parseFloat(matrix[5]);
2261            }
2262            if (s.rtl && curTransform) curTransform = -curTransform;
2263            return curTransform || 0;
2264        };
2265        s.getWrapperTranslate = function (axis) {
2266            if (typeof axis === 'undefined') {
2267                axis = s.isHorizontal() ? 'x' : 'y';
2268            }
2269            return s.getTranslate(s.wrapper[0], axis);
2270        };
2271        
2272        /*=========================
2273          Observer
2274          ===========================*/
2275        s.observers = [];
2276        function initObserver(target, options) {
2277            options = options || {};
2278            // create an observer instance
2279            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
2280            var observer = new ObserverFunc(function (mutations) {
2281                mutations.forEach(function (mutation) {
2282                    s.onResize(true);
2283                    s.emit('onObserverUpdate', s, mutation);
2284                });
2285            });
2286        
2287            observer.observe(target, {
2288                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
2289                childList: typeof options.childList === 'undefined' ? true : options.childList,
2290                characterData: typeof options.characterData === 'undefined' ? true : options.characterData
2291            });
2292        
2293            s.observers.push(observer);
2294        }
2295        s.initObservers = function () {
2296            if (s.params.observeParents) {
2297                var containerParents = s.container.parents();
2298                for (var i = 0; i < containerParents.length; i++) {
2299                    initObserver(containerParents[i]);
2300                }
2301            }
2302        
2303            // Observe container
2304            initObserver(s.container[0], {childList: false});
2305        
2306            // Observe wrapper
2307            initObserver(s.wrapper[0], {attributes: false});
2308        };
2309        s.disconnectObservers = function () {
2310            for (var i = 0; i < s.observers.length; i++) {
2311                s.observers[i].disconnect();
2312            }
2313            s.observers = [];
2314        };
2315        /*=========================
2316          Loop
2317          ===========================*/
2318        // Create looped slides
2319        s.createLoop = function () {
2320            // Remove duplicated slides
2321            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
2322        
2323            var slides = s.wrapper.children('.' + s.params.slideClass);
2324        
2325            if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;
2326        
2327            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);
2328            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;
2329            if (s.loopedSlides > slides.length) {
2330                s.loopedSlides = slides.length;
2331            }
2332        
2333            var prependSlides = [], appendSlides = [], i;
2334            slides.each(function (index, el) {
2335                var slide = $(this);
2336                if (index < s.loopedSlides) appendSlides.push(el);
2337                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);
2338                slide.attr('data-swiper-slide-index', index);
2339            });
2340            for (i = 0; i < appendSlides.length; i++) {
2341                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
2342            }
2343            for (i = prependSlides.length - 1; i >= 0; i--) {
2344                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
2345            }
2346        };
2347        s.destroyLoop = function () {
2348            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
2349            s.slides.removeAttr('data-swiper-slide-index');
2350        };
2351        s.reLoop = function (updatePosition) {
2352            var oldIndex = s.activeIndex - s.loopedSlides;
2353            s.destroyLoop();
2354            s.createLoop();
2355            s.updateSlidesSize();
2356            if (updatePosition) {
2357                s.slideTo(oldIndex + s.loopedSlides, 0, false);
2358            }
2359        
2360        };
2361        s.fixLoop = function () {
2362            var newIndex;
2363            //Fix For Negative Oversliding
2364            if (s.activeIndex < s.loopedSlides) {
2365                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;
2366                newIndex = newIndex + s.loopedSlides;
2367                s.slideTo(newIndex, 0, false, true);
2368            }
2369            //Fix For Positive Oversliding
2370            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {
2371                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;
2372                newIndex = newIndex + s.loopedSlides;
2373                s.slideTo(newIndex, 0, false, true);
2374            }
2375        };
2376        /*=========================
2377          Append/Prepend/Remove Slides
2378          ===========================*/
2379        s.appendSlide = function (slides) {
2380            if (s.params.loop) {
2381                s.destroyLoop();
2382            }
2383            if (typeof slides === 'object' && slides.length) {
2384                for (var i = 0; i < slides.length; i++) {
2385                    if (slides[i]) s.wrapper.append(slides[i]);
2386                }
2387            }
2388            else {
2389                s.wrapper.append(slides);
2390            }
2391            if (s.params.loop) {
2392                s.createLoop();
2393            }
2394            if (!(s.params.observer && s.support.observer)) {
2395                s.update(true);
2396            }
2397        };
2398        s.prependSlide = function (slides) {
2399            if (s.params.loop) {
2400                s.destroyLoop();
2401            }
2402            var newActiveIndex = s.activeIndex + 1;
2403            if (typeof slides === 'object' && slides.length) {
2404                for (var i = 0; i < slides.length; i++) {
2405                    if (slides[i]) s.wrapper.prepend(slides[i]);
2406                }
2407                newActiveIndex = s.activeIndex + slides.length;
2408            }
2409            else {
2410                s.wrapper.prepend(slides);
2411            }
2412            if (s.params.loop) {
2413                s.createLoop();
2414            }
2415            if (!(s.params.observer && s.support.observer)) {
2416                s.update(true);
2417            }
2418            s.slideTo(newActiveIndex, 0, false);
2419        };
2420        s.removeSlide = function (slidesIndexes) {
2421            if (s.params.loop) {
2422                s.destroyLoop();
2423                s.slides = s.wrapper.children('.' + s.params.slideClass);
2424            }
2425            var newActiveIndex = s.activeIndex,
2426                indexToRemove;
2427            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {
2428                for (var i = 0; i < slidesIndexes.length; i++) {
2429                    indexToRemove = slidesIndexes[i];
2430                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
2431                    if (indexToRemove < newActiveIndex) newActiveIndex--;
2432                }
2433                newActiveIndex = Math.max(newActiveIndex, 0);
2434            }
2435            else {
2436                indexToRemove = slidesIndexes;
2437                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
2438                if (indexToRemove < newActiveIndex) newActiveIndex--;
2439                newActiveIndex = Math.max(newActiveIndex, 0);
2440            }
2441        
2442            if (s.params.loop) {
2443                s.createLoop();
2444            }
2445        
2446            if (!(s.params.observer && s.support.observer)) {
2447                s.update(true);
2448            }
2449            if (s.params.loop) {
2450                s.slideTo(newActiveIndex + s.loopedSlides, 0, false);
2451            }
2452            else {
2453                s.slideTo(newActiveIndex, 0, false);
2454            }
2455        
2456        };
2457        s.removeAllSlides = function () {
2458            var slidesIndexes = [];
2459            for (var i = 0; i < s.slides.length; i++) {
2460                slidesIndexes.push(i);
2461            }
2462            s.removeSlide(slidesIndexes);
2463        };
2464        
2465
2466        /*=========================
2467          Effects
2468          ===========================*/
2469        s.effects = {
2470            fade: {
2471                setTranslate: function () {
2472                    for (var i = 0; i < s.slides.length; i++) {
2473                        var slide = s.slides.eq(i);
2474                        var offset = slide[0].swiperSlideOffset;
2475                        var tx = -offset;
2476                        if (!s.params.virtualTranslate) tx = tx - s.translate;
2477                        var ty = 0;
2478                        if (!s.isHorizontal()) {
2479                            ty = tx;
2480                            tx = 0;
2481                        }
2482                        var slideOpacity = s.params.fade.crossFade ?
2483                                Math.max(1 - Math.abs(slide[0].progress), 0) :
2484                                1 + Math.min(Math.max(slide[0].progress, -1), 0);
2485                        slide
2486                            .css({
2487                                opacity: slideOpacity
2488                            })
2489                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');
2490        
2491                    }
2492        
2493                },
2494                setTransition: function (duration) {
2495                    s.slides.transition(duration);
2496                    if (s.params.virtualTranslate && duration !== 0) {
2497                        var eventTriggered = false;
2498                        s.slides.transitionEnd(function () {
2499                            if (eventTriggered) return;
2500                            if (!s) return;
2501                            eventTriggered = true;
2502                            s.animating = false;
2503                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
2504                            for (var i = 0; i < triggerEvents.length; i++) {
2505                                s.wrapper.trigger(triggerEvents[i]);
2506                            }
2507                        });
2508                    }
2509                }
2510            },
2511            flip: {
2512                setTranslate: function () {
2513                    for (var i = 0; i < s.slides.length; i++) {
2514                        var slide = s.slides.eq(i);
2515                        var progress = slide[0].progress;
2516                        if (s.params.flip.limitRotation) {
2517                            progress = Math.max(Math.min(slide[0].progress, 1), -1);
2518                        }
2519                        var offset = slide[0].swiperSlideOffset;
2520                        var rotate = -180 * progress,
2521                            rotateY = rotate,
2522                            rotateX = 0,
2523                            tx = -offset,
2524                            ty = 0;
2525                        if (!s.isHorizontal()) {
2526                            ty = tx;
2527                            tx = 0;
2528                            rotateX = -rotateY;
2529                            rotateY = 0;
2530                        }
2531                        else if (s.rtl) {
2532                            rotateY = -rotateY;
2533                        }
2534        
2535                        slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;
2536        
2537                        if (s.params.flip.slideShadows) {
2538                            //Set shadows
2539                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
2540                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
2541                            if (shadowBefore.length === 0) {
2542                                shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
2543                                slide.append(shadowBefore);
2544                            }
2545                            if (shadowAfter.length === 0) {
2546                                shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
2547                                slide.append(shadowAfter);
2548                            }
2549                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
2550                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
2551                        }
2552        
2553                        slide
2554                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');
2555                    }
2556                },
2557                setTransition: function (duration) {
2558                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
2559                    if (s.params.virtualTranslate && duration !== 0) {
2560                        var eventTriggered = false;
2561                        s.slides.eq(s.activeIndex).transitionEnd(function () {
2562                            if (eventTriggered) return;
2563                            if (!s) return;
2564                            if (!$(this).hasClass(s.params.slideActiveClass)) return;
2565                            eventTriggered = true;
2566                            s.animating = false;
2567                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
2568                            for (var i = 0; i < triggerEvents.length; i++) {
2569                                s.wrapper.trigger(triggerEvents[i]);
2570                            }
2571                        });
2572                    }
2573                }
2574            },
2575            cube: {
2576                setTranslate: function () {
2577                    var wrapperRotate = 0, cubeShadow;
2578                    if (s.params.cube.shadow) {
2579                        if (s.isHorizontal()) {
2580                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');
2581                            if (cubeShadow.length === 0) {
2582                                cubeShadow = $('<div class="swiper-cube-shadow"></div>');
2583                                s.wrapper.append(cubeShadow);
2584                            }
2585                            cubeShadow.css({height: s.width + 'px'});
2586                        }
2587                        else {
2588                            cubeShadow = s.container.find('.swiper-cube-shadow');
2589                            if (cubeShadow.length === 0) {
2590                                cubeShadow = $('<div class="swiper-cube-shadow"></div>');
2591                                s.container.append(cubeShadow);
2592                            }
2593                        }
2594                    }
2595                    for (var i = 0; i < s.slides.length; i++) {
2596                        var slide = s.slides.eq(i);
2597                        var slideAngle = i * 90;
2598                        var round = Math.floor(slideAngle / 360);
2599                        if (s.rtl) {
2600                            slideAngle = -slideAngle;
2601                            round = Math.floor(-slideAngle / 360);
2602                        }
2603                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);
2604                        var tx = 0, ty = 0, tz = 0;
2605                        if (i % 4 === 0) {
2606                            tx = - round * 4 * s.size;
2607                            tz = 0;
2608                        }
2609                        else if ((i - 1) % 4 === 0) {
2610                            tx = 0;
2611                            tz = - round * 4 * s.size;
2612                        }
2613                        else if ((i - 2) % 4 === 0) {
2614                            tx = s.size + round * 4 * s.size;
2615                            tz = s.size;
2616                        }
2617                        else if ((i - 3) % 4 === 0) {
2618                            tx = - s.size;
2619                            tz = 3 * s.size + s.size * 4 * round;
2620                        }
2621                        if (s.rtl) {
2622                            tx = -tx;
2623                        }
2624        
2625                        if (!s.isHorizontal()) {
2626                            ty = tx;
2627                            tx = 0;
2628                        }
2629        
2630                        var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';
2631                        if (progress <= 1 && progress > -1) {
2632                            wrapperRotate = i * 90 + progress * 90;
2633                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;
2634                        }
2635                        slide.transform(transform);
2636                        if (s.params.cube.slideShadows) {
2637                            //Set shadows
2638                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
2639                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
2640                            if (shadowBefore.length === 0) {
2641                                shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
2642                                slide.append(shadowBefore);
2643                            }
2644                            if (shadowAfter.length === 0) {
2645                                shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
2646                                slide.append(shadowAfter);
2647                            }
2648                            if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
2649                            if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
2650                        }
2651                    }
2652                    s.wrapper.css({
2653                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2654                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2655                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2656                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'
2657                    });
2658        
2659                    if (s.params.cube.shadow) {
2660                        if (s.isHorizontal()) {
2661                            cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');
2662                        }
2663                        else {
2664                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
2665                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
2666                            var scale1 = s.params.cube.shadowScale,
2667                                scale2 = s.params.cube.shadowScale / multiplier,
2668                                offset = s.params.cube.shadowOffset;
2669                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');
2670                        }
2671                    }
2672                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;
2673                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');
2674                },
2675                setTransition: function (duration) {
2676                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
2677                    if (s.params.cube.shadow && !s.isHorizontal()) {
2678                        s.container.find('.swiper-cube-shadow').transition(duration);
2679                    }
2680                }
2681            },
2682            coverflow: {
2683                setTranslate: function () {
2684                    var transform = s.translate;
2685                    var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;
2686                    var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;
2687                    var translate = s.params.coverflow.depth;
2688                    //Each slide offset from center
2689                    for (var i = 0, length = s.slides.length; i < length; i++) {
2690                        var slide = s.slides.eq(i);
2691                        var slideSize = s.slidesSizesGrid[i];
2692                        var slideOffset = slide[0].swiperSlideOffset;
2693                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;
2694        
2695                        var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;
2696                        var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;
2697                        // var rotateZ = 0
2698                        var translateZ = -translate * Math.abs(offsetMultiplier);
2699        
2700                        var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);
2701                        var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;
2702        
2703                        //Fix for ultra small values
2704                        if (Math.abs(translateX) < 0.001) translateX = 0;
2705                        if (Math.abs(translateY) < 0.001) translateY = 0;
2706                        if (Math.abs(translateZ) < 0.001) translateZ = 0;
2707                        if (Math.abs(rotateY) < 0.001) rotateY = 0;
2708                        if (Math.abs(rotateX) < 0.001) rotateX = 0;
2709        
2710                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
2711        
2712                        slide.transform(slideTransform);
2713                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
2714                        if (s.params.coverflow.slideShadows) {
2715                            //Set shadows
2716                            var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
2717                            var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
2718                            if (shadowBefore.length === 0) {
2719                                shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
2720                                slide.append(shadowBefore);
2721                            }
2722                            if (shadowAfter.length === 0) {
2723                                shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
2724                                slide.append(shadowAfter);
2725                            }
2726                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
2727                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;
2728                        }
2729                    }
2730        
2731                    //Set correct perspective for IE10
2732                    if (s.browser.ie) {
2733                        var ws = s.wrapper[0].style;
2734                        ws.perspectiveOrigin = center + 'px 50%';
2735                    }
2736                },
2737                setTransition: function (duration) {
2738                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
2739                }
2740            }
2741        };
2742
2743        /*=========================
2744          Images Lazy Loading
2745          ===========================*/
2746        s.lazy = {
2747            initialImageLoaded: false,
2748            loadImageInSlide: function (index, loadInDuplicate) {
2749                if (typeof index === 'undefined') return;
2750                if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;
2751                if (s.slides.length === 0) return;
2752        
2753                var slide = s.slides.eq(index);
2754                var img = slide.find('.' + s.params.lazyLoadingClass + ':not(.' + s.params.lazyStatusLoadedClass + '):not(.' + s.params.lazyStatusLoadingClass + ')');
2755                if (slide.hasClass(s.params.lazyLoadingClass) && !slide.hasClass(s.params.lazyStatusLoadedClass) && !slide.hasClass(s.params.lazyStatusLoadingClass)) {
2756                    img = img.add(slide[0]);
2757                }
2758                if (img.length === 0) return;
2759        
2760                img.each(function () {
2761                    var _img = $(this);
2762                    _img.addClass(s.params.lazyStatusLoadingClass);
2763                    var background = _img.attr('data-background');
2764                    var src = _img.attr('data-src'),
2765                        srcset = _img.attr('data-srcset'),
2766                        sizes = _img.attr('data-sizes');
2767                    s.loadImage(_img[0], (src || background), srcset, sizes, false, function () {
2768                        if (background) {
2769                            _img.css('background-image', 'url("' + background + '")');
2770                            _img.removeAttr('data-background');
2771                        }
2772                        else {
2773                            if (srcset) {
2774                                _img.attr('srcset', srcset);
2775                                _img.removeAttr('data-srcset');
2776                            }
2777                            if (sizes) {
2778                                _img.attr('sizes', sizes);
2779                                _img.removeAttr('data-sizes');
2780                            }
2781                            if (src) {
2782                                _img.attr('src', src);
2783                                _img.removeAttr('data-src');
2784                            }
2785        
2786                        }
2787        
2788                        _img.addClass(s.params.lazyStatusLoadedClass).removeClass(s.params.lazyStatusLoadingClass);
2789                        slide.find('.' + s.params.lazyPreloaderClass + ', .' + s.params.preloaderClass).remove();
2790                        if (s.params.loop && loadInDuplicate) {
2791                            var slideOriginalIndex = slide.attr('data-swiper-slide-index');
2792                            if (slide.hasClass(s.params.slideDuplicateClass)) {
2793                                var originalSlide = s.wrapper.children('[data-swiper-slide-index="' + slideOriginalIndex + '"]:not(.' + s.params.slideDuplicateClass + ')');
2794                                s.lazy.loadImageInSlide(originalSlide.index(), false);
2795                            }
2796                            else {
2797                                var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + slideOriginalIndex + '"]');
2798                                s.lazy.loadImageInSlide(duplicatedSlide.index(), false);
2799                            }
2800                        }
2801                        s.emit('onLazyImageReady', s, slide[0], _img[0]);
2802                    });
2803        
2804                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);
2805                });
2806        
2807            },
2808            load: function () {
2809                var i;
2810                var slidesPerView = s.params.slidesPerView;
2811                if (slidesPerView === 'auto') {
2812                    slidesPerView = 0;
2813                }
2814                if (!s.lazy.initialImageLoaded) s.lazy.initialImageLoaded = true;
2815                if (s.params.watchSlidesVisibility) {
2816                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {
2817                        s.lazy.loadImageInSlide($(this).index());
2818                    });
2819                }
2820                else {
2821                    if (slidesPerView > 1) {
2822                        for (i = s.activeIndex; i < s.activeIndex + slidesPerView ; i++) {
2823                            if (s.slides[i]) s.lazy.loadImageInSlide(i);
2824                        }
2825                    }
2826                    else {
2827                        s.lazy.loadImageInSlide(s.activeIndex);
2828                    }
2829                }
2830                if (s.params.lazyLoadingInPrevNext) {
2831                    if (slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {
2832                        var amount = s.params.lazyLoadingInPrevNextAmount;
2833                        var spv = slidesPerView;
2834                        var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);
2835                        var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);
2836                        // Next Slides
2837                        for (i = s.activeIndex + slidesPerView; i < maxIndex; i++) {
2838                            if (s.slides[i]) s.lazy.loadImageInSlide(i);
2839                        }
2840                        // Prev Slides
2841                        for (i = minIndex; i < s.activeIndex ; i++) {
2842                            if (s.slides[i]) s.lazy.loadImageInSlide(i);
2843                        }
2844                    }
2845                    else {
2846                        var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);
2847                        if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());
2848        
2849                        var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);
2850                        if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());
2851                    }
2852                }
2853            },
2854            onTransitionStart: function () {
2855                if (s.params.lazyLoading) {
2856                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {
2857                        s.lazy.load();
2858                    }
2859                }
2860            },
2861            onTransitionEnd: function () {
2862                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {
2863                    s.lazy.load();
2864                }
2865            }
2866        };
2867        
2868
2869        /*=========================
2870          Scrollbar
2871          ===========================*/
2872        s.scrollbar = {
2873            isTouched: false,
2874            setDragPosition: function (e) {
2875                var sb = s.scrollbar;
2876                var x = 0, y = 0;
2877                var translate;
2878                var pointerPosition = s.isHorizontal() ?
2879                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :
2880                    ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;
2881                var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;
2882                var positionMin = -s.minTranslate() * sb.moveDivider;
2883                var positionMax = -s.maxTranslate() * sb.moveDivider;
2884                if (position < positionMin) {
2885                    position = positionMin;
2886                }
2887                else if (position > positionMax) {
2888                    position = positionMax;
2889                }
2890                position = -position / sb.moveDivider;
2891                s.updateProgress(position);
2892                s.setWrapperTranslate(position, true);
2893            },
2894            dragStart: function (e) {
2895                var sb = s.scrollbar;
2896                sb.isTouched = true;
2897                e.preventDefault();
2898                e.stopPropagation();
2899        
2900                sb.setDragPosition(e);
2901                clearTimeout(sb.dragTimeout);
2902        
2903                sb.track.transition(0);
2904                if (s.params.scrollbarHide) {
2905                    sb.track.css('opacity', 1);
2906                }
2907                s.wrapper.transition(100);
2908                sb.drag.transition(100);
2909                s.emit('onScrollbarDragStart', s);
2910            },
2911            dragMove: function (e) {
2912                var sb = s.scrollbar;
2913                if (!sb.isTouched) return;
2914                if (e.preventDefault) e.preventDefault();
2915                else e.returnValue = false;
2916                sb.setDragPosition(e);
2917                s.wrapper.transition(0);
2918                sb.track.transition(0);
2919                sb.drag.transition(0);
2920                s.emit('onScrollbarDragMove', s);
2921            },
2922            dragEnd: function (e) {
2923                var sb = s.scrollbar;
2924                if (!sb.isTouched) return;
2925                sb.isTouched = false;
2926                if (s.params.scrollbarHide) {
2927                    clearTimeout(sb.dragTimeout);
2928                    sb.dragTimeout = setTimeout(function () {
2929                        sb.track.css('opacity', 0);
2930                        sb.track.transition(400);
2931                    }, 1000);
2932        
2933                }
2934                s.emit('onScrollbarDragEnd', s);
2935                if (s.params.scrollbarSnapOnRelease) {
2936                    s.slideReset();
2937                }
2938            },
2939            draggableEvents: (function () {
2940                if ((s.params.simulateTouch === false && !s.support.touch)) return s.touchEventsDesktop;
2941                else return s.touchEvents;
2942            })(),
2943            enableDraggable: function () {
2944                var sb = s.scrollbar;
2945                var target = s.support.touch ? sb.track : document;
2946                $(sb.track).on(sb.draggableEvents.start, sb.dragStart);
2947                $(target).on(sb.draggableEvents.move, sb.dragMove);
2948                $(target).on(sb.draggableEvents.end, sb.dragEnd);
2949            },
2950            disableDraggable: function () {
2951                var sb = s.scrollbar;
2952                var target = s.support.touch ? sb.track : document;
2953                $(sb.track).off(s.draggableEvents.start, sb.dragStart);
2954                $(target).off(s.draggableEvents.move, sb.dragMove);
2955                $(target).off(s.draggableEvents.end, sb.dragEnd);
2956            },
2957            set: function () {
2958                if (!s.params.scrollbar) return;
2959                var sb = s.scrollbar;
2960                sb.track = $(s.params.scrollbar);
2961                if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {
2962                    sb.track = s.container.find(s.params.scrollbar);
2963                }
2964                sb.drag = sb.track.find('.swiper-scrollbar-drag');
2965                if (sb.drag.length === 0) {
2966                    sb.drag = $('<div class="swiper-scrollbar-drag"></div>');
2967                    sb.track.append(sb.drag);
2968                }
2969                sb.drag[0].style.width = '';
2970                sb.drag[0].style.height = '';
2971                sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;
2972        
2973                sb.divider = s.size / s.virtualSize;
2974                sb.moveDivider = sb.divider * (sb.trackSize / s.size);
2975                sb.dragSize = sb.trackSize * sb.divider;
2976        
2977                if (s.isHorizontal()) {
2978                    sb.drag[0].style.width = sb.dragSize + 'px';
2979                }
2980                else {
2981                    sb.drag[0].style.height = sb.dragSize + 'px';
2982                }
2983        
2984                if (sb.divider >= 1) {
2985                    sb.track[0].style.display = 'none';
2986                }
2987                else {
2988                    sb.track[0].style.display = '';
2989                }
2990                if (s.params.scrollbarHide) {
2991                    sb.track[0].style.opacity = 0;
2992                }
2993            },
2994            setTranslate: function () {
2995                if (!s.params.scrollbar) return;
2996                var diff;
2997                var sb = s.scrollbar;
2998                var translate = s.translate || 0;
2999                var newPos;
3000        
3001                var newSize = sb.dragSize;
3002                newPos = (sb.trackSize - sb.dragSize) * s.progress;
3003                if (s.rtl && s.isHorizontal()) {
3004                    newPos = -newPos;
3005                    if (newPos > 0) {
3006                        newSize = sb.dragSize - newPos;
3007                        newPos = 0;
3008                    }
3009                    else if (-newPos + sb.dragSize > sb.trackSize) {
3010                        newSize = sb.trackSize + newPos;
3011                    }
3012                }
3013                else {
3014                    if (newPos < 0) {
3015                        newSize = sb.dragSize + newPos;
3016                        newPos = 0;
3017                    }
3018                    else if (newPos + sb.dragSize > sb.trackSize) {
3019                        newSize = sb.trackSize - newPos;
3020                    }
3021                }
3022                if (s.isHorizontal()) {
3023                    if (s.support.transforms3d) {
3024                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');
3025                    }
3026                    else {
3027                        sb.drag.transform('translateX(' + (newPos) + 'px)');
3028                    }
3029                    sb.drag[0].style.width = newSize + 'px';
3030                }
3031                else {
3032                    if (s.support.transforms3d) {
3033                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');
3034                    }
3035                    else {
3036                        sb.drag.transform('translateY(' + (newPos) + 'px)');
3037                    }
3038                    sb.drag[0].style.height = newSize + 'px';
3039                }
3040                if (s.params.scrollbarHide) {
3041                    clearTimeout(sb.timeout);
3042                    sb.track[0].style.opacity = 1;
3043                    sb.timeout = setTimeout(function () {
3044                        sb.track[0].style.opacity = 0;
3045                        sb.track.transition(400);
3046                    }, 1000);
3047                }
3048            },
3049            setTransition: function (duration) {
3050                if (!s.params.scrollbar) return;
3051                s.scrollbar.drag.transition(duration);
3052            }
3053        };
3054
3055        /*=========================
3056          Controller
3057          ===========================*/
3058        s.controller = {
3059            LinearSpline: function (x, y) {
3060                this.x = x;
3061                this.y = y;
3062                this.lastIndex = x.length - 1;
3063                // Given an x value (x2), return the expected y2 value:
3064                // (x1,y1) is the known point before given value,
3065                // (x3,y3) is the known point after given value.
3066                var i1, i3;
3067                var l = this.x.length;
3068        
3069                this.interpolate = function (x2) {
3070                    if (!x2) return 0;
3071        
3072                    // Get the indexes of x1 and x3 (the array indexes before and after given x2):
3073                    i3 = binarySearch(this.x, x2);
3074                    i1 = i3 - 1;
3075        
3076                    // We have our indexes i1 & i3, so we can calculate already:
3077                    // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
3078                    return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];
3079                };
3080        
3081                var binarySearch = (function() {
3082                    var maxIndex, minIndex, guess;
3083                    return function(array, val) {
3084                        minIndex = -1;
3085                        maxIndex = array.length;
3086                        while (maxIndex - minIndex > 1)
3087                            if (array[guess = maxIndex + minIndex >> 1] <= val) {
3088                                minIndex = guess;
3089                            } else {
3090                                maxIndex = guess;
3091                            }
3092                        return maxIndex;
3093                    };
3094                })();
3095            },
3096            //xxx: for now i will just save one spline function to to
3097            getInterpolateFunction: function(c){
3098                if(!s.controller.spline) s.controller.spline = s.params.loop ?
3099                    new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :
3100                    new s.controller.LinearSpline(s.snapGrid, c.snapGrid);
3101            },
3102            setTranslate: function (translate, byController) {
3103               var controlled = s.params.control;
3104               var multiplier, controlledTranslate;
3105               function setControlledTranslate(c) {
3106                    // this will create an Interpolate function based on the snapGrids
3107                    // x is the Grid of the scrolled scroller and y will be the controlled scroller
3108                    // it makes sense to create this only once and recall it for the interpolation
3109                    // the function does a lot of value caching for performance
3110                    translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;
3111                    if (s.params.controlBy === 'slide') {
3112                        s.controller.getInterpolateFunction(c);
3113                        // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
3114                        // but it did not work out
3115                        controlledTranslate = -s.controller.spline.interpolate(-translate);
3116                    }
3117        
3118                    if(!controlledTranslate || s.params.controlBy === 'container'){
3119                        multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());
3120                        controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();
3121                    }
3122        
3123                    if (s.params.controlInverse) {
3124                        controlledTranslate = c.maxTranslate() - controlledTranslate;
3125                    }
3126                    c.updateProgress(controlledTranslate);
3127                    c.setWrapperTranslate(controlledTranslate, false, s);
3128                    c.updateActiveIndex();
3129               }
3130               if (s.isArray(controlled)) {
3131                   for (var i = 0; i < controlled.length; i++) {
3132                       if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
3133                           setControlledTranslate(controlled[i]);
3134                       }
3135                   }
3136               }
3137               else if (controlled instanceof Swiper && byController !== controlled) {
3138        
3139                   setControlledTranslate(controlled);
3140               }
3141            },
3142            setTransition: function (duration, byController) {
3143                var controlled = s.params.control;
3144                var i;
3145                function setControlledTransition(c) {
3146                    c.setWrapperTransition(duration, s);
3147                    if (duration !== 0) {
3148                        c.onTransitionStart();
3149                        c.wrapper.transitionEnd(function(){
3150                            if (!controlled) return;
3151                            if (c.params.loop && s.params.controlBy === 'slide') {
3152                                c.fixLoop();
3153                            }
3154                            c.onTransitionEnd();
3155        
3156                        });
3157                    }
3158                }
3159                if (s.isArray(controlled)) {
3160                    for (i = 0; i < controlled.length; i++) {
3161                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
3162                            setControlledTransition(controlled[i]);
3163                        }
3164                    }
3165                }
3166                else if (controlled instanceof Swiper && byController !== controlled) {
3167                    setControlledTransition(controlled);
3168                }
3169            }
3170        };
3171
3172        /*=========================
3173          Hash Navigation
3174          ===========================*/
3175        s.hashnav = {
3176            onHashCange: function (e, a) {
3177                var newHash = document.location.hash.replace('#', '');
3178                var activeSlideHash = s.slides.eq(s.activeIndex).attr('data-hash');
3179                if (newHash !== activeSlideHash) {
3180                    s.slideTo(s.wrapper.children('.' + s.params.slideClass + '[data-hash="' + (newHash) + '"]').index());
3181                }
3182            },
3183            attachEvents: function (detach) {
3184                var action = detach ? 'off' : 'on';
3185                $(window)[action]('hashchange', s.hashnav.onHashCange);
3186            },
3187            setHash: function () {
3188                if (!s.hashnav.initialized || !s.params.hashnav) return;
3189                if (s.params.replaceState && window.history && window.history.replaceState) {
3190                    window.history.replaceState(null, null, ('#' + s.slides.eq(s.activeIndex).attr('data-hash') || ''));
3191                } else {
3192                    var slide = s.slides.eq(s.activeIndex);
3193                    var hash = slide.attr('data-hash') || slide.attr('data-history');
3194                    document.location.hash = hash || '';
3195                }
3196            },
3197            init: function () {
3198                if (!s.params.hashnav || s.params.history) return;
3199                s.hashnav.initialized = true;
3200                var hash = document.location.hash.replace('#', '');
3201                if (!hash) return;
3202                var speed = 0;
3203                for (var i = 0, length = s.slides.length; i < length; i++) {
3204                    var slide = s.slides.eq(i);
3205                    var slideHash = slide.attr('data-hash') || slide.attr('data-history');
3206                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {
3207                        var index = slide.index();
3208                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);
3209                    }
3210                }
3211                if (s.params.hashnavWatchState) s.hashnav.attachEvents();
3212            },
3213            destroy: function () {
3214                if (s.params.hashnavWatchState) s.hashnav.attachEvents(true);
3215            }
3216        };
3217
3218        /*=========================
3219          History Api with fallback to Hashnav
3220          ===========================*/
3221        s.history = {
3222            init: function () {
3223                if (!s.params.history) return;
3224                if (!window.history || !window.history.pushState) {
3225                    s.params.history = false;
3226                    s.params.hashnav = true;
3227                    return;
3228                }
3229                s.history.initialized = true;
3230                this.paths = this.getPathValues();
3231                if (!this.paths.key && !this.paths.value) return;
3232                this.scrollToSlide(0, this.paths.value, s.params.runCallbacksOnInit);
3233                if (!s.params.replaceState) {
3234                    window.addEventListener('popstate', this.setHistoryPopState);
3235                }
3236            },
3237            setHistoryPopState: function() {
3238                s.history.paths = s.history.getPathValues();
3239                s.history.scrollToSlide(s.params.speed, s.history.paths.value, false);
3240            },
3241            getPathValues: function() {
3242                var pathArray = window.location.pathname.slice(1).split('/');
3243                var total = pathArray.length;
3244                var key = pathArray[total - 2];
3245                var value = pathArray[total - 1];
3246                return { key: key, value: value };
3247            },
3248            setHistory: function (key, index) {
3249                if (!s.history.initialized || !s.params.history) return;
3250                var slide = s.slides.eq(index);
3251                var value = this.slugify(slide.attr('data-history'));
3252                if (!window.location.pathname.includes(key)) {
3253                    value = key + '/' + value;
3254                }
3255                if (s.params.replaceState) {
3256                    window.history.replaceState(null, null, value);
3257                } else {
3258                    window.history.pushState(null, null, value);
3259                }
3260            },
3261            slugify: function(text) {
3262                return text.toString().toLowerCase()
3263                    .replace(/\s+/g, '-')
3264                    .replace(/[^\w\-]+/g, '')
3265                    .replace(/\-\-+/g, '-')
3266                    .replace(/^-+/, '')
3267                    .replace(/-+$/, '');
3268            },
3269            scrollToSlide: function(speed, value, runCallbacks) {
3270                if (value) {
3271                    for (var i = 0, length = s.slides.length; i < length; i++) {
3272                        var slide = s.slides.eq(i);
3273                        var slideHistory = this.slugify(slide.attr('data-history'));
3274                        if (slideHistory === value && !slide.hasClass(s.params.slideDuplicateClass)) {
3275                            var index = slide.index();
3276                            s.slideTo(index, speed, runCallbacks);
3277                        }
3278                    }
3279                } else {
3280                    s.slideTo(0, speed, runCallbacks);
3281                }
3282            }
3283        };
3284
3285        /*=========================
3286          Keyboard Control
3287          ===========================*/
3288        function handleKeyboard(e) {
3289            if (e.originalEvent) e = e.originalEvent; //jquery fix
3290            var kc = e.keyCode || e.charCode;
3291            // Directions locks
3292            if (!s.params.allowSwipeToNext && (s.isHorizontal() && kc === 39 || !s.isHorizontal() && kc === 40)) {
3293                return false;
3294            }
3295            if (!s.params.allowSwipeToPrev && (s.isHorizontal() && kc === 37 || !s.isHorizontal() && kc === 38)) {
3296                return false;
3297            }
3298            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
3299                return;
3300            }
3301            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {
3302                return;
3303            }
3304            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
3305                var inView = false;
3306                //Check that swiper should be inside of visible area of window
3307                if (s.container.parents('.' + s.params.slideClass).length > 0 && s.container.parents('.' + s.params.slideActiveClass).length === 0) {
3308                    return;
3309                }
3310                var windowScroll = {
3311                    left: window.pageXOffset,
3312                    top: window.pageYOffset
3313                };
3314                var windowWidth = window.innerWidth;
3315                var windowHeight = window.innerHeight;
3316                var swiperOffset = s.container.offset();
3317                if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;
3318                var swiperCoord = [
3319                    [swiperOffset.left, swiperOffset.top],
3320                    [swiperOffset.left + s.width, swiperOffset.top],
3321                    [swiperOffset.left, swiperOffset.top + s.height],
3322                    [swiperOffset.left + s.width, swiperOffset.top + s.height]
3323                ];
3324                for (var i = 0; i < swiperCoord.length; i++) {
3325                    var point = swiperCoord[i];
3326                    if (
3327                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&
3328                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight
3329                    ) {
3330                        inView = true;
3331                    }
3332        
3333                }
3334                if (!inView) return;
3335            }
3336            if (s.isHorizontal()) {
3337                if (kc === 37 || kc === 39) {
3338                    if (e.preventDefault) e.preventDefault();
3339                    else e.returnValue = false;
3340                }
3341                if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();
3342                if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();
3343            }
3344            else {
3345                if (kc === 38 || kc === 40) {
3346                    if (e.preventDefault) e.preventDefault();
3347                    else e.returnValue = false;
3348                }
3349                if (kc === 40) s.slideNext();
3350                if (kc === 38) s.slidePrev();
3351            }
3352        }
3353        s.disableKeyboardControl = function () {
3354            s.params.keyboardControl = false;
3355            $(document).off('keydown', handleKeyboard);
3356        };
3357        s.enableKeyboardControl = function () {
3358            s.params.keyboardControl = true;
3359            $(document).on('keydown', handleKeyboard);
3360        };
3361        
3362
3363        /*=========================
3364          Mousewheel Control
3365          ===========================*/
3366        s.mousewheel = {
3367            event: false,
3368            lastScrollTime: (new window.Date()).getTime()
3369        };
3370        if (s.params.mousewheelControl) {
3371            /**
3372             * The best combination if you prefer spinX + spinY normalization.  It favors
3373             * the older DOMMouseScroll for Firefox, as FF does not include wheelDelta with
3374             * 'wheel' event, making spin speed determination impossible.
3375             */
3376            s.mousewheel.event = (navigator.userAgent.indexOf('firefox') > -1) ?
3377                'DOMMouseScroll' :
3378                isEventSupported() ?
3379                    'wheel' : 'mousewheel';
3380        }
3381        
3382        function isEventSupported() {
3383            var eventName = 'onwheel';
3384            var isSupported = eventName in document;
3385        
3386            if (!isSupported) {
3387                var element = document.createElement('div');
3388                element.setAttribute(eventName, 'return;');
3389                isSupported = typeof element[eventName] === 'function';
3390            }
3391        
3392            if (!isSupported &&
3393                document.implementation &&
3394                document.implementation.hasFeature &&
3395                    // always returns true in newer browsers as per the standard.
3396                    // @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
3397                document.implementation.hasFeature('', '') !== true ) {
3398                // This is the only way to test support for the `wheel` event in IE9+.
3399                isSupported = document.implementation.hasFeature('Events.wheel', '3.0');
3400            }
3401        
3402            return isSupported;
3403        }
3404        
3405        function handleMousewheel(e) {
3406            if (e.originalEvent) e = e.originalEvent; //jquery fix
3407            var delta = 0;
3408            var rtlFactor = s.rtl ? -1 : 1;
3409        
3410            var data = normalizeWheel( e );
3411        
3412            if (s.params.mousewheelForceToAxis) {
3413                if (s.isHorizontal()) {
3414                    if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = data.pixelX * rtlFactor;
3415                    else return;
3416                }
3417                else {
3418                    if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = data.pixelY;
3419                    else return;
3420                }
3421            }
3422            else {
3423                delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? - data.pixelX * rtlFactor : - data.pixelY;
3424            }
3425        
3426            if (delta === 0) return;
3427        
3428            if (s.params.mousewheelInvert) delta = -delta;
3429        
3430            if (!s.params.freeMode) {
3431                if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {
3432                    if (delta < 0) {
3433                        if ((!s.isEnd || s.params.loop) && !s.animating) {
3434                            s.slideNext();
3435                            s.emit('onScroll', s, e);
3436                        }
3437                        else if (s.params.mousewheelReleaseOnEdges) return true;
3438                    }
3439                    else {
3440                        if ((!s.isBeginning || s.params.loop) && !s.animating) {
3441                            s.slidePrev();
3442                            s.emit('onScroll', s, e);
3443                        }
3444                        else if (s.params.mousewheelReleaseOnEdges) return true;
3445                    }
3446                }
3447                s.mousewheel.lastScrollTime = (new window.Date()).getTime();
3448        
3449            }
3450            else {
3451                //Freemode or scrollContainer:
3452                var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;
3453                var wasBeginning = s.isBeginning,
3454                    wasEnd = s.isEnd;
3455        
3456                if (position >= s.minTranslate()) position = s.minTranslate();
3457                if (position <= s.maxTranslate()) position = s.maxTranslate();
3458        
3459                s.setWrapperTransition(0);
3460                s.setWrapperTranslate(position);
3461                s.updateProgress();
3462                s.updateActiveIndex();
3463        
3464                if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {
3465                    s.updateClasses();
3466                }
3467        
3468                if (s.params.freeModeSticky) {
3469                    clearTimeout(s.mousewheel.timeout);
3470                    s.mousewheel.timeout = setTimeout(function () {
3471                        s.slideReset();
3472                    }, 300);
3473                }
3474                else {
3475                    if (s.params.lazyLoading && s.lazy) {
3476                        s.lazy.load();
3477                    }
3478                }
3479                // Emit event
3480                s.emit('onScroll', s, e);
3481        
3482                // Stop autoplay
3483                if (s.params.autoplay && s.params.autoplayDisableOnInteraction) s.stopAutoplay();
3484        
3485                // Return page scroll on edge positions
3486                if (position === 0 || position === s.maxTranslate()) return;
3487            }
3488        
3489            if (e.preventDefault) e.preventDefault();
3490            else e.returnValue = false;
3491            return false;
3492        }
3493        s.disableMousewheelControl = function () {
3494            if (!s.mousewheel.event) return false;
3495            var target = s.container;
3496            if (s.params.mousewheelEventsTarged !== 'container') {
3497                target = $(s.params.mousewheelEventsTarged);
3498            }
3499            target.off(s.mousewheel.event, handleMousewheel);
3500            return true;
3501        };
3502        
3503        s.enableMousewheelControl = function () {
3504            if (!s.mousewheel.event) return false;
3505            var target = s.container;
3506            if (s.params.mousewheelEventsTarged !== 'container') {
3507                target = $(s.params.mousewheelEventsTarged);
3508            }
3509            target.on(s.mousewheel.event, handleMousewheel);
3510            return true;
3511        };
3512        
3513        /**
3514         * Mouse wheel (and 2-finger trackpad) support on the web sucks.  It is
3515         * complicated, thus this doc is long and (hopefully) detailed enough to answer
3516         * your questions.
3517         *
3518         * If you need to react to the mouse wheel in a predictable way, this code is
3519         * like your bestest friend. * hugs *
3520         *
3521         * As of today, there are 4 DOM event types you can listen to:
3522         *
3523         *   'wheel'                -- Chrome(31+), FF(17+), IE(9+)
3524         *   'mousewheel'           -- Chrome, IE(6+), Opera, Safari
3525         *   'MozMousePixelScroll'  -- FF(3.5 only!) (2010-2013) -- don't bother!
3526         *   'DOMMouseScroll'       -- FF(0.9.7+) since 2003
3527         *
3528         * So what to do?  The is the best:
3529         *
3530         *   normalizeWheel.getEventType();
3531         *
3532         * In your event callback, use this code to get sane interpretation of the
3533         * deltas.  This code will return an object with properties:
3534         *
3535         *   spinX   -- normalized spin speed (use for zoom) - x plane
3536         *   spinY   -- " - y plane
3537         *   pixelX  -- normalized distance (to pixels) - x plane
3538         *   pixelY  -- " - y plane
3539         *
3540         * Wheel values are provided by the browser assuming you are using the wheel to
3541         * scroll a web page by a number of lines or pixels (or pages).  Values can vary
3542         * significantly on different platforms and browsers, forgetting that you can
3543         * scroll at different speeds.  Some devices (like trackpads) emit more events
3544         * at smaller increments with fine granularity, and some emit massive jumps with
3545         * linear speed or acceleration.
3546         *
3547         * This code does its best to normalize the deltas for you:
3548         *
3549         *   - spin is trying to normalize how far the wheel was spun (or trackpad
3550         *     dragged).  This is super useful for zoom support where you want to
3551         *     throw away the chunky scroll steps on the PC and make those equal to
3552         *     the slow and smooth tiny steps on the Mac. Key data: This code tries to
3553         *     resolve a single slow step on a wheel to 1.
3554         *
3555         *   - pixel is normalizing the desired scroll delta in pixel units.  You'll
3556         *     get the crazy differences between browsers, but at least it'll be in
3557         *     pixels!
3558         *
3559         *   - positive value indicates scrolling DOWN/RIGHT, negative UP/LEFT.  This
3560         *     should translate to positive value zooming IN, negative zooming OUT.
3561         *     This matches the newer 'wheel' event.
3562         *
3563         * Why are there spinX, spinY (or pixels)?
3564         *
3565         *   - spinX is a 2-finger side drag on the trackpad, and a shift + wheel turn
3566         *     with a mouse.  It results in side-scrolling in the browser by default.
3567         *
3568         *   - spinY is what you expect -- it's the classic axis of a mouse wheel.
3569         *
3570         *   - I dropped spinZ/pixelZ.  It is supported by the DOM 3 'wheel' event and
3571         *     probably is by browsers in conjunction with fancy 3D controllers .. but
3572         *     you know.
3573         *
3574         * Implementation info:
3575         *
3576         * Examples of 'wheel' event if you scroll slowly (down) by one step with an
3577         * average mouse:
3578         *
3579         *   OS X + Chrome  (mouse)     -    4   pixel delta  (wheelDelta -120)
3580         *   OS X + Safari  (mouse)     -  N/A   pixel delta  (wheelDelta  -12)
3581         *   OS X + Firefox (mouse)     -    0.1 line  delta  (wheelDelta  N/A)
3582         *   Win8 + Chrome  (mouse)     -  100   pixel delta  (wheelDelta -120)
3583         *   Win8 + Firefox (mouse)     -    3   line  delta  (wheelDelta -120)
3584         *
3585         * On the trackpad:
3586         *
3587         *   OS X + Chrome  (trackpad)  -    2   pixel delta  (wheelDelta   -6)
3588         *   OS X + Firefox (trackpad)  -    1   pixel delta  (wheelDelta  N/A)
3589         *
3590         * On other/older browsers.. it's more complicated as there can be multiple and
3591         * also missing delta values.
3592         *
3593         * The 'wheel' event is more standard:
3594         *
3595         * https://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
3596         *
3597         * The basics is that it includes a unit, deltaMode (pixels, lines, pages), and
3598         * deltaX, deltaY and deltaZ.  Some browsers provide other values to maintain
3599         * backward compatibility with older events.  Those other values help us
3600         * better normalize spin speed.  Example of what the browsers provide:
3601         *
3602         *                          | event.wheelDelta | event.detail
3603         *        ------------------+------------------+--------------
3604         *          Safari v5/OS X  |       -120       |       0
3605         *          Safari v5/Win7  |       -120       |       0
3606         *         Chrome v17/OS X  |       -120       |       0
3607         *         Chrome v17/Win7  |       -120       |       0
3608         *                IE9/Win7  |       -120       |   undefined
3609         *         Firefox v4/OS X  |     undefined    |       1
3610         *         Firefox v4/Win7  |     undefined    |       3
3611         *
3612         */
3613        function normalizeWheel( /*object*/ event ) /*object*/ {
3614            // Reasonable defaults
3615            var PIXEL_STEP = 10;
3616            var LINE_HEIGHT = 40;
3617            var PAGE_HEIGHT = 800;
3618        
3619            var sX = 0, sY = 0,       // spinX, spinY
3620                pX = 0, pY = 0;       // pixelX, pixelY
3621        
3622            // Legacy
3623            if( 'detail' in event ) {
3624                sY = event.detail;
3625            }
3626            if( 'wheelDelta' in event ) {
3627                sY = -event.wheelDelta / 120;
3628            }
3629            if( 'wheelDeltaY' in event ) {
3630                sY = -event.wheelDeltaY / 120;
3631            }
3632            if( 'wheelDeltaX' in event ) {
3633                sX = -event.wheelDeltaX / 120;
3634            }
3635        
3636            // side scrolling on FF with DOMMouseScroll
3637            if( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) {
3638                sX = sY;
3639                sY = 0;
3640            }
3641        
3642            pX = sX * PIXEL_STEP;
3643            pY = sY * PIXEL_STEP;
3644        
3645            if( 'deltaY' in event ) {
3646                pY = event.deltaY;
3647            }
3648            if( 'deltaX' in event ) {
3649                pX = event.deltaX;
3650            }
3651        
3652            if( (pX || pY) && event.deltaMode ) {
3653                if( event.deltaMode === 1 ) {          // delta in LINE units
3654                    pX *= LINE_HEIGHT;
3655                    pY *= LINE_HEIGHT;
3656                } else {                             // delta in PAGE units
3657                    pX *= PAGE_HEIGHT;
3658                    pY *= PAGE_HEIGHT;
3659                }
3660            }
3661        
3662            // Fall-back if spin cannot be determined
3663            if( pX && !sX ) {
3664                sX = (pX < 1) ? -1 : 1;
3665            }
3666            if( pY && !sY ) {
3667                sY = (pY < 1) ? -1 : 1;
3668            }
3669        
3670            return {
3671                spinX: sX,
3672                spinY: sY,
3673                pixelX: pX,
3674                pixelY: pY
3675            };
3676        }
3677
3678        /*=========================
3679          Parallax
3680          ===========================*/
3681        function setParallaxTransform(el, progress) {
3682            el = $(el);
3683            var p, pX, pY;
3684            var rtlFactor = s.rtl ? -1 : 1;
3685        
3686            p = el.attr('data-swiper-parallax') || '0';
3687            pX = el.attr('data-swiper-parallax-x');
3688            pY = el.attr('data-swiper-parallax-y');
3689            if (pX || pY) {
3690                pX = pX || '0';
3691                pY = pY || '0';
3692            }
3693            else {
3694                if (s.isHorizontal()) {
3695                    pX = p;
3696                    pY = '0';
3697                }
3698                else {
3699                    pY = p;
3700                    pX = '0';
3701                }
3702            }
3703        
3704            if ((pX).indexOf('%') >= 0) {
3705                pX = parseInt(pX, 10) * progress * rtlFactor + '%';
3706            }
3707            else {
3708                pX = pX * progress * rtlFactor + 'px' ;
3709            }
3710            if ((pY).indexOf('%') >= 0) {
3711                pY = parseInt(pY, 10) * progress + '%';
3712            }
3713            else {
3714                pY = pY * progress + 'px' ;
3715            }
3716        
3717            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');
3718        }
3719        s.parallax = {
3720            setTranslate: function () {
3721                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
3722                    setParallaxTransform(this, s.progress);
3723        
3724                });
3725                s.slides.each(function () {
3726                    var slide = $(this);
3727                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {
3728                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);
3729                        setParallaxTransform(this, progress);
3730                    });
3731                });
3732            },
3733            setTransition: function (duration) {
3734                if (typeof duration === 'undefined') duration = s.params.speed;
3735                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
3736                    var el = $(this);
3737                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;
3738                    if (duration === 0) parallaxDuration = 0;
3739                    el.transition(parallaxDuration);
3740                });
3741            }
3742        };
3743        
3744
3745        /*=========================
3746          Zoom
3747          ===========================*/
3748        s.zoom = {
3749            // "Global" Props
3750            scale: 1,
3751            currentScale: 1,
3752            isScaling: false,
3753            gesture: {
3754                slide: undefined,
3755                slideWidth: undefined,
3756                slideHeight: undefined,
3757                image: undefined,
3758                imageWrap: undefined,
3759                zoomMax: s.params.zoomMax
3760            },
3761            image: {
3762                isTouched: undefined,
3763                isMoved: undefined,
3764                currentX: undefined,
3765                currentY: undefined,
3766                minX: undefined,
3767                minY: undefined,
3768                maxX: undefined,
3769                maxY: undefined,
3770                width: undefined,
3771                height: undefined,
3772                startX: undefined,
3773                startY: undefined,
3774                touchesStart: {},
3775                touchesCurrent: {}
3776            },
3777            velocity: {
3778                x: undefined,
3779                y: undefined,
3780                prevPositionX: undefined,
3781                prevPositionY: undefined,
3782                prevTime: undefined
3783            },
3784            // Calc Scale From Multi-touches
3785            getDistanceBetweenTouches: function (e) {
3786                if (e.targetTouches.length < 2) return 1;
3787                var x1 = e.targetTouches[0].pageX,
3788                    y1 = e.targetTouches[0].pageY,
3789                    x2 = e.targetTouches[1].pageX,
3790                    y2 = e.targetTouches[1].pageY;
3791                var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
3792                return distance;
3793            },
3794            // Events
3795            onGestureStart: function (e) {
3796                var z = s.zoom;
3797                if (!s.support.gestures) {
3798                    if (e.type !== 'touchstart' || e.type === 'touchstart' && e.targetTouches.length < 2) {
3799                        return;
3800                    }
3801                    z.gesture.scaleStart = z.getDistanceBetweenTouches(e);
3802                }
3803                if (!z.gesture.slide || !z.gesture.slide.length) {
3804                    z.gesture.slide = $(this);
3805                    if (z.gesture.slide.length === 0) z.gesture.slide = s.slides.eq(s.activeIndex);
3806                    z.gesture.image = z.gesture.slide.find('img, svg, canvas');
3807                    z.gesture.imageWrap = z.gesture.image.parent('.' + s.params.zoomContainerClass);
3808                    z.gesture.zoomMax = z.gesture.imageWrap.attr('data-swiper-zoom') || s.params.zoomMax ;
3809                    if (z.gesture.imageWrap.length === 0) {
3810                        z.gesture.image = undefined;
3811                        return;
3812                    }
3813                }
3814                z.gesture.image.transition(0);
3815                z.isScaling = true;
3816            },
3817            onGestureChange: function (e) {
3818                var z = s.zoom;
3819                if (!s.support.gestures) {
3820                    if (e.type !== 'touchmove' || e.type === 'touchmove' && e.targetTouches.length < 2) {
3821                        return;
3822                    }
3823                    z.gesture.scaleMove = z.getDistanceBetweenTouches(e);
3824                }
3825                if (!z.gesture.image || z.gesture.image.length === 0) return;
3826                if (s.support.gestures) {
3827                    z.scale = e.scale * z.currentScale;
3828                }
3829                else {
3830                    z.scale = (z.gesture.scaleMove / z.gesture.scaleStart) * z.currentScale;
3831                }
3832                if (z.scale > z.gesture.zoomMax) {
3833                    z.scale = z.gesture.zoomMax - 1 + Math.pow((z.scale - z.gesture.zoomMax + 1), 0.5);
3834                }
3835                if (z.scale < s.params.zoomMin) {
3836                    z.scale =  s.params.zoomMin + 1 - Math.pow((s.params.zoomMin - z.scale + 1), 0.5);
3837                }
vendor: 8,595 bytes, lines 3838-3982
3838                z.gesture.image.transform('translate3d(0,0,0) scale(' + z.scale + ')');
3839            },
3840            onGestureEnd: function (e) {
3841                var z = s.zoom;
3842                if (!s.support.gestures) {
3843                    if (e.type !== 'touchend' || e.type === 'touchend' && e.changedTouches.length < 2) {
3844                        return;
3845                    }
3846                }
3847                if (!z.gesture.image || z.gesture.image.length === 0) return;
3848                z.scale = Math.max(Math.min(z.scale, z.gesture.zoomMax), s.params.zoomMin);
3849                z.gesture.image.transition(s.params.speed).transform('translate3d(0,0,0) scale(' + z.scale + ')');
3850                z.currentScale = z.scale;
3851                z.isScaling = false;
3852                if (z.scale === 1) z.gesture.slide = undefined;
3853            },
3854            onTouchStart: function (s, e) {
3855                var z = s.zoom;
3856                if (!z.gesture.image || z.gesture.image.length === 0) return;
3857                if (z.image.isTouched) return;
3858                if (s.device.os === 'android') e.preventDefault();
3859                z.image.isTouched = true;
3860                z.image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
3861                z.image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
3862            },
3863            onTouchMove: function (e) {
3864                var z = s.zoom;
3865                if (!z.gesture.image || z.gesture.image.length === 0) return;
3866                s.allowClick = false;
3867                if (!z.image.isTouched || !z.gesture.slide) return;
3868        
3869                if (!z.image.isMoved) {
3870                    z.image.width = z.gesture.image[0].offsetWidth;
3871                    z.image.height = z.gesture.image[0].offsetHeight;
3872                    z.image.startX = s.getTranslate(z.gesture.imageWrap[0], 'x') || 0;
3873                    z.image.startY = s.getTranslate(z.gesture.imageWrap[0], 'y') || 0;
3874                    z.gesture.slideWidth = z.gesture.slide[0].offsetWidth;
3875                    z.gesture.slideHeight = z.gesture.slide[0].offsetHeight;
3876                    z.gesture.imageWrap.transition(0);
3877                }
3878                // Define if we need image drag
3879                var scaledWidth = z.image.width * z.scale;
3880                var scaledHeight = z.image.height * z.scale;
3881        
3882                if (scaledWidth < z.gesture.slideWidth && scaledHeight < z.gesture.slideHeight) return;
3883        
3884                z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
3885                z.image.maxX = -z.image.minX;
3886                z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
3887                z.image.maxY = -z.image.minY;
3888        
3889                z.image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
3890                z.image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
3891        
3892                if (!z.image.isMoved && !z.isScaling) {
3893                    if (s.isHorizontal() &&
3894                        (Math.floor(z.image.minX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x < z.image.touchesStart.x) ||
3895                        (Math.floor(z.image.maxX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x > z.image.touchesStart.x)
3896                        ) {
3897                        z.image.isTouched = false;
3898                        return;
3899                    }
3900                    else if (!s.isHorizontal() &&
3901                        (Math.floor(z.image.minY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y < z.image.touchesStart.y) ||
3902                        (Math.floor(z.image.maxY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y > z.image.touchesStart.y)
3903                        ) {
3904                        z.image.isTouched = false;
3905                        return;
3906                    }
3907                }
3908                e.preventDefault();
3909                e.stopPropagation();
3910        
3911                z.image.isMoved = true;
3912                z.image.currentX = z.image.touchesCurrent.x - z.image.touchesStart.x + z.image.startX;
3913                z.image.currentY = z.image.touchesCurrent.y - z.image.touchesStart.y + z.image.startY;
3914        
3915                if (z.image.currentX < z.image.minX) {
3916                    z.image.currentX =  z.image.minX + 1 - Math.pow((z.image.minX - z.image.currentX + 1), 0.8);
3917                }
3918                if (z.image.currentX > z.image.maxX) {
3919                    z.image.currentX = z.image.maxX - 1 + Math.pow((z.image.currentX - z.image.maxX + 1), 0.8);
3920                }
3921        
3922                if (z.image.currentY < z.image.minY) {
3923                    z.image.currentY =  z.image.minY + 1 - Math.pow((z.image.minY - z.image.currentY + 1), 0.8);
3924                }
3925                if (z.image.currentY > z.image.maxY) {
3926                    z.image.currentY = z.image.maxY - 1 + Math.pow((z.image.currentY - z.image.maxY + 1), 0.8);
3927                }
3928        
3929                //Velocity
3930                if (!z.velocity.prevPositionX) z.velocity.prevPositionX = z.image.touchesCurrent.x;
3931                if (!z.velocity.prevPositionY) z.velocity.prevPositionY = z.image.touchesCurrent.y;
3932                if (!z.velocity.prevTime) z.velocity.prevTime = Date.now();
3933                z.velocity.x = (z.image.touchesCurrent.x - z.velocity.prevPositionX) / (Date.now() - z.velocity.prevTime) / 2;
3934                z.velocity.y = (z.image.touchesCurrent.y - z.velocity.prevPositionY) / (Date.now() - z.velocity.prevTime) / 2;
3935                if (Math.abs(z.image.touchesCurrent.x - z.velocity.prevPositionX) < 2) z.velocity.x = 0;
3936                if (Math.abs(z.image.touchesCurrent.y - z.velocity.prevPositionY) < 2) z.velocity.y = 0;
3937                z.velocity.prevPositionX = z.image.touchesCurrent.x;
3938                z.velocity.prevPositionY = z.image.touchesCurrent.y;
3939                z.velocity.prevTime = Date.now();
3940        
3941                z.gesture.imageWrap.transform('translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
3942            },
3943            onTouchEnd: function (s, e) {
3944                var z = s.zoom;
3945                if (!z.gesture.image || z.gesture.image.length === 0) return;
3946                if (!z.image.isTouched || !z.image.isMoved) {
3947                    z.image.isTouched = false;
3948                    z.image.isMoved = false;
3949                    return;
3950                }
3951                z.image.isTouched = false;
3952                z.image.isMoved = false;
3953                var momentumDurationX = 300;
3954                var momentumDurationY = 300;
3955                var momentumDistanceX = z.velocity.x * momentumDurationX;
3956                var newPositionX = z.image.currentX + momentumDistanceX;
3957                var momentumDistanceY = z.velocity.y * momentumDurationY;
3958                var newPositionY = z.image.currentY + momentumDistanceY;
3959        
3960                //Fix duration
3961                if (z.velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - z.image.currentX) / z.velocity.x);
3962                if (z.velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - z.image.currentY) / z.velocity.y);
3963                var momentumDuration = Math.max(momentumDurationX, momentumDurationY);
3964        
3965                z.image.currentX = newPositionX;
3966                z.image.currentY = newPositionY;
3967        
3968                // Define if we need image drag
3969                var scaledWidth = z.image.width * z.scale;
3970                var scaledHeight = z.image.height * z.scale;
3971                z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
3972                z.image.maxX = -z.image.minX;
3973                z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
3974                z.image.maxY = -z.image.minY;
3975                z.image.currentX = Math.max(Math.min(z.image.currentX, z.image.maxX), z.image.minX);
3976                z.image.currentY = Math.max(Math.min(z.image.currentY, z.image.maxY), z.image.minY);
3977        
3978                z.gesture.imageWrap.transition(momentumDuration).transform('translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
3979            },
3980            onTransitionEnd: function (s) {
3981                var z = s.zoom;
3982                if (z.gesture.slide && s.previousIndex !== s.activeIndex) {
3983                    z.gesture.image.transform('translate3d(0,0,0) scale(1)');
3984                    z.gesture.imageWrap.transform('translate3d(0,0,0)');
3985                    z.gesture.slide = z.gesture.image = z.gesture.imageWrap = undefined;
3986                    z.scale = z.currentScale = 1;
3987                }
3988            },
3989            // Toggle Zoom
3990            toggleZoom: function (s, e) {
3991                var z = s.zoom;
3992                if (!z.gesture.slide) {
3993                    z.gesture.slide = s.clickedSlide ? $(s.clickedSlide) : s.slides.eq(s.activeIndex);
3994                    z.gesture.image = z.gesture.slide.find('img, svg, canvas');
3995                    z.gesture.imageWrap = z.gesture.image.parent('.' + s.params.zoomContainerClass);
3996                }
3997                if (!z.gesture.image || z.gesture.image.length === 0) return;
3998        
3999                var touchX, touchY, offsetX, offsetY, diffX, diffY, translateX, translateY, imageWidth, imageHeight, scaledWidth, scaledHeight, translateMinX, translateMinY, translateMaxX, translateMaxY, slideWidth, slideHeight;
4000        
4001                if (typeof z.image.touchesStart.x === 'undefined' && e) {
4002                    touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;
4003                    touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;
4004                }
4005                else {
4006                    touchX = z.image.touchesStart.x;
4007                    touchY = z.image.touchesStart.y;
4008                }
4009        
4010                if (z.scale && z.scale !== 1) {
4011                    // Zoom Out
4012                    z.scale = z.currentScale = 1;
4013                    z.gesture.imageWrap.transition(300).transform('translate3d(0,0,0)');
4014                    z.gesture.image.transition(300).transform('translate3d(0,0,0) scale(1)');
4015                    z.gesture.slide = undefined;
4016                }
4017                else {
4018                    // Zoom In
4019                    z.scale = z.currentScale = z.gesture.imageWrap.attr('data-swiper-zoom') || s.params.zoomMax;
4020                    if (e) {
4021                        slideWidth = z.gesture.slide[0].offsetWidth;
4022                        slideHeight = z.gesture.slide[0].offsetHeight;
4023                        offsetX = z.gesture.slide.offset().left;
4024                        offsetY = z.gesture.slide.offset().top;
4025                        diffX = offsetX + slideWidth/2 - touchX;
4026                        diffY = offsetY + slideHeight/2 - touchY;
4027        
4028                        imageWidth = z.gesture.image[0].offsetWidth;
4029                        imageHeight = z.gesture.image[0].offsetHeight;
4030                        scaledWidth = imageWidth * z.scale;
4031                        scaledHeight = imageHeight * z.scale;
4032        
4033                        translateMinX = Math.min((slideWidth / 2 - scaledWidth / 2), 0);
4034                        translateMinY = Math.min((slideHeight / 2 - scaledHeight / 2), 0);
4035                        translateMaxX = -translateMinX;
4036                        translateMaxY = -translateMinY;
4037        
4038                        translateX = diffX * z.scale;
4039                        translateY = diffY * z.scale;
4040        
4041                        if (translateX < translateMinX) {
4042                            translateX =  translateMinX;
4043                        }
4044                        if (translateX > translateMaxX) {
4045                            translateX = translateMaxX;
4046                        }
4047        
4048                        if (translateY < translateMinY) {
4049                            translateY =  translateMinY;
4050                        }
4051                        if (translateY > translateMaxY) {
4052                            translateY = translateMaxY;
4053                        }
4054                    }
4055                    else {
4056                        translateX = 0;
4057                        translateY = 0;
4058                    }
4059                    z.gesture.imageWrap.transition(300).transform('translate3d(' + translateX + 'px, ' + translateY + 'px,0)');
4060                    z.gesture.image.transition(300).transform('translate3d(0,
40600,0) scale(' + z.scale + ')');
4061                }
4062            },
4063            // Attach/Detach Events
4064            attachEvents: function (detach) {
4065                var action = detach ? 'off' : 'on';
4066        
4067                if (s.params.zoom) {
4068                    var target = s.slides;
4069                    var passiveListener = s.touchEvents.start === 'touchstart' && s.support.passiveListener && s.params.passiveListeners ? {passive: true, capture: false} : false;
4070                    // Scale image
4071                    if (s.support.gestures) {
4072                        s.slides[action]('gesturestart', s.zoom.onGestureStart, passiveListener);
4073                        s.slides[action]('gesturechange', s.zoom.onGestureChange, passiveListener);
4074                        s.slides[action]('gestureend', s.zoom.onGestureEnd, passiveListener);
4075                    }
4076                    else if (s.touchEvents.start === 'touchstart') {
4077                        s.slides[action](s.touchEvents.start, s.zoom.onGestureStart, passiveListener);
4078                        s.slides[action](s.touchEvents.move, s.zoom.onGestureChange, passiveListener);
4079                        s.slides[action](s.touchEvents.end, s.zoom.onGestureEnd, passiveListener);
4080                    }
4081        
4082                    // Move image
4083                    s[action]('touchStart', s.zoom.onTouchStart);
4084                    s.slides.each(function (index, slide){
4085                        if ($(slide).find('.' + s.params.zoomContainerClass).length > 0) {
4086                            $(slide)[action](s.touchEvents.move, s.zoom.onTouchMove);
4087                        }
4088                    });
4089                    s[action]('touchEnd', s.zoom.onTouchEnd);
4090        
4091                    // Scale Out
4092                    s[action]('transitionEnd', s.zoom.onTransitionEnd);
4093                    if (s.params.zoomToggle) {
4094                        s.on('doubleTap', s.zoom.toggleZoom);
4095                    }
4096                }
4097            },
4098            init: function () {
4099                s.zoom.attachEvents();
4100            },
4101            destroy: function () {
4102                s.zoom.attachEvents(true);
4103            }
4104        };
4105
4106        /*=========================
4107          Plugins API. Collect all and init all plugins
4108          ===========================*/
4109        s._plugins = [];
4110        for (var plugin in s.plugins) {
4111            var p = s.plugins[plugin](s, s.params[plugin]);
4112            if (p) s._plugins.push(p);
4113        }
4114        // Method to call all plugins event/method
4115        s.callPlugins = function (eventName) {
4116            for (var i = 0; i < s._plugins.length; i++) {
4117                if (eventName in s._plugins[i]) {
4118                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
4119                }
4120            }
4121        };
4122
4123        /*=========================
4124          Events/Callbacks/Plugins Emitter
4125          ===========================*/
4126        function normalizeEventName (eventName) {
4127            if (eventName.indexOf('on') !== 0) {
4128                if (eventName[0] !== eventName[0].toUpperCase()) {
4129                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);
4130                }
4131                else {
4132                    eventName = 'on' + eventName;
4133                }
4134            }
4135            return eventName;
4136        }
4137        s.emitterEventListeners = {
4138        
4139        };
4140        s.emit = function (eventName) {
4141            // Trigger callbacks
4142            if (s.params[eventName]) {
4143                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
4144            }
4145            var i;
4146            // Trigger events
4147            if (s.emitterEventListeners[eventName]) {
4148                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
4149                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
4150                }
4151            }
4152            // Trigger plugins
4153            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
4154        };
4155        s.on = function (eventName, handler) {
4156            eventName = normalizeEventName(eventName);
4157            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];
4158            s.emitterEventListeners[eventName].push(handler);
4159            return s;
4160        };
4161        s.off = function (eventName, handler) {
4162            var i;
4163            eventName = normalizeEventName(eventName);
4164            if (typeof handler === 'undefined') {
4165                // Remove all handlers for such event
4166                s.emitterEventListeners[eventName] = [];
4167                return s;
4168            }
4169            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;
4170            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
4171                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);
4172            }
4173            return s;
4174        };
4175        s.once = function (eventName, handler) {
4176            eventName = normalizeEventName(eventName);
4177            var _handler = function () {
4178                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
4179                s.off(eventName, _handler);
4180            };
4181            s.on(eventName, _handler);
4182            return s;
4183        };
4184
4185        // Accessibility tools
4186        s.a11y = {
4187            makeFocusable: function ($el) {
4188                $el.attr('tabIndex', '0');
4189                return $el;
4190            },
4191            addRole: function ($el, role) {
4192                $el.attr('role', role);
4193                return $el;
4194            },
4195        
4196            addLabel: function ($el, label) {
4197                $el.attr('aria-label', label);
4198                return $el;
4199            },
4200        
4201            disable: function ($el) {
4202                $el.attr('aria-disabled', true);
4203                return $el;
4204            },
4205        
4206            enable: function ($el) {
4207                $el.attr('aria-disabled', false);
4208                return $el;
4209            },
4210        
4211            onEnterKey: function (event) {
4212                if (event.keyCode !== 13) return;
4213                if ($(event.target).is(s.params.nextButton)) {
4214                    s.onClickNext(event);
4215                    if (s.isEnd) {
4216                        s.a11y.notify(s.params.lastSlideMessage);
4217                    }
4218                    else {
4219                        s.a11y.notify(s.params.nextSlideMessage);
4220                    }
4221                }
4222                else if ($(event.target).is(s.params.prevButton)) {
4223                    s.onClickPrev(event);
4224                    if (s.isBeginning) {
4225                        s.a11y.notify(s.params.firstSlideMessage);
4226                    }
4227                    else {
4228                        s.a11y.notify(s.params.prevSlideMessage);
4229                    }
4230                }
4231                if ($(event.target).is('.' + s.params.bulletClass)) {
4232                    $(event.target)[0].click();
4233                }
4234            },
4235        
4236            liveRegion: $('<span class="' + s.params.notificationClass + '" aria-live="assertive" aria-atomic="true"></span>'),
4237        
4238            notify: function (message) {
4239                var notification = s.a11y.liveRegion;
4240                if (notification.length === 0) return;
4241                notification.html('');
4242                notification.html(message);
4243            },
4244            init: function () {
4245                // Setup accessibility
4246                if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
4247                    s.a11y.makeFocusable(s.nextButton);
4248                    s.a11y.addRole(s.nextButton, 'button');
4249                    s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);
4250                }
4251                if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
4252                    s.a11y.makeFocusable(s.prevButton);
4253                    s.a11y.addRole(s.prevButton, 'button');
4254                    s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);
4255                }
4256        
4257                $(s.container).append(s.a11y.liveRegion);
4258            },
4259            initPagination: function () {
4260                if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {
4261                    s.bullets.each(function () {
4262                        var bullet = $(this);
4263                        s.a11y.makeFocusable(bullet);
4264                        s.a11y.addRole(bullet, 'button');
4265                        s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));
4266                    });
4267                }
4268            },
4269            destroy: function () {
4270                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();
4271            }
4272        };
4273        
4274
4275        /*=========================
4276          Init/Destroy
4277          ===========================*/
4278        s.init = function () {
4279            if (s.params.loop) s.createLoop();
4280            s.updateContainerSize();
4281            s.updateSlidesSize();
4282            s.updatePagination();
4283            if (s.params.scrollbar && s.scrollbar) {
4284                s.scrollbar.set();
4285                if (s.params.scrollbarDraggable) {
4286                    s.scrollbar.enableDraggable();
4287                }
4288            }
4289            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
4290                if (!s.params.loop) s.updateProgress();
4291                s.effects[s.params.effect].setTranslate();
4292            }
4293            if (s.params.loop) {
4294                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);
4295            }
4296            else {
4297                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);
4298                if (s.params.initialSlide === 0) {
4299                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();
4300                    if (s.lazy && s.params.lazyLoading) {
4301                        s.lazy.load();
4302                        s.lazy.initialImageLoaded = true;
4303                    }
4304                }
4305            }
4306            s.attachEvents();
4307            if (s.params.observer && s.support.observer) {
4308                s.initObservers();
4309            }
4310            if (s.params.preloadImages && !s.params.lazyLoading) {
4311                s.preloadImages();
4312            }
4313            if (s.params.zoom && s.zoom) {
4314                s.zoom.init();
4315            }
4316            if (s.params.autoplay) {
4317                s.startAutoplay();
4318            }
4319            if (s.params.keyboardControl) {
4320                if (s.enableKeyboardControl) s.enableKeyboardControl();
4321            }
4322            if (s.params.mousewheelControl) {
4323                if (s.enableMousewheelControl) s.enableMousewheelControl();
4324            }
4325            // Deprecated hashnavReplaceState changed to replaceState for use in hashnav and history
4326            if (s.params.hashnavReplaceState) {
4327                s.params.replaceState = s.params.hashnavReplaceState;
4328            }
4329            if (s.params.history) {
4330                if (s.history) s.history.init();
4331            }
4332            if (s.params.hashnav) {
4333                if (s.hashnav) s.hashnav.init();
4334            }
4335            if (s.params.a11y && s.a11y) s.a11y.init();
4336            s.emit('onInit', s);
4337        };
4338        
4339        // Cleanup dynamic styles
4340        s.cleanupStyles = function () {
4341            // Container
4342            s.container.removeClass(s.classNames.join(' ')).removeAttr('style');
4343        
4344            // Wrapper
4345            s.wrapper.removeAttr('style');
4346        
4347            // Slides
4348            if (s.slides && s.slides.length) {
4349                s.slides
4350                    .removeClass([
4351                      s.params.slideVisibleClass,
4352                      s.params.slideActiveClass,
4353                      s.params.slideNextClass,
4354                      s.params.slidePrevClass
4355                    ].join(' '))
4356                    .removeAttr('style')
4357                    .removeAttr('data-swiper-column')
4358                    .removeAttr('data-swiper-row');
4359            }
4360        
4361            // Pagination/Bullets
4362            if (s.paginationContainer && s.paginationContainer.length) {
4363                s.paginationContainer.removeClass(s.params.paginationHiddenClass);
4364            }
4365            if (s.bullets && s.bullets.length) {
4366                s.bullets.removeClass(s.params.bulletActiveClass);
4367            }
4368        
4369            // Buttons
4370            if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
4371            if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
4372        
4373            // Scrollbar
4374            if (s.params.scrollbar && s.scrollbar) {
4375                if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');
4376                if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');
4377            }
4378        };
4379        
4380        // Destroy
4381        s.destroy = function (deleteInstance, cleanupStyles) {
4382            // Detach evebts
4383            s.detachEvents();
4384            // Stop autoplay
4385            s.stopAutoplay();
4386            // Disable draggable
4387            if (s.params.scrollbar && s.scrollbar) {
4388                if (s.params.scrollbarDraggable) {
4389                    s.scrollbar.disableDraggable();
4390                }
4391            }
4392            // Destroy loop
4393            if (s.params.loop) {
4394                s.destroyLoop();
4395            }
4396            // Cleanup styles
4397            if (cleanupStyles) {
4398                s.cleanupStyles();
4399            }
4400            // Disconnect observer
4401            s.disconnectObservers();
4402        
4403            // Destroy zoom
4404            if (s.params.zoom && s.zoom) {
4405                s.zoom.destroy();
4406            }
4407            // Disable keyboard/mousewheel
4408            if (s.params.keyboardControl) {
4409                if (s.disableKeyboardControl) s.disableKeyboardControl();
4410            }
4411            if (s.params.mousewheelControl) {
4412                if (s.disableMousewheelControl) s.disableMousewheelControl();
4413            }
4414            // Disable a11y
4415            if (s.params.a11y && s.a11y) s.a11y.destroy();
4416            // Delete history popstate
4417            if (s.params.history && !s.params.replaceState) {
4418                window.removeEventListener('popstate', s.history.setHistoryPopState);
4419            }
4420            if (s.params.hashnav && s.hashnav)  {
4421                s.hashnav.destroy();
4422            }
4423            // Destroy callback
4424            s.emit('onDestroy');
4425            // Delete instance
4426            if (deleteInstance !== false) s = null;
4427        };
4428        
4429        s.init();
4430        
4431
4432    
4433        // Return swiper instance
4434        return s;
4435    };
4436    
4437
4438    /*==================================================
4439        Prototype
4440    ====================================================*/
4441    Swiper.prototype = {
4442        isSafari: (function () {
4443            var ua = navigator.userAgent.toLowerCase();
4444            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);
4445        })(),
4446        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),
4447        isArray: function (arr) {
4448            return Object.prototype.toString.apply(arr) === '[object Array]';
4449        },
4450        /*==================================================
4451        Browser
4452        ====================================================*/
4453        browser: {
4454            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
4455            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1),
4456            lteIE9: (function() {
4457                // create temporary DIV
4458                var div = document.createElement('div');
4459                // add content to tmp DIV which is wrapped into the IE HTML conditional statement
4460                div.innerHTML = '<!--[if lte IE 9]><i></i><![endif]-->';
4461                // return true / false value based on what will browser render
4462                return div.getElementsByTagName('i').length === 1;
4463            })()
4464        },
4465        /*==================================================
4466        Devices
4467        ====================================================*/
4468        device: (function () {
4469            var ua = navigator.userAgent;
4470            var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
4471            var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
4472            var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
4473            var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
4474            return {
4475                ios: ipad || iphone || ipod,
4476                android: android
4477            };
4478        })(),
4479        /*==================================================
4480        Feature Detection
4481        ====================================================*/
4482        support: {
4483            touch : (window.Modernizr && Modernizr.touch === true) || (function () {
4484                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
4485            })(),
4486    
4487            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
4488                var div = document.createElement('div').style;
4489                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
4490            })(),
4491    
4492            flexbox: (function () {
4493                var div = document.createElement('div').style;
4494                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
4495                for (var i = 0; i < styles.length; i++) {
4496                    if (styles[i] in div) return true;
4497                }
4498            })(),
4499    
4500            observer: (function () {
4501                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);
4502            })(),
4503    
4504            passiveListener: (function () {
4505                var supportsPassive = false;
4506                try {
4507                    var opts = Object.defineProperty({}, 'passive', {
4508                        get: function() {
4509                            supportsPassive = true;
4510                        }
4511                    });
4512                    window.addEventListener('testPassiveListener', null, opts);
4513                } catch (e) {}
4514                return supportsPassive;
4515            })(),
4516    
4517            gestures: (function () {
4518                return 'ongesturestart' in window;
4519            })()
4520        },
4521        /*==================================================
4522        Plugins
4523        ====================================================*/
4524        plugins: {}
4525    };
4526    
4527
4528    /*===========================
4529    Dom7 Library
4530    ===========================*/
4531    var Dom7 = (function () {
4532        var Dom7 = function (arr) {
4533            var _this = this, i = 0;
4534            // Create array-like object
4535            for (i = 0; i < arr.length; i++) {
4536                _this[i] = arr[i];
4537            }
4538            _this.length = arr.length;
4539            // Return collection with methods
4540            return this;
4541        };
4542        var $ = function (selector, context) {
4543            var arr = [], i = 0;
4544            if (selector && !context) {
4545                if (selector instanceof Dom7) {
4546                    return selector;
4547                }
4548            }
4549            if (selector) {
4550                // String
4551                if (typeof selector === 'string') {
4552                    var els, tempParent, html = selector.trim();
4553                    if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
4554                        var toCreate = 'div';
4555                        if (html.indexOf('<li') === 0) toCreate = 'ul';
4556                        if (html.indexOf('<tr') === 0) toCreate = 'tbody';
4557                        if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';
4558                        if (html.indexOf('<tbody') === 0) toCreate = 'table';
4559                        if (html.indexOf('<option') === 0) toCreate = 'select';
4560                        tempParent = document.createElement(toCreate);
4561                        tempParent.innerHTML = selector;
4562                        for (i = 0; i < tempParent.childNodes.length; i++) {
4563                            arr.push(tempParent.childNodes[i]);
4564                        }
4565                    }
4566                    else {
4567                        if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {
4568                            // Pure ID selector
4569                            els = [document.getElementById(selector.split('#')[1])];
4570                        }
4571                        else {
4572                            // Other selectors
4573                            els = (context || document).querySelectorAll(selector);
4574                        }
4575                        for (i = 0; i < els.length; i++) {
4576                            if (els[i]) arr.push(els[i]);
4577                        }
4578                    }
4579                }
4580                // Node/element
4581                else if (selector.nodeType || selector === window || selector === document) {
4582                    arr.push(selector);
4583                }
4584                //Array of elements or instance of Dom
4585                else if (selector.length > 0 && selector[0].nodeType) {
4586                    for (i = 0; i < selector.length; i++) {
4587                        arr.push(selector[i]);
4588                    }
4589                }
4590            }
4591            return new Dom7(arr);
4592        };
4593        Dom7.prototype = {
4594            // Classes and attriutes
4595            addClass: function (className) {
4596                if (typeof className === 'undefined') {
4597                    return this;
4598                }
4599                var classes = className.split(' ');
4600                for (var i = 0; i < classes.length; i++) {
4601                    for (var j = 0; j < this.length; j++) {
4602                        this[j].classList.add(classes[i]);
4603                    }
4604                }
4605                return this;
4606            },
4607            removeClass: function (className) {
4608                var classes = className.split(' ');
4609                for (var i = 0; i < classes.length; i++) {
4610                    for (var j = 0; j < this.length; j++) {
4611                        this[j].classList.remove(classes[i]);
4612                    }
4613                }
4614                return this;
4615            },
4616            hasClass: function (className) {
4617                if (!this[0]) return false;
4618                else return this[0].classList.contains(className);
4619            },
4620            toggleClass: function (className) {
4621                var classes = className.split(' ');
4622                for (var i = 0; i < classes.length; i++) {
4623                    for (var j = 0; j < this.length; j++) {
4624                        this[j].classList.toggle(classes[i]);
4625                    }
4626                }
4627                return this;
4628            },
4629            attr: function (attrs, value) {
4630                if (arguments.length === 1 && typeof attrs === 'string') {
4631                    // Get attr
4632                    if (this[0]) return this[0].getAttribute(attrs);
4633                    else return undefined;
4634                }
4635                else {
4636                    // Set attrs
4637                    for (var i = 0; i < this.length; i++) {
4638                        if (arguments.length === 2) {
4639                            // String
4640                            this[i].setAttribute(attrs, value);
4641                        }
4642                        else {
4643                            // Object
4644                            for (var attrName in attrs) {
4645                                this[i][attrName] = attrs[attrName];
4646                                this[i].setAttribute(attrName, attrs[attrName]);
4647                            }
4648                        }
4649                    }
4650                    return this;
4651                }
4652            },
4653            removeAttr: function (attr) {
4654                for (var i = 0; i < this.length; i++) {
4655                    this[i].removeAttribute(attr);
4656                }
4657                return this;
4658            },
4659            data: function (key, value) {
4660                if (typeof value === 'undefined') {
4661                    // Get value
4662                    if (this[0]) {
4663                        var dataKey = this[0].getAttribute('data-' + key);
4664                        if (dataKey) return dataKey;
4665                        else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];
4666                        else return undefined;
4667                    }
4668                    else return undefined;
4669                }
4670                else {
4671                    // Set value
4672                    for (var i = 0; i < this.length; i++) {
4673                        var el = this[i];
4674                        if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};
4675                        el.dom7ElementDataStorage[key] = value;
4676                    }
4677                    return this;
4678                }
4679            },
4680            // Transforms
4681            transform : function (transform) {
4682                for (var i = 0; i < this.length; i++) {
4683                    var elStyle = this[i].style;
4684                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;
4685                }
4686                return this;
4687            },
4688            transition: function (duration) {
4689                if (typeof duration !== 'string') {
4690                    duration = duration + 'ms';
4691                }
4692                for (var i = 0; i < this.length; i++) {
4693                    var elStyle = this[i].style;
4694                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;
4695                }
4696                return this;
4697            },
4698            //Events
4699            on: function (eventName, targetSelector, listener, capture) {
4700                function handleLiveEvent(e) {
4701                    var target = e.target;
4702                    if ($(target).is(targetSelector)) listener.call(target, e);
4703                    else {
4704                        var parents = $(target).parents();
4705                        for (var k = 0; k < parents.length; k++) {
4706                            if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);
4707                        }
4708                    }
4709                }
4710                var events = eventName.split(' ');
4711                var i, j;
4712                for (i = 0; i < this.length; i++) {
4713                    if (typeof targetSelector === 'function' || targetSelector === false) {
4714                        // Usual events
4715                        if (typeof targetSelector === 'function') {
4716                            listener = arguments[1];
4717                            capture = arguments[2] || false;
4718                        }
4719                        for (j = 0; j < events.length; j++) {
4720                            this[i].addEventListener(events[j], listener, capture);
4721                        }
4722                    }
4723                    else {
4724                        //Live events
4725                        for (j = 0; j < events.length; j++) {
4726                            if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];
4727                            this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});
4728                            this[i].addEventListener(events[j], handleLiveEvent, capture);
4729                        }
4730                    }
4731                }
4732    
4733                return this;
4734            },
4735            off: function (eventName, targetSelector, listener, capture) {
4736                var events = eventName.split(' ');
4737                for (var i = 0; i < events.length; i++) {
4738                    for (var j = 0; j < this.length; j++) {
4739                        if (typeof targetSelector === 'function' || targetSelector === false) {
4740                            // Usual events
4741                            if (typeof targetSelector === 'function') {
4742                                listener = arguments[1];
4743                                capture = arguments[2] || false;
4744                            }
4745                            this[j].removeEventListener(events[i], listener, capture);
4746                        }
4747                        else {
4748                            // Live event
4749                            if (this[j].dom7LiveListeners) {
4750                                for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {
4751                                    if (this[j].dom7LiveListeners[k].listener === listener) {
4752                                        this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);
4753                                    }
4754                                }
4755                            }
4756                        }
4757                    }
4758                }
4759                return this;
4760            },
4761            once: function (eventName, targetSelector, listener, capture) {
4762                var dom = this;
4763                if (typeof targetSelector === 'function') {
4764                    targetSelector = false;
4765                    listener = arguments[1];
4766                    capture = arguments[2];
4767                }
4768                function proxy(e) {
4769                    listener(e);
4770                    dom.off(eventName, targetSelector, proxy, capture);
4771                }
4772                dom.on(eventName, targetSelector, proxy, capture);
4773            },
4774            trigger: function (eventName, eventData) {
4775                for (var i = 0; i < this.length; i++) {
4776                    var evt;
4777                    try {
4778                        evt = new window.CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});
4779                    }
4780                    catch (e) {
4781                        evt = document.createEvent('Event');
4782                        evt.initEvent(eventName, true, true);
4783                        evt.detail = eventData;
4784                    }
4785                    this[i].dispatchEvent(evt);
4786                }
4787                return this;
4788            },
4789            transitionEnd: function (callback) {
4790                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
4791                    i, j, dom = this;
4792                function fireCallBack(e) {
4793                    /*jshint validthis:true */
4794                    if (e.target !== this) return;
4795                    callback.call(this, e);
4796                    for (i = 0; i < events.length; i++) {
4797                        dom.off(events[i], fireCallBack);
4798                    }
4799                }
4800                if (callback) {
4801                    for (i = 0; i < events.length; i++) {
4802                        dom.on(events[i], fireCallBack);
4803                    }
4804                }
4805                return this;
4806            },
4807            // Sizing/Styles
4808            width: function () {
4809                if (this[0] === window) {
4810                    return window.innerWidth;
4811                }
4812                else {
4813                    if (this.length > 0) {
4814                        return parseFloat(this.css('width'));
4815                    }
4816                    else {
4817                        return null;
4818                    }
4819                }
4820            },
4821            outerWidth: function (includeMargins) {
4822                if (this.length > 0) {
4823                    if (includeMargins)
4824                        return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));
4825                    else
4826                        return this[0].offsetWidth;
4827                }
4828                else return null;
4829            },
4830            height: function () {
4831                if (this[0] === window) {
4832                    return window.innerHeight;
4833                }
4834                else {
4835                    if (this.length > 0) {
4836                        return parseFloat(this.css('height'));
4837                    }
4838                    else {
4839                        return null;
4840                    }
4841                }
4842            },
4843            outerHeight: function (includeMargins) {
4844                if (this.length > 0) {
4845                    if (includeMargins)
4846                        return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));
4847                    else
4848                        return this[0].offsetHeight;
4849                }
4850                else return null;
4851            },
4852            offset: function () {
4853                if (this.length > 0) {
4854                    var el = this[0];
4855                    var box = el.getBoundingClientRect();
4856                    var body = document.body;
4857                    var clientTop  = el.clientTop  || body.clientTop  || 0;
4858                    var clientLeft = el.clientLeft || body.clientLeft || 0;
4859                    var scrollTop  = window.pageYOffset || el.scrollTop;
4860                    var scrollLeft = window.pageXOffset || el.scrollLeft;
4861                    return {
4862                        top: box.top  + scrollTop  - clientTop,
4863                        left: box.left + scrollLeft - clientLeft
4864                    };
4865                }
4866                else {
4867                    return null;
4868                }
4869            },
4870            css: function (props, value) {
4871                var i;
4872                if (arguments.length === 1) {
4873                    if (typeof props === 'string') {
4874                        if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);
4875                    }
4876                    else {
4877                        for (i = 0; i < this.length; i++) {
4878                            for (var prop in props) {
4879                                this[i].style[prop] = props[prop];
4880                            }
4881                        }
4882                        return this;
4883                    }
4884                }
4885                if (arguments.length === 2 && typeof props === 'string') {
4886                    for (i = 0; i < this.length; i++) {
4887                        this[i].style[props] = value;
4888                    }
4889                    return this;
4890                }
4891                return this;
4892            },
4893    
4894            //Dom manipulation
4895            each: function (callback) {
4896                for (var i = 0; i < this.length; i++) {
4897                    callback.call(this[i], i, this[i]);
4898                }
4899                return this;
4900            },
4901            html: function (html) {
4902                if (typeof html === 'undefined') {
4903                    return this[0] ? this[0].innerHTML : undefined;
4904                }
4905                else {
4906                    for (var i = 0; i < this.length; i++) {
4907                        this[i].innerHTML = html;
4908                    }
4909                    return this;
4910                }
4911            },
4912            text: function (text) {
4913                if (typeof text === 'undefined') {
4914                    if (this[0]) {
4915                        return this[0].textContent.trim();
4916                    }
4917                    else return null;
4918                }
4919                else {
4920                    for (var i = 0; i < this.length; i++) {
4921                        this[i].textContent = text;
4922                    }
4923                    return this;
4924                }
4925            },
4926            is: function (selector) {
4927                if (!this[0]) return false;
4928                var compareWith, i;
4929                if (typeof selector === 'string') {
4930                    var el = this[0];
4931                    if (el === document) return selector === document;
4932                    if (el === window) return selector === window;
4933    
4934                    if (el.matches) return el.matches(selector);
4935                    else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);
4936                    else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);
4937                    else if (el.msMatchesSelector) return el.msMatchesSelector(selector);
4938                    else {
4939                        compareWith = $(selector);
4940                        for (i = 0; i < compareWith.length; i++) {
4941                            if (compareWith[i] === this[0]) return true;
4942                        }
4943                        return false;
4944                    }
4945                }
4946                else if (selector === document) return this[0] === document;
4947                else if (selector === window) return this[0] === window;
4948                else {
4949                    if (selector.nodeType || selector instanceof Dom7) {
4950                        compareWith = selector.nodeType ? [selector] : selector;
4951                        for (i = 0; i < compareWith.length; i++) {
4952                            if (compareWith[i] === this[0]) return true;
4953                        }
4954                        return false;
4955                    }
4956                    return false;
4957                }
4958    
4959            },
4960            index: function () {
4961                if (this[0]) {
4962                    var child = this[0];
4963                    var i = 0;
4964                    while ((child = child.previousSibling) !== null) {
4965                        if (child.nodeType === 1) i++;
4966                    }
4967                    return i;
4968                }
4969                else return undefined;
4970            },
4971            eq: function (index) {
4972                if (typeof index === 'undefined') return this;
4973                var length = this.length;
4974                var returnIndex;
4975                if (index > length - 1) {
4976                    return new Dom7([]);
4977                }
4978                if (index < 0) {
4979                    returnIndex = length + index;
4980                    if (returnIndex < 0) return new Dom7([]);
4981                    else return new Dom7([this[returnIndex]]);
4982                }
4983                return new Dom7([this[index]]);
4984            },
4985            append: function (newChild) {
4986                var i, j;
4987                for (i = 0; i < this.length; i++) {
4988                    if (typeof newChild === 'string') {
4989                        var tempDiv = document.createElement('div');
4990                        tempDiv.innerHTML = newChild;
4991                        while (tempDiv.firstChild) {
4992                            this[i].appendChild(tempDiv.firstChild);
4993                        }
4994                    }
4995                    else if (newChild instanceof Dom7) {
4996                        for (j = 0; j < newChild.length; j++) {
4997                            this[i].appendChild(newChild[j]);
4998                        }
4999                    }
5000                    else {
5001                        this[i].appendChild(newChild);
5002                    }
5003                }
5004                return this;
5005            },
5006            prepend: function (newChild) {
5007                var i, j;
5008                for (i = 0; i < this.length; i++) {
5009                    if (typeof newChild === 'string') {
5010                        var tempDiv = document.createElement('div');
5011                        tempDiv.innerHTML = newChild;
5012                        for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {
5013                            this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
5014                        }
5015                        // this[i].insertAdjacentHTML('afterbegin', newChild);
5016                    }
5017                    else if (newChild instanceof Dom7) {
5018                        for (j = 0; j < newChild.length; j++) {
5019                            this[i].insertBefore(newChild[j], this[i].childNodes[0]);
5020                        }
5021                    }
5022                    else {
5023                        this[i].insertBefore(newChild, this[i].childNodes[0]);
5024                    }
5025                }
5026                return this;
5027            },
5028            insertBefore: function (selector) {
5029                var before = $(selector);
5030                for (var i = 0; i < this.length; i++) {
5031                    if (before.length === 1) {
5032                        before[0].parentNode.insertBefore(this[i], before[0]);
5033                    }
5034                    else if (before.length > 1) {
5035                        for (var j = 0; j < before.length; j++) {
5036                            before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
5037                        }
5038                    }
5039                }
5040            },
5041            insertAfter: function (selector) {
5042                var after = $(selector);
5043                for (var i = 0; i < this.length; i++) {
5044                    if (after.length === 1) {
5045                        after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
5046                    }
5047                    else if (after.length > 1) {
5048                        for (var j = 0; j < after.length; j++) {
5049                            after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
5050                        }
5051                    }
5052                }
5053            },
5054            next: function (selector) {
5055                if (this.length > 0) {
5056                    if (selector) {
5057                        if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);
5058                        else return new Dom7([]);
5059                    }
5060                    else {
5061                        if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);
5062                        else return new Dom7([]);
5063                    }
5064                }
5065                else return new Dom7([]);
5066            },
5067            nextAll: function (selector) {
5068                var nextEls = [];
5069                var el = this[0];
5070                if (!el) return new Dom7([]);
5071                while (el.nextElementSibling) {
5072                    var next = el.nextElementSibling;
5073                    if (selector) {
5074                        if($(next).is(selector)) nextEls.push(next);
5075                    }
5076                    else nextEls.push(next);
5077                    el = next;
5078                }
5079                return new Dom7(nextEls);
5080            },
5081            prev: function (selector) {
5082                if (this.length > 0) {
5083                    if (selector) {
5084                        if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);
5085                        else return new Dom7([]);
5086                    }
5087                    else {
5088                        if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);
5089                        else return new Dom7([]);
5090                    }
5091                }
5092                else return new Dom7([]);
5093            },
5094            prevAll: function (selector) {
5095                var prevEls = [];
5096                var el = this[0];
5097                if (!el) return new Dom7([]);
5098                while (el.previousElementSibling) {
5099                    var prev = el.previousElementSibling;
5100                    if (selector) {
5101                        if($(prev).is(selector)) prevEls.push(prev);
5102                    }
5103                    else prevEls.push(prev);
5104                    el = prev;
5105                }
5106                return new Dom7(prevEls);
5107            },
5108            parent: function (selector) {
5109                var parents = [];
5110                for (var i = 0; i < this.length; i++) {
5111                    if (selector) {
5112                        if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);
5113                    }
5114                    else {
5115                        parents.push(this[i].parentNode);
5116                    }
5117                }
5118                return $($.unique(parents));
5119            },
5120            parents: function (selector) {
5121                var parents = [];
5122                for (var i = 0; i < this.length; i++) {
5123                    var parent = this[i].parentNode;
5124                    while (parent) {
5125                        if (selector) {
5126                            if ($(parent).is(selector)) parents.push(parent);
5127                        }
5128                        else {
5129                            parents.push(parent);
5130                        }
5131                        parent = parent.parentNode;
5132                    }
5133                }
5134                return $($.unique(parents));
5135            },
5136            find : function (selector) {
5137                var foundElements = [];
5138                for (var i = 0; i < this.length; i++) {
5139                    var found = this[i].querySelectorAll(selector);
5140                    for (var j = 0; j < found.length; j++) {
5141                        foundElements.push(found[j]);
5142                    }
5143                }
5144                return new Dom7(foundElements);
5145            },
5146            children: function (selector) {
5147                var children = [];
5148                for (var i = 0; i < this.length; i++) {
5149                    var childNodes = this[i].childNodes;
5150    
5151                    for (var j = 0; j < childNodes.length; j++) {
5152                        if (!selector) {
5153                            if (childNodes[j].nodeType === 1) children.push(childNodes[j]);
5154                        }
5155                        else {
5156                            if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);
5157                        }
5158                    }
5159                }
5160                return new Dom7($.unique(children));
5161            },
5162            remove: function () {
5163                for (var i = 0; i < this.length; i++) {
5164                    if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);
5165                }
5166                return this;
5167            },
5168            add: function () {
5169                var dom = this;
5170                var i, j;
5171                for (i = 0; i < arguments.length; i++) {
5172                    var toAdd = $(arguments[i]);
5173                    for (j = 0; j < toAdd.length; j++) {
5174                        dom[dom.length] = toAdd[j];
5175                        dom.length++;
5176                    }
5177                }
5178                return dom;
5179            }
5180        };
5181        $.fn = Dom7.prototype;
5182        $.unique = function (arr) {
5183            var unique = [];
5184            for (var i = 0; i < arr.length; i++) {
5185                if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);
5186            }
5187            return unique;
5188        };
5189    
5190        return $;
5191    })();
5192    
5193
5194    /*===========================
5195     Get Dom libraries
5196     ===========================*/
5197    var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];
5198    for (var i = 0; i < swiperDomPlugins.length; i++) {
5199    	if (window[swiperDomPlugins[i]]) {
5200    		addLibraryPlugin(window[swiperDomPlugins[i]]);
5201    	}
5202    }
5203    // Required DOM Plugins
5204    var domLib;
5205    if (typeof Dom7 === 'undefined') {
5206    	domLib = window.Dom7 || window.Zepto || window.jQuery;
5207    }
5208    else {
5209    	domLib = Dom7;
5210    }
5211
5212    /*===========================
5213    Add .swiper plugin from Dom libraries
5214    ===========================*/
5215    function addLibraryPlugin(lib) {
5216        lib.fn.swiper = function (params) {
5217            var firstInstance;
5218            lib(this).each(function () {
5219                var s = new Swiper(this, params);
5220                if (!firstInstance) firstInstance = s;
5221            });
5222            return firstInstance;
5223        };
5224    }
5225    
5226    if (domLib) {
5227        if (!('transitionEnd' in domLib.fn)) {
5228            domLib.fn.transitionEnd = function (callback) {
5229                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
5230                    i, j, dom = this;
5231                function fireCallBack(e) {
5232                    /*jshint validthis:true */
5233                    if (e.target !== this) return;
5234                    callback.call(this, e);
5235                    for (i = 0; i < events.length; i++) {
5236                        dom.off(events[i], fireCallBack);
5237                    }
5238                }
5239                if (callback) {
5240                    for (i = 0; i < events.length; i++) {
5241                        dom.on(events[i], fireCallBack);
5242                    }
5243                }
5244                return this;
5245            };
5246        }
5247        if (!('transform' in domLib.fn)) {
5248            domLib.fn.transform = function (transform) {
5249                for (var i = 0; i < this.length; i++) {
5250                    var elStyle = this[i].style;
5251                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;
5252                }
5253                return this;
5254            };
5255        }
5256        if (!('transition' in domLib.fn)) {
5257            domLib.fn.transition = function (duration) {
5258                if (typeof duration !== 'string') {
5259                    duration = duration + 'ms';
5260                }
5261                for (var i = 0; i < this.length; i++) {
5262                    var elStyle = this[i].style;
5263                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;
5264                }
5265                return this;
5266            };
5267        }
5268        if (!('outerWidth' in domLib.fn)) {
5269            domLib.fn.outerWidth = function (includeMargins) {
5270                if (this.length > 0) {
5271                    if (includeMargins)
5272                        return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));
5273                    else
5274                        return this[0].offsetWidth;
5275                }
5276                else return null;
5277            };
5278        }
5279    }
5280
5281    window.Swiper = Swiper;
5282})();
5283/*===========================
5284Swiper AMD Export
5285===========================*/
5286if (typeof(module) !== 'undefined')
5287{
5288    module.exports = window.Swiper;
5289}
5290else if (typeof define === 'function' && define.amd) {
5291    define([], function () {
5292        'use strict';
5293        return window.Swiper;
5294    });
5295}
5296//# sourceMappingURL=maps/swiper.js.map

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.