PageSourceSearch

http://kosin.org/phpApplications/contentTouchSlider/js/swiper.js

js kosin.org collected 2026-09-24 23:48:29 UTC 152,856 bytes, 3,610 lines download raw bytes

1/**
2 * Swiper 3.0.5
3 * Most modern mobile touch slider and framework with hardware accelerated transitions
4 * 
5 * http://www.idangero.us/swiper/
6 * 
7 * Copyright 2015, Vladimir Kharlampidi
8 * The iDangero.us
9 * http://www.idangero.us/
10 * 
11 * Licensed under MIT
12 * 
13 * Released on: March 22, 2015
14 */
15(function () {
16    'use strict';
17    /*===========================
18    Swiper
19    ===========================*/
20    window.Swiper = function (container, params) {
21        if (!(this instanceof Swiper)) return new Swiper(container, params);
22
23        var defaults = {
24            direction: 'horizontal',
25            touchEventsTarget: 'container',
26            initialSlide: 0,
27            speed: 300,
28            // autoplay
29            autoplay: false,
30            autoplayDisableOnInteraction: true,
31            // Free mode
32            freeMode: false,
33            freeModeMomentum: true,
34            freeModeMomentumRatio: 1,
35            freeModeMomentumBounce: true,
36            freeModeMomentumBounceRatio: 1,
37            // Set wrapper width
38            setWrapperSize: false,
39            // Virtual Translate
40            virtualTranslate: false,
41            // Effects
42            effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow'
43            coverflow: {
44                rotate: 50,
45                stretch: 0,
46                depth: 100,
47                modifier: 1,
48                slideShadows : true
49            },
50            cube: {
51                slideShadows: true,
52                shadow: true,
53                shadowOffset: 20,
54                shadowScale: 0.94
55            },
56            fade: {
57                crossFade: false
58            },
59            // Parallax
60            parallax: false,
61            // Scrollbar
62            scrollbar: null,
63            scrollbarHide: true,
64            // Keyboard Mousewheel
65            keyboardControl: false,
66            mousewheelControl: false,
67            mousewheelForceToAxis: false,
68            // Hash Navigation
69            hashnav: false,
70            // Slides grid
71            spaceBetween: 0,
72            slidesPerView: 1,
73            slidesPerColumn: 1,
74            slidesPerColumnFill: 'column',
75            slidesPerGroup: 1,
76            centeredSlides: false,
77            // Touches
78            touchRatio: 1,
79            touchAngle: 45,
80            simulateTouch: true,
81            shortSwipes: true,
82            longSwipes: true,
83            longSwipesRatio: 0.5,
84            longSwipesMs: 300,
85            followFinger: true,
86            onlyExternal: false,
87            threshold: 0,
88            touchMoveStopPropagation: true,
89            // Pagination
90            pagination: null,
91            paginationClickable: false,
92            paginationHide: false,
93            paginationBulletRender: null,
94            // Resistance
95            resistance: true,
96            resistanceRatio: 0.85,
97            // Next/prev buttons
98            nextButton: null,
99            prevButton: null,
100            // Progress
101            watchSlidesProgress: false,
102            watchSlidesVisibility: false,
103            // Cursor
104            grabCursor: false,
105            // Clicks
106            preventClicks: true,
107            preventClicksPropagation: true,
108            slideToClickedSlide: false,
109            // Lazy Loading
110            lazyLoading: false,
111            lazyLoadingInPrevNext: false,
112            lazyLoadingOnTransitionStart: false,
113            // Images
114            preloadImages: true,
115            updateOnImagesReady: true,
116            // loop
117            loop: false,
118            loopAdditionalSlides: 0,
119            loopedSlides: null,
120            // Control
121            control: undefined,
122            controlInverse: false,
123            // Swiping/no swiping
124            allowSwipeToPrev: true,
125            allowSwipeToNext: true,
126            swipeHandler: null, //'.swipe-handler',
127            noSwiping: true,
128            noSwipingClass: 'swiper-no-swiping',
129            // NS
130            slideClass: 'swiper-slide',
131            slideActiveClass: 'swiper-slide-active',
132            slideVisibleClass: 'swiper-slide-visible',
133            slideDuplicateClass: 'swiper-slide-duplicate',
134            slideNextClass: 'swiper-slide-next',
135            slidePrevClass: 'swiper-slide-prev',
136            wrapperClass: 'swiper-wrapper',
137            bulletClass: 'swiper-pagination-bullet',
138            bulletActiveClass: 'swiper-pagination-bullet-active',
139            buttonDisabledClass: 'swiper-button-disabled',
140            paginationHiddenClass: 'swiper-pagination-hidden',
141            // Observer
142            observer: false,
143            observeParents: false,
144            // Accessibility
145            a11y: false,
146            prevSlideMessage: 'Previous slide',
147            nextSlideMessage: 'Next slide',
148            firstSlideMessage: 'This is the first slide',
149            lastSlideMessage: 'This is the last slide',
150            // Callbacks
151            runCallbacksOnInit: true,
152            /*
153            Callbacks:
154            onInit: function (swiper)
155            onDestroy: function (swiper)
156            onClick: function (swiper, e)
157            onTap: function (swiper, e)
158            onDoubleTap: function (swiper, e)
159            onSliderMove: function (swiper, e)
160            onSlideChangeStart: function (swiper)
161            onSlideChangeEnd: function (swiper)
162            onTransitionStart: function (swiper)
163            onTransitionEnd: function (swiper)
164            onImagesReady: function (swiper)
165            onProgress: function (swiper, progress)
166            onTouchStart: function (swiper, e)
167            onTouchMove: function (swiper, e)
168            onTouchMoveOpposite: function (swiper, e)
169            onTouchEnd: function (swiper, e)
170            onReachBeginning: function (swiper)
171            onReachEnd: function (swiper)
172            onSetTransition: function (swiper, duration)
173            onSetTranslate: function (swiper, translate)
174            onAutoplayStart: function (swiper)
175            onAutoplayStop: function (swiper),
176            onLazyImageLoad: function (swiper, slide, image)
177            onLazyImageReady: function (swiper, slide, image)
178            */
179            
180        };
181        params = params || {};
182        for (var def in defaults) {
183            if (typeof params[def] === 'undefined') {
184                params[def] = defaults[def];
185            }
186            else if (typeof params[def] === 'object') {
187                for (var deepDef in defaults[def]) {
188                    if (typeof params[def][deepDef] === 'undefined') {
189                        params[def][deepDef] = defaults[def][deepDef];
190                    }
191                }
192            }
193        }
194        
195        // Swiper
196        var s = this;
197        
198        // Params
199        s.params = params;
200        
201        // Classname
202        s.classNames = [];
203        /*=========================
204          Dom Library and plugins
205          ===========================*/
206        var $;
207        if (typeof Dom7 === 'undefined') {
208            $ = window.Dom7 || window.Zepto || window.jQuery;
209        }
210        else {
211            $ = Dom7;
212        }
213        if (!$) return;
214        
215        // Export it to Swiper instance
216        s.$ = $;
217        /*=========================
218          Preparation - Define Container, Wrapper and Pagination
219          ===========================*/
220        s.container = $(container);
221        if (s.container.length === 0) return;
222        if (s.container.length > 1) {
223            s.container.each(function () {
224                new Swiper(this, params);
225            });
226            return;
227        }
228        
229        // Save instance in container HTML Element and in data
230        s.container[0].swiper = s;
231        s.container.data('swiper', s);
232        
233        s.classNames.push('swiper-container-' + s.params.direction);
234        
235        if (s.params.freeMode) {
236            s.classNames.push('swiper-container-free-mode');
237        }
238        if (!s.support.flexbox) {
239            s.classNames.push('swiper-container-no-flexbox');
240            s.params.slidesPerColumn = 1;
241        }
242        // Enable slides progress when required
243        if (s.params.parallax || s.params.watchSlidesVisibility) {
244            s.params.watchSlidesProgress = true;
245        }
246        // Coverflow / 3D
247        if (['cube', 'coverflow'].indexOf(s.params.effect) >= 0) {
248            if (s.support.transforms3d) {
249                s.params.watchSlidesProgress = true;
250                s.classNames.push('swiper-container-3d');
251            }
252            else {
253                s.params.effect = 'slide';
254            }
255        }
256        if (s.params.effect !== 'slide') {
257            s.classNames.push('swiper-container-' + s.params.effect);
258        }
259        if (s.params.effect === 'cube') {
260            s.params.resistanceRatio = 0;
261            s.params.slidesPerView = 1;
262            s.params.slidesPerColumn = 1;
263            s.params.slidesPerGroup = 1;
264            s.params.centeredSlides = false;
265            s.params.spaceBetween = 0;
266            s.params.virtualTranslate = true;
267            s.params.setWrapperSize = false;
268        }
269        if (s.params.effect === 'fade') {
270            s.params.slidesPerView = 1;
271            s.params.slidesPerColumn = 1;
272            s.params.slidesPerGroup = 1;
273            s.params.watchSlidesProgress = true;
274            s.params.spaceBetween = 0;
275            s.params.virtualTranslate = true;
276        }
277        
278        // Grab Cursor
279        if (s.params.grabCursor && s.support.touch) {
280            s.params.grabCursor = false;
281        }
282        
283        // Wrapper
284        s.wrapper = s.container.children('.' + s.params.wrapperClass);
285        
286        // Pagination
287        if (s.params.pagination) {
288            s.paginationContainer = $(s.params.pagination);
289            if (s.params.paginationClickable) {
290                s.paginationContainer.addClass('swiper-pagination-clickable');
291            }
292        }
293        
294        // Is Horizontal
295        function isH() {
296            return s.params.direction === 'horizontal';
297        }
298        
299        // RTL
300        s.rtl = isH() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');
301        if (s.rtl) {
302            s.classNames.push('swiper-container-rtl');
303        }
304        
305        // Wrong RTL support
306        if (s.rtl) {
307            s.wrongRTL = s.wrapper.css('display') === '-webkit-box';
308        }
309        
310        // Columns
311        if (s.params.slidesPerColumn > 1) {
312            s.classNames.push('swiper-container-multirow');
313        }
314        
315        // Check for Android
316        if (s.device.android) {
317            s.classNames.push('swiper-container-android');
318        }
319        
320        // Add classes
321        s.container.addClass(s.classNames.join(' '));
322        
323        // Translate
324        s.translate = 0;
325        
326        // Progress
327        s.progress = 0;
328        
329        // Velocity
330        s.velocity = 0;
331        
332        // Locks, unlocks
333        s.lockSwipeToNext = function () {
334            s.params.allowSwipeToNext = false;
335        };
336        s.lockSwipeToPrev = function () {
337            s.params.allowSwipeToPrev = false;
338        };
339        s.lockSwipes = function () {
340            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;
341        };
342        s.unlockSwipeToNext = function () {
343            s.params.allowSwipeToNext = true;
344        };
345        s.unlockSwipeToPrev = function () {
346            s.params.allowSwipeToPrev = true;
347        };
348        s.unlockSwipes = function () {
349            s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;
350        };
351        
352        
353        /*=========================
354          Set grab cursor
355          ===========================*/
356        if (s.params.grabCursor) {
357            s.container[0].style.cursor = 'move';
358            s.container[0].style.cursor = '-webkit-grab';
359            s.container[0].style.cursor = '-moz-grab';
360            s.container[0].style.cursor = 'grab';
361        }
362        /*=========================
363          Update on Images Ready
364          ===========================*/
365        s.imagesToLoad = [];
366        s.imagesLoaded = 0;
367        
368        s.loadImage = function (imgElement, src, checkForComplete, callback) {
369            var image;
370            function onReady () {
371                if (callback) callback();
372            }
373            if (!imgElement.complete || !checkForComplete) {
374                if (src) {
375                    image = new Image();
376                    image.onload = onReady;
377                    image.onerror = onReady;
378                    image.src = src;
379                } else {
380                    onReady();
381                }
382        
383            } else {//image already loaded...
384                onReady();
385            }
386        };
387        s.preloadImages = function () {
388            s.imagesToLoad = s.container.find('img');
389            function _onReady() {
390                if (typeof s === 'undefined' || s === null) return;
391                if (s.imagesLoaded !== undefined) s.imagesLoaded++;
392                if (s.imagesLoaded === s.imagesToLoad.length) {
393                    if (s.params.updateOnImagesReady) s.update();
394                    s.emit('onImagesReady', s);
395                }
396            }
397            for (var i = 0; i < s.imagesToLoad.length; i++) {
398                s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), true, _onReady);
399            }
400        };
401        
402        /*=========================
403          Autoplay
404          ===========================*/
405        s.autoplayTimeoutId = undefined;
406        s.autoplaying = false;
407        s.autoplayPaused = false;
408        function autoplay() {
409            s.autoplayTimeoutId = setTimeout(function () {
410                if (s.params.loop) {
411                    s.fixLoop();
412                    s._slideNext();
413                }
414                else {
415                    if (!s.isEnd) {
416                        s._slideNext();
417                    }
418                    else {
419                        if (!params.autoplayStopOnLast) {
420                            s._slideTo(0);
421                        }
422                        else {
423                            s.stopAutoplay();
424                        }
425                    }
426                }
427            }, s.params.autoplay);
428        }
429        s.startAutoplay = function () {
430            if (typeof s.autoplayTimeoutId !== 'undefined') return false;
431            if (!s.params.autoplay) return false;
432            if (s.autoplaying) return false;
433            s.autoplaying = true;
434            s.emit('onAutoplayStart', s);
435            autoplay();
436        };
437        s.stopAutoplay = function (internal) {
438            if (!s.autoplayTimeoutId) return;
439            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
440            s.autoplaying = false;
441            s.autoplayTimeoutId = undefined;
442            s.emit('onAutoplayStop', s);
443        };
444        s.pauseAutoplay = function (speed) {
445            if (s.autoplayPaused) return;
446            if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
447            s.autoplayPaused = true;
448            if (speed === 0) {
449                s.autoplayPaused = false;
450                autoplay();
451            }
452            else {
453                s.wrapper.transitionEnd(function () {
454                    s.autoplayPaused = false;
455                    if (!s.autoplaying) {
456                        s.stopAutoplay();
457                    }
458                    else {
459                        autoplay();
460                    }
461                });
462            }
463        };
464        /*=========================
465          Min/Max Translate
466          ===========================*/
467        s.minTranslate = function () {
468            return (-s.snapGrid[0]);
469        };
470        s.maxTranslate = function () {
471            return (-s.snapGrid[s.snapGrid.length - 1]);
472        };
473        /*=========================
474          Slider/slides sizes
475          ===========================*/
476        s.updateContainerSize = function () {
477            s.width = s.container[0].clientWidth;
478            s.height = s.container[0].clientHeight;
479            s.size = isH() ? s.width : s.height;
480        };
481        
482        s.updateSlidesSize = function () {
483            s.slides = s.wrapper.children('.' + s.params.slideClass);
484            s.snapGrid = [];
485            s.slidesGrid = [];
486            s.slidesSizesGrid = [];
487            
488            var spaceBetween = s.params.spaceBetween,
489                slidePosition = 0,
490                i,
491                prevSlideSize = 0,
492                index = 0;
493            if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
494                spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;
495            }
496        
497            s.virtualSize = -spaceBetween;
498            // reset margins
499            if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});
500            else s.slides.css({marginRight: '', marginBottom: ''});
501        
502            var slidesNumberEvenToRows;
503            if (s.params.slidesPerColumn > 1) {
504                if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {
505                    slidesNumberEvenToRows = s.slides.length;
506                }
507                else {
508                    slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;
509                }
510            }
511        
512            // Calc slides
513            var slideSize;
514            for (i = 0; i < s.slides.length; i++) {
515                slideSize = 0;
516                var slide = s.slides.eq(i);
517                if (s.params.slidesPerColumn > 1) {
518                    // Set slides order
519                    var newSlideOrderIndex;
520                    var column, row;
521                    var slidesPerColumn = s.params.slidesPerColumn;
522                    var slidesPerRow;
523                    if (s.params.slidesPerColumnFill === 'column') {
524                        column = Math.floor(i / slidesPerColumn);
525                        row = i - column * slidesPerColumn;
526                        newSlideOrderIndex = column + row * slidesNumber
526EvenToRows / slidesPerColumn;
527                        slide
528                            .css({
529                                '-webkit-box-ordinal-group': newSlideOrderIndex,
530                                '-moz-box-ordinal-group': newSlideOrderIndex,
531                                '-ms-flex-order': newSlideOrderIndex,
532                                '-webkit-order': newSlideOrderIndex,
533                                'order': newSlideOrderIndex
534                            });
535                    }
536                    else {
537                        slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
538                        row = Math.floor(i / slidesPerRow);
539                        column = i - row * slidesPerRow;
540                        
541                    }
542                    slide
543                        .css({
544                            'margin-top': (row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')
545                        })
546                        .attr('data-swiper-column', column)
547                        .attr('data-swiper-row', row);
548                        
549                }
550                if (slide.css('display') === 'none') continue;
551                if (s.params.slidesPerView === 'auto') {
552                    slideSize = isH() ? slide.outerWidth(true) : slide.outerHeight(true);
553                }
554                else {
555                    slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;
556                    if (isH()) {
557                        s.slides[i].style.width = slideSize + 'px';
558                    }
559                    else {
560                        s.slides[i].style.height = slideSize + 'px';
561                    }
562                }
563                s.slides[i].swiperSlideSize = slideSize;
564                s.slidesSizesGrid.push(slideSize);
565                
566                
567                if (s.params.centeredSlides) {
568                    slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
569                    if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;
570                    if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
571                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
572                    s.slidesGrid.push(slidePosition);
573                }
574                else {
575                    if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
576                    s.slidesGrid.push(slidePosition);
577                    slidePosition = slidePosition + slideSize + spaceBetween;
578                }
579        
580                s.virtualSize += slideSize + spaceBetween;
581        
582                prevSlideSize = slideSize;
583        
584                index ++;
585            }
586            s.virtualSize = Math.max(s.virtualSize, s.size);
587        
588            var newSlidesGrid;
589        
590            if (
591                s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {
592                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
593            }
594            if (!s.support.flexbox || s.params.setWrapperSize) {
595                if (isH()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
596                else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
597            }
598        
599            if (s.params.slidesPerColumn > 1) {
600                s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;
601                s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;
602                s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
603                if (s.params.centeredSlides) {
604                    newSlidesGrid = [];
605                    for (i = 0; i < s.snapGrid.length; i++) {
606                        if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);
607                    }
608                    s.snapGrid = newSlidesGrid;
609                }
610            }
611        
612            // Remove last grid elements depending on width
613            if (!s.params.centeredSlides) {
614                newSlidesGrid = [];
615                for (i = 0; i < s.snapGrid.length; i++) {
616                    if (s.snapGrid[i] <= s.virtualSize - s.size) {
617                        newSlidesGrid.push(s.snapGrid[i]);
618                    }
619                }
620                s.snapGrid = newSlidesGrid;
621                if (Math.floor(s.virtualSize - s.size) > Math.floor(s.snapGrid[s.snapGrid.length - 1])) {
622                    s.snapGrid.push(s.virtualSize - s.size);
623                }
624            }
625            if (s.snapGrid.length === 0) s.snapGrid = [0];
626                
627            if (s.params.spaceBetween !== 0) {
628                if (isH()) {
629                    if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});
630                    else s.slides.css({marginRight: spaceBetween + 'px'});
631                }
632                else s.slides.css({marginBottom: spaceBetween + 'px'});
633            }
634            if (s.params.watchSlidesProgress) {
635                s.updateSlidesOffset();
636            }
637        };
638        s.updateSlidesOffset = function () {
639            for (var i = 0; i < s.slides.length; i++) {
640                s.slides[i].swiperSlideOffset = isH() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;
641            }
642        };
643        
644        /*=========================
645          Slider/slides progress
646          ===========================*/
647        s.updateSlidesProgress = function (translate) {
648            if (typeof translate === 'undefined') {
649                translate = s.translate || 0;
650            }
651            if (s.slides.length === 0) return;
652            if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();
653        
654            var offsetCenter = s.params.centeredSlides ? -translate + s.size / 2 : -translate;
655            if (s.rtl) offsetCenter = s.params.centeredSlides ? translate - s.size / 2 : translate;
656        
657            // Visible Slides
658            var containerBox = s.container[0].getBoundingClientRect();
659            var sideBefore = isH() ? 'left' : 'top';
660            var sideAfter = isH() ? 'right' : 'bottom';
661            s.slides.removeClass(s.params.slideVisibleClass);
662            for (var i = 0; i < s.slides.length; i++) {
663                var slide = s.slides[i];
664                var slideCenterOffset = (s.params.centeredSlides === true) ? slide.swiperSlideSize / 2 : 0;
665                var slideProgress = (offsetCenter - slide.swiperSlideOffset - slideCenterOffset) / (slide.swiperSlideSize + s.params.spaceBetween);
666                if (s.params.watchSlidesVisibility) {
667                    var slideBefore = -(offsetCenter - slide.swiperSlideOffset - slideCenterOffset);
668                    var slideAfter = slideBefore + s.slidesSizesGrid[i];
669                    var isVisible =
670                        (slideBefore >= 0 && slideBefore < s.size) ||
671                        (slideAfter > 0 && slideAfter <= s.size) ||
672                        (slideBefore <= 0 && slideAfter >= s.size);
673                    if (isVisible) {
674                        s.slides.eq(i).addClass(s.params.slideVisibleClass);
675                    }
676                }
677                slide.progress = s.rtl ? -slideProgress : slideProgress;
678            }
679        };
680        s.updateProgress = function (translate) {
681            if (typeof translate === 'undefined') {
682                translate = s.translate || 0;
683            }
684            var translatesDiff = s.maxTranslate() - s.minTranslate();
685            if (translatesDiff === 0) {
686                s.progress = 0;
687                s.isBeginning = s.isEnd = true;
688            }
689            else {
690                s.progress = (translate - s.minTranslate()) / (translatesDiff);
691                s.isBeginning = s.progress <= 0;
692                s.isEnd = s.progress >= 1;
693            }
694            if (s.isBeginning) s.emit('onReachBeginning', s);
695            if (s.isEnd) s.emit('onReachEnd', s);
696            
697            if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);
698            s.emit('onProgress', s, s.progress);
699        };
700        s.updateActiveIndex = function () {
701            var translate = s.rtl ? s.translate : -s.translate;
702            var newActiveIndex, i, snapIndex;
703            for (i = 0; i < s.slidesGrid.length; i ++) {
704                if (typeof s.slidesGrid[i + 1] !== 'undefined') {
705                    if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {
706                        newActiveIndex = i;
707                    }
708                    else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {
709                        newActiveIndex = i + 1;
710                    }
711                }
712                else {
713                    if (translate >= s.slidesGrid[i]) {
714                        newActiveIndex = i;
715                    }
716                }
717            }
718            // Normalize slideIndex
719            if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;
720            // for (i = 0; i < s.slidesGrid.length; i++) {
721                // if (- translate >= s.slidesGrid[i]) {
722                    // newActiveIndex = i;
723                // }
724            // }
725            snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);
726            if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;
727        
728            if (newActiveIndex === s.activeIndex) {
729                return;
730            }
731            s.snapIndex = snapIndex;
732            s.previousIndex = s.activeIndex;
733            s.activeIndex = newActiveIndex;
734            s.updateClasses();
735        };
736        
737        /*=========================
738          Classes
739          ===========================*/
740        s.updateClasses = function () {
741            s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);
742            var activeSlide = s.slides.eq(s.activeIndex);
743            // Active classes
744            activeSlide.addClass(s.params.slideActiveClass);
745            activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);
746            activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);
747        
748            // Pagination
749            if (s.bullets && s.bullets.length > 0) {
750                s.bullets.removeClass(s.params.bulletActiveClass);
751                var bulletIndex;
752                if (s.params.loop) {
753                    bulletIndex = Math.ceil(s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup;
754                    if (bulletIndex > s.slides.length - 1 - s.loopedSlides * 2) {
755                        bulletIndex = bulletIndex - (s.slides.length - s.loopedSlides * 2);
756                    }
757                    if (bulletIndex > s.bullets.length - 1) bulletIndex = bulletIndex - s.bullets.length; 
758                }
759                else {
760                    if (typeof s.snapIndex !== 'undefined') {
761                        bulletIndex = s.snapIndex;
762                    }
763                    else {
764                        bulletIndex = s.activeIndex || 0;
765                    }
766                }
767                if (s.paginationContainer.length > 1) {
768                    s.bullets.each(function () {
769                        if ($(this).index() === bulletIndex) $(this).addClass(s.params.bulletActiveClass);
770                    });
771                }
772                else {
773                    s.bullets.eq(bulletIndex).addClass(s.params.bulletActiveClass);
774                }
775            }
776        
777            // Next/active buttons
778            if (!s.params.loop) {
779                if (s.params.prevButton) {
780                    if (s.isBeginning) {
781                        $(s.params.prevButton).addClass(s.params.buttonDisabledClass);
782                        if (s.params.a11y && s.a11y) s.a11y.disable($(s.params.prevButton));
783                    }
784                    else {
785                        $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
786                        if (s.params.a11y && s.a11y) s.a11y.enable($(s.params.prevButton));
787                    }
788                }
789                if (s.params.nextButton) {
790                    if (s.isEnd) {
791                        $(s.params.nextButton).addClass(s.params.buttonDisabledClass);
792                        if (s.params.a11y && s.a11y) s.a11y.disable($(s.params.nextButton));
793                    }
794                    else {
795                        $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
796                        if (s.params.a11y && s.a11y) s.a11y.enable($(s.params.nextButton));
797                    }
798                }
799            }
800        };
801        
802        /*=========================
803          Pagination
804          ===========================*/
805        s.updatePagination = function () {
806            if (!s.params.pagination) return;
807            if (s.paginationContainer && s.paginationContainer.length > 0) {
808                var bulletsHTML = '';
809                var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
810                for (var i = 0; i < numberOfBullets; i++) {
811                    if (s.params.paginationBulletRender) {
812                        bulletsHTML += s.params.paginationBulletRender(i, s.params.bulletClass);
813                    }
814                    else {
815                        bulletsHTML += '<span class="' + s.params.bulletClass + '"></span>';
816                    }
817                }
818                s.paginationContainer.html(bulletsHTML);
819                s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);
820            }
821        };
822        /*=========================
823          Common update method
824          ===========================*/
825        s.update = function (updateTranslate) {
826            s.updateContainerSize();
827            s.updateSlidesSize();
828            s.updateProgress();
829            s.updatePagination();
830            s.updateClasses();
831            if (s.params.scrollbar && s.scrollbar) {
832                s.scrollbar.set();
833            }
834            function forceSetTranslate() {
835                newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
836                s.setWrapperTranslate(newTranslate);
837                s.updateActiveIndex();
838                s.updateClasses();
839            }
840            if (updateTranslate) {
841                var translated, newTranslate;
842                if (s.params.freeMode) {
843                    forceSetTranslate();
844                }
845                else {
846                    if (s.params.slidesPerView === 'auto' && s.isEnd && !s.params.centeredSlides) {
847                        translated = s.slideTo(s.slides.length - 1, 0, false, true);
848                    }
849                    else {
850                        translated = s.slideTo(s.activeIndex, 0, false, true);
851                    }
852                    if (!translated) {
853                        forceSetTranslate();
854                    }
855                }
856                    
857            }
858        };
859        
860        /*=========================
861          Resize Handler
862          ===========================*/
863        s.onResize = function () {
864            s.updateContainerSize();
865            s.updateSlidesSize();
866            s.updateProgress();
867            if (s.params.slidesPerView === 'auto' || s.params.freeMode) s.updatePagination();
868            if (s.params.scrollbar && s.scrollbar) {
869                s.scrollbar.set();
870            }
871            if (s.params.freeMode) {
872                var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
873                s.setWrapperTranslate(newTranslate);
874                s.updateActiveIndex();
875                s.updateClasses();
876            }
877            else {
878                s.updateClasses();
879                if (s.params.slidesPerView === 'auto' && s.isEnd && !s.params.centeredSlides) {
880                    s.slideTo(s.slides.length -
880 1, 0, false, true);
881                }
882                else {
883                    s.slideTo(s.activeIndex, 0, false, true);
884                }
885            }
886                
887        };
888        
889        /*=========================
890          Events
891          ===========================*/
892        
893        //Define Touch Events
894        var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];
895        if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];
896        else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];
897        s.touchEvents = {
898            start : s.support.touch || !s.params.simulateTouch  ? 'touchstart' : desktopEvents[0],
899            move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],
900            end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]
901        };
902            
903        
904        // WP8 Touch Events Fix
905        if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {
906            (s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);
907        }
908        
909        // Attach/detach events
910        s.initEvents = function (detach) {
911            var actionDom = detach ? 'off' : 'on';
912            var action = detach ? 'removeEventListener' : 'addEventListener';
913            var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];
914            var target = s.support.touch ? touchEventsTarget : document;
915        
916            var moveCapture = s.params.nested ? true : false;
917        
918            //Touch Events
919            if (s.browser.ie) {
920                touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
921                target[action](s.touchEvents.move, s.onTouchMove, moveCapture);
922                target[action](s.touchEvents.end, s.onTouchEnd, false);
923            }
924            else {
925                if (s.support.touch) {
926                    touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
927                    touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);
928                    touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);
929                }
930                if (params.simulateTouch && !s.device.ios && !s.device.android) {
931                    touchEventsTarget[action]('mousedown', s.onTouchStart, false);
932                    target[action]('mousemove', s.onTouchMove, moveCapture);
933                    target[action]('mouseup', s.onTouchEnd, false);
934                }
935            }
936            window[action]('resize', s.onResize);
937        
938            // Next, Prev, Index
939            if (s.params.nextButton) {
940                $(s.params.nextButton)[actionDom]('click', s.onClickNext);
941                if (s.params.a11y && s.a11y) $(s.params.nextButton)[actionDom]('keydown', s.a11y.onEnterKey);
942            }
943            if (s.params.prevButton) {
944                $(s.params.prevButton)[actionDom]('click', s.onClickPrev);
945                if (s.params.a11y && s.a11y) $(s.params.prevButton)[actionDom]('keydown', s.a11y.onEnterKey);
946            }
947            if (s.params.pagination && s.params.paginationClickable) {
948                $(s.paginationContainer)[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);
949            }
950        
951            // Prevent Links Clicks
952            if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);
953        };
954        s.attachEvents = function (detach) {
955            s.initEvents();
956        };
957        s.detachEvents = function () {
958            s.initEvents(true);
959        };
960        
961        /*=========================
962          Handle Clicks
963          ===========================*/
964        // Prevent Clicks
965        s.allowClick = true;
966        s.preventClicks = function (e) {
967            if (!s.allowClick) {
968                if (s.params.preventClicks) e.preventDefault();
969                if (s.params.preventClicksPropagation) {
970                    e.stopPropagation();
971                    e.stopImmediatePropagation();
972                }
973            }
974        };
975        // Clicks
976        s.onClickNext = function (e) {
977            e.preventDefault();
978            s.slideNext();
979        };
980        s.onClickPrev = function (e) {
981            e.preventDefault();
982            s.slidePrev();
983        };
984        s.onClickIndex = function (e) {
985            e.preventDefault();
986            var index = $(this).index() * s.params.slidesPerGroup;
987            if (s.params.loop) index = index + s.loopedSlides;
988            s.slideTo(index);
989        };
990        
991        /*=========================
992          Handle Touches
993          ===========================*/
994        function findElementInEvent(e, selector) {
995            var el = $(e.target);
996            if (!el.is(selector)) {
997                if (typeof selector === 'string') {
998                    el = el.parents(selector);
999                }
1000                else if (selector.nodeType) {
1001                    var found;
1002                    el.parents().each(function (index, _el) {
1003                        if (_el === selector) found = selector;
1004                    });
1005                    if (!found) return undefined;
1006                    else return selector;
1007                }
1008            }
1009            if (el.length === 0) {
1010                return undefined;
1011            }
1012            return el[0];
1013        }
1014        s.updateClickedSlide = function (e) {
1015            var slide = findElementInEvent(e, '.' + s.params.slideClass);
1016            if (slide) {
1017                s.clickedSlide = slide;
1018                s.clickedIndex = $(slide).index();
1019            }
1020            else {
1021                s.clickedSlide = undefined;
1022                s.clickedIndex = undefined;
1023                return;
1024            }
1025            if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {
1026                var slideToIndex = s.clickedIndex,
1027                    realIndex;
1028                if (s.params.loop) {
1029                    realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');
1030                    if (slideToIndex > s.slides.length - s.params.slidesPerView) {
1031                        s.fixLoop();
1032                        slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]').eq(0).index();
1033                        setTimeout(function () {
1034                            s.slideTo(slideToIndex);
1035                        }, 0);
1036                    }
1037                    else if (slideToIndex < s.params.slidesPerView - 1) {
1038                        s.fixLoop();
1039                        var duplicatedSlides = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]');
1040                        slideToIndex = duplicatedSlides.eq(duplicatedSlides.length - 1).index();
1041                        setTimeout(function () {
1042                            s.slideTo(slideToIndex);
1043                        }, 0);
1044                    }
1045                    else {
1046                        s.slideTo(slideToIndex);
1047                    }
1048                }
1049                else {
1050                    s.slideTo(slideToIndex);
1051                }
1052            }
1053        };
1054        
1055        var isTouched, 
1056            isMoved, 
1057            touchStartTime, 
1058            isScrolling, 
1059            currentTranslate, 
1060            startTranslate, 
1061            allowThresholdMove,
1062            // Form elements to match
1063            formElements = 'input, select, textarea, button',
1064            // Last click time
1065            lastClickTime = Date.now(), clickTimeout,
1066            //Velocities
1067            velocities = [], 
1068            allowMomentumBounce;
1069        
1070        // Animating Flag
1071        s.animating = false;
1072        
1073        // Touches information
1074        s.touches = {
1075            startX: 0,
1076            startY: 0,
1077            currentX: 0,
1078            currentY: 0,
1079            diff: 0
1080        };
1081        
1082        // Touch handlers
1083        var isTouchEvent, startMoving;
1084        s.onTouchStart = function (e) {
1085            if (e.originalEvent) e = e.originalEvent;
1086            isTouchEvent = e.type === 'touchstart';
1087            if (!isTouchEvent && 'which' in e && e.which === 3) return;
1088            if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {
1089                s.allowClick = true;
1090                return;
1091            }
1092            if (s.params.swipeHandler) {
1093                if (!findElementInEvent(e, s.params.swipeHandler)) return;
1094            }
1095            isTouched = true;
1096            isMoved = false;
1097            isScrolling = undefined;
1098            startMoving = undefined;
1099            s.touches.startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
1100            s.touches.startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
1101            touchStartTime = Date.now();
1102            s.allowClick = true;
1103            s.updateContainerSize();
1104            s.swipeDirection = undefined;
1105            if (s.params.threshold > 0) allowThresholdMove = false;
1106            if (e.type !== 'touchstart') {
1107                var preventDefault = true;
1108                if ($(e.target).is(formElements)) preventDefault = false;
1109                if (document.activeElement && $(document.activeElement).is(formElements)) {
1110                    document.activeElement.blur();
1111                }
1112                if (preventDefault) {
1113                    e.preventDefault();
1114                }
1115            }
1116            s.emit('onTouchStart', s, e);
1117        };
1118        
1119        s.onTouchMove = function (e) {
1120            if (e.originalEvent) e = e.originalEvent;
1121            if (isTouchEvent && e.type === 'mousemove') return;
1122            if (e.preventedByNestedSwiper) return;
1123            if (s.params.onlyExternal) {
1124                isMoved = true;
1125                s.allowClick = false;
1126                return;
1127            }
1128            if (isTouchEvent && document.activeElement) {
1129                if (e.target === document.activeElement && $(e.target).is(formElements)) {
1130                    isMoved = true;
1131                    s.allowClick = false;
1132                    return;
1133                }
1134            }
1135            
1136            s.emit('onTouchMove', s, e);
1137            
1138            if (e.targetTouches && e.targetTouches.length > 1) return;
1139            
1140            s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
1141            s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
1142        
1143            if (typeof isScrolling === 'undefined') {
1144                var touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;
1145                isScrolling = isH() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);
1146            }
1147            if (isScrolling) {
1148                s.emit('onTouchMoveOpposite', s, e);
1149            }
1150            if (typeof startMoving === 'undefined' && s.browser.ieTouch) {
1151                if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {
1152                    startMoving = true;
1153                }
1154            }
1155            if (!isTouched) return;
1156            if (isScrolling)  {
1157                isTouched = false;
1158                return;
1159            }
1160            if (!startMoving && s.browser.ieTouch) {
1161                return;
1162            }
1163            s.allowClick = false;
1164            s.emit('onSliderMove', s, e);
1165            e.preventDefault();
1166            if (s.params.touchMoveStopPropagation && !s.params.nested) {
1167                e.stopPropagation();
1168            }
1169        
1170            if (!isMoved) {
1171                if (params.loop) {
1172                    s.fixLoop();
1173                }
1174                startTranslate = s.getWrapperTranslate();
1175                s.setWrapperTransition(0);
1176                if (s.animating) {
1177                    s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');
1178                }
1179                if (s.params.autoplay && s.autoplaying) {
1180                    if (s.params.autoplayDisableOnInteraction) {
1181                        s.stopAutoplay();
1182                    }
1183                    else {
1184                        s.pauseAutoplay();
1185                    }
1186                }
1187                allowMomentumBounce = false;
1188                //Grab Cursor
1189                if (s.params.grabCursor) {
1190                    s.container[0].style.cursor = 'move';
1191                    s.container[0].style.cursor = '-webkit-grabbing';
1192                    s.container[0].style.cursor = '-moz-grabbin';
1193                    s.container[0].style.cursor = 'grabbing';
1194                }
1195            }
1196            isMoved = true;
1197        
1198            var diff = s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
1199        
1200            diff = diff * s.params.touchRatio;
1201            if (s.rtl) diff = -diff;
1202        
1203            s.swipeDirection = diff > 0 ? 'prev' : 'next';
1204            currentTranslate = diff + startTranslate;
1205        
1206            var disableParentSwiper = true;
1207            if ((diff > 0 && currentTranslate > s.minTranslate())) {
1208                disableParentSwiper = false;
1209                if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);
1210            }
1211            else if (diff < 0 && currentTranslate < s.maxTranslate()) {
1212                disableParentSwiper = false;
1213                if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);
1214            }
1215            
1216            if (disableParentSwiper) {
1217                e.preventedByNestedSwiper = true;
1218            }
1219        
1220            // Directions locks
1221            if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {
1222                currentTranslate = startTranslate;
1223            }
1224            if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {
1225                currentTranslate = startTranslate;
1226            }
1227            
1228            if (!s.params.followFinger) return;
1229        
1230            // Threshold
1231            if (s.params.threshold > 0) {
1232                if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {
1233                    if (!allowThresholdMove) {
1234                        allowThresholdMove = true;
1235                        s.touches.startX = s.touches.currentX;
1236                        s.touches.startY = s.touches.currentY;
1237                        currentTranslate = startTranslate;
1238                        s.touches.diff = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
1239                        return;
1240                    }
1241                }
1242                else {
1243                    currentTranslate = startTranslate;
1244                    return;
1245                }
1246            }
1247            // Update active index in free mode
1248            if (s.params.freeMode || s.params.watchSlidesProgress) {
1249                s.updateActiveIndex();
1250            }
1251            if (s.params.freeMode) {
1252                //Velocity
1253                if (velocities.length === 0) {
1254                    velocities.push({
1255                        position: s.touches[isH() ? 'startX' : 'startY'],
1256                        time: touchStartTime
1257                    });
1258                }
1259                velocities.push({
1260                    position: s.touches[isH() ? 'currentX' : 'currentY'],
1261                    time: (new Date()).getTime()
1262                });
1263            }
1264            // Update progress
1265            s.updateProgress(currentTranslate);
1266            // Update translate
1267            s.setWrapperTranslate(currentTranslate);
1268        };
1269        s.onTouchEnd = function (e) {
1270            if (e.originalEvent) e = e.originalEvent;
1271            s.emit('onTouchEnd', s, e);
1272            if (!isTouched) return;
1273            //Return Grab Cursor
1274            if (s.params.grabCursor && isMoved && isTouched) {
1275                s.container[0].style.cursor = 'move';
1276                s.container[0].style.cursor = '-webkit-grab';
1277                s.container[0].style.cursor = '-moz-grab';
1278                s.container[0].style.cursor = 'grab';
1279            }
1280        
1281            // Time diff
1282            var touchEndTime = Date.now();
1283            var timeDiff = touchEndTime - touchStartTime;
1284        
1285            // Tap, doubleTap, Click
1286            if (s.allowClick) {
1287                s.updateClickedSlide(e);
1288                s.emit('onTap', s, e);
1289                if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {
1290                    if (clickTimeout) clearTimeout(clickTimeout);
1291                    clickTimeout = setTimeout(function () {
1292                        if (!s) return;
1293                        if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {
1294                            s.paginationContainer.toggleClass(s.params.paginationHiddenClass);
1295                        }
1296                        s.emit('onClick', s, e);
1297                    }, 300);
1298                    
1299                }
1300                if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {
1301                    if (clickTimeout) clearTimeout(clickTimeout);
1302                    s.emit('onDoubleTap', s, e);
1303                }
1304            }
1305        
1306            lastClickTime = Date.now();
1307            setTimeout(function () {
1308                if (s && s.allowClick) s.allowClick = true;
1309            }, 0);
1310        
1311            if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {
1312                isTouched = isMoved = false;
1313                return;
1314            }
1315            isTouched = isMoved = false;
1316        
1317            var currentPos;
1318            if (s.params.followFinger) {
1319                currentPos = s.rtl ? s.translate : -s.translate;
1320            }
1321            else {
1322                currentPos = -currentTranslate;
1323            }
1324            if (s.params.freeMode) {
1325                if (currentPos < -s.minTranslate()) {
1326                    s.slideTo(s.activeIndex);
1327                    return;
1328                }
1329                else if (currentPos > -s.maxTranslate()) {
1330                    s.slideTo(s.slides.length - 1);
1331                    return;
1332                }
1333                
1334                if (s.params.freeModeMomentum) {
1335                    if (velocities.length > 1) {
1336                        var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();
1337        
1338                        var distance = lastMoveEvent.position - velocityEvent.position;
1339                        var time = lastMoveEvent.time - velocityEvent.time;
1340                        s.velocity = distance / time;
1341                        s.velocity = s.velocity / 2;
1342                        if (Math.abs(s.velocity) < 0.02) {
1343                            s.velocity = 0;
1344                        }
1345                        // this implies that the user stopped moving a finger then released.
1346                        // There would be no events with distance zero, so the last event is stale.
1347                        if (time > 150 || (new Date().getTime() - lastMoveEvent.time) > 300) {
1348                            s.velocity = 0;
1349                        }
1350                    } else {
1351                        s.velocity = 0;
1352                    }
1353        
1354                    velocities.length = 0;
1355                    var momentumDuration = 1000 * s.params.freeModeMomentumRatio;
1356                    var momentumDistance = s.velocity * momentumDuration;
1357        
1358                    var newPosition = s.translate + momentumDistance;
1359                    if (s.rtl) newPosition = - newPosition;
1360                    var doBounce = false;
1361                    var afterBouncePosition;
1362                    var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;
1363                    if (newPosition < s.maxTranslate()) {
1364                        if (s.params.freeModeMomentumBounce) {
1365                            if (newPosition + s.maxTranslate() < -bounceAmount) {
1366                                newPosition = s.maxTranslate() - bounceAmount;
1367                            }
1368                            afterBouncePosition = s.maxTranslate();
1369                            doBounce = true;
1370                            allowMomentumBounce = true;
1371                        }
1372                        else {
1373                            newPosition = s.maxTranslate();
1374                        }
1375                    }
1376                    if (newPosition > s.minTranslate()) {
1377                        if (s.params.freeModeMomentumBounce) {
1378                            if (newPosition - s.minTranslate() > bounceAmount) {
1379                                newPosition = s.minTranslate() + bounceAmount;
1380                            }
1381                            afterBouncePosition = s.minTranslate();
1382                            doBounce = true;
1383                            allowMomentumBounce = true;
1384                        }
1385                        else {
1386                            newPosition = s.minTranslate();
1387                        }
1388                    }
1389                    //Fix duration
1390                    if (s.velocity !== 0) {
1391                        if (s.rtl) {
1392                            momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);
1393                        }
1394                        else {
1395                            momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);
1396                        }
1397                    }
1398        
1399                    if (s.params.freeModeMomentumBounce && doBounce) {
1400                        s.updateProgress(afterBouncePosition);
1401                        s.setWrapperTransition(momentumDuration);
1402                        s.setWrapperTranslate(newPosition);
1403                        s.onTransitionStart();
1404                        s.animating = true;
1405                        s.wrapper.transitionEnd(function () {
1406                            if (!allowMomentumBounce) return;
1407                            s.emit('onMomentumBounce', s);
1408        
1409                            s.setWrapperTransition(s.params.speed);
1410                            s.setWrapperTranslate(afterBouncePosition);
1411                            s.wrapper.transitionEnd(function () {
1412                                s.onTransitionEnd();
1413                            });
1414                        });
1415                    } else if (s.velocity) {
1416                        s.updateProgress(newPosition);
1417                        s.setWrapperTransition(momentumDuration);
1418                        s.setWrapperTranslate(newPosition);
1419                        s.onTransitionStart();
1420                        if (!s.animating) {
1421                            s.animating = true;
1422                            s.wrapper.transitionEnd(function () {
1423                                s.onTransitionEnd();
1424                            });
1425                        }
1426                            
1427                    } else {
1428                        s.updateProgress(newPosition);
1429                    }
1430                    
1431                    s.updateActiveIndex();
1432                }
1433                if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {
1434                    s.updateProgress();
1435                    s.updateActiveIndex();
1436                }
1437                return;
1438            }
1439        
1440            // Find current slide
1441            var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];
1442            for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {
1443                if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {
1444                    if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {
1445                        stopIndex = i;
1446                        groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];
1447                    }
1448                }
1449                else {
1450                    if (currentPos >= s.slidesGrid[i]) {
1451                        stopIndex = i;
1452                        groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];
1453                    }
1454                }
1455            }
1456        
1457            // Find current slide size
1458            var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;
1459            
1460            if (timeDiff > s.params.longSwipesMs) {
1461                // Long touches
1462                if (!s.params.longSwipes) {
1463                    s.slideTo(s.activeIndex);
1464                    return;
1465                }
1466                if (s.swipeDirection === 'next') {
1467                    if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);
1468                    else s.slideTo(stopIndex);
1469        
1470                }
1471                if (s.swipeDirection === 'prev') {
1472                    if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);
1473                    else s.slideTo(stopIndex);
1474                }
1475            }
1476            else {
1477                // Short swipes
1478                if (!s.params.shortSwipes) {
1479                    s.slideTo(s.activeIndex);
1480                    return;
1481                }
1482                if (s.swipeDirection === 'next') {
1483                    s.slideTo(stopIndex + s.params.slidesPerGroup);
1484        
1485                }
1486                if (s.swipeDirection === 'prev') {
1487                    s.slideTo(stopIndex);
1488                }
1489            }
1490        };
1491        /*=========================
1492          Transitions
1493          ===========================*/
1494        s._slideTo = function (slideIndex, speed) {
1495            return s.slideTo(slideIndex, speed, true, true);
1496        };
1497        s.slideTo = function (slideIndex, speed, runCallbacks, internal) {
1498            if (typeof runCallbacks === 'undefined') runCallbacks = true;
1499            if (typeof slideIndex === 'undefined') slideIndex = 0;
1500            if (slideIndex < 0) slideIndex = 0;
1501            s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);
1502            if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;
1503            
1504            var translate = - s.snapGrid[s.snapIndex];
1505        
1506            // Stop autoplay
1507        
1508            if (s.params.autoplay && s.autoplaying) {
1509                if (internal || !s.params.autoplayDisableOnInteraction) {
1510                    s.pauseAutoplay(speed);
1511                }
1512                else {
1513                    s.stopAutoplay();
1514                }
1515            }
1516            // Update progress
1517            s.updateProgress(translate);
1518        
1519            // Normalize slideIndex
1520            for (var i = 0; i < s.slidesGrid.length; i++) {
1521                if (- translate >= s.slidesGrid[i]) {
1522                    slideIndex = i;
1523                }
1524            }
1525        
1526            if (typeof speed === 'undefined') speed = s.params.speed;
1527            s.previousIndex = s.activeIndex || 0;
1528            s.activeIndex = slideIndex;
1529            
1530            if (translate === s.translate) {
1531                s.updateClasses();
1532                return false;
1533            }
1534            s.onTransitionStart(runCallbacks);
1535            var translateX = isH() ? translate : 0, translateY = isH() ? 0 : translate;
1536            if (speed === 0) {
1537                s.setWrapperTransition(0);
1538                s.setWrapperTranslate(translate);
1539                s.onTransitionEnd(runCallbacks);
1540            }
1541            else {
1542                s.setWrapperTransition(speed);
1543                s.setWrapperTranslate(translate);
1544                if (!s.animating) {
1545                    s.animating = true;
1546                    s.wrapper.transitionEnd(function () {
1547                        s.onTransitionEnd(runCallbacks);
1548                    });
1549                }
1550                    
1551            }
1552            s.updateClasses();
1553            return true;
1554        };
1555        
1556        s.onTransitionStart = function (runCallbacks) {
1557            if (typeof runCallbacks === 'undefined') runCallbacks = true;
1558            if (s.lazy) s.lazy.onTransitionStart();
1559            if (runCallbacks) {
1560                s.emit('onTransitionStart', s);
1561                if (s.activeIndex !== s.previousIndex) {
1562                    s.emit('onSlideChangeStart', s);
1563                }
1564            }
1565        };
1566        s.onTransitionEnd = function (runCallbacks) {
1567            s.animating = false;
1568            s.setWrapperTransition(0);
1569            if (typeof runCallbacks === 'undefined') runCallbacks = true;
1570            if (s.lazy) s.lazy.onTransitionEnd();
1571            if (runCallbacks) {
1572                s.emit('onTransitionEnd', s);
1573                if (s.activeIndex !== s.previousIndex) {
1574                    s.emit('onSlideChangeEnd', s);
1575                }
1576            }
1577            if (s.params.hashnav && s.hashnav) {
1578                s.hashnav.setHash();
1579            }
1580                
1581        };
1582        s.slideNext = function (runCallbacks, speed, internal) {
1583            if (s.params.loop) {
1584                if (s.animating) return false;
1585                s.fixLoop();
1586                var clientLeft = s.container[0].clientLeft;
1587                return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
1588            }
1589            else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
1590        };
1591        s._slideNext = function (speed) {
1592            return s.slideNext(true, speed, true);
1593        };
1594        s.slidePrev = function (runCallbacks, speed, internal) {
1595            if (s.params.loop) {
1596                if (s.animating) return false;
1597                s.fixLoop();
1598                var clientLeft = s.container[0].clientLeft;
1599                return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
1600            }
1601            else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
1602        };
1603        s._slidePrev = function (speed) {
1604            return s.slidePrev(true, speed, true);
1605        };
1606        s.slideReset = function (runCallbacks, speed, internal) {
1607            return s.slideTo(s.activeIndex, speed, runCallbacks);
1608        };
1609        
1610        /*=========================
1611          Translate/transition helpers
1612          ===========================*/
1613        s.setWrapperTransition = function (duration, byController) {
1614            s.wrapper.transition(duration);
1615            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
1616                s.effects[s.params.effect].setTransition(duration);
1617            }
1618            if (s.params.parallax && s.parallax) {
1619                s.parallax.setTransition(duration);
1620            }
1621            if (s.params.scrollbar && s.scrollbar) {
1622                s.scrollbar.setTransition(duration);
1623            }
1624            if (s.params.control && s.controller) {
1625                s.controller.setTransition(duration, byController);
1626            }
1627            s.emit('onSetTransition', s, duration);
1628        };
1629        s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {
1630            var x = 0, y = 0, z = 0;
1631            if (isH()) {
1632                x = s.rtl ? -translate : translate;
1633            }
1634            else {
1635                y = translate;
1636            }
1637            if (!s.params.virtualTranslate) {
1638                if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');
1639                else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');
1640            }
1641        
1642            s.translate = isH() ? x : y;
1643        
1644            if (updateActiveIndex) s.updateActiveIndex();
1645            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
1646                s.effects[s.params.effect].setTranslate(s.translate);
1647            }
1648            if (s.params.parallax && s.parallax) {
1649                s.parallax.setTranslate(s.translate);
1650            }
1651            if (s.params.scrollbar && s.scrollbar) {
1652                s.scrollbar.setTranslate(s.translate);
1653            }
1654            if (s.params.control && s.controller) {
1655                s.controller.setTranslate(s.translate, byController);
1656            }
1657            s.emit('onSetTranslate', s, s.translate);
1658        };
1659        
1660        s.getTranslate = function (el, axis) {
1661            var matrix, curTransform, curStyle, transformMatrix;
1662        
1663            // automatic axis detection
1664            if (typeof axis === 'undefined') {
1665                axis = 'x';
1666            }
1667        
1668            if (s.params.virtualTranslate) {
1669                return s.rtl ? -s.translate : s.translate;
1670            }
1671        
1672            curStyle = window.getComputedStyle(el, null);
1673            if (window.WebKitCSSMatrix) {
1674                // Some old versions of Webkit choke when 'none' is passed; pass
1675                // empty string instead in this case
1676                transformMatrix = new WebKitCSSMatrix(curStyle.webkitTransform === 'none' ? '' : curStyle.webkitTransform);
1677            }
1678            else {
1679                transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform  || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
1680                matrix = transformMatrix.toString().split(',');
1681            }
1682        
1683            if (axis === 'x') {
1684                //Latest Chrome and webkits Fix
1685                if (window.WebKitCSSMatrix)
1686                    curTransform = transformMatrix.m41;
1687                //Crazy IE10 Matrix
1688                else if (matrix.length === 16)
1689                    curTransform = parseFloat(matrix[12]);
1690                //Normal Browsers
1691                else
1692                    curTransform = parseFloat(matrix[4]);
1693            }
1694            if (axis === 'y') {
1695                //Latest Chrome and webkits Fix
1696                if (window.WebKitCSSMatrix)
1697                    curTransform = transformMatrix.m42;
1698                //Crazy IE10 Matrix
1699                else if (matrix.length === 16)
1700                    curTransform = parseFloat(matrix[13]);
1701                //Normal Browsers
1702                else
1703                    curTransform = parseFloat(matrix[5]);
1704            }
1705            if (s.rtl && curTransform) curTransform = -curTransform;
1706            return curTransform || 0;
1707        };
1708        s.getWrapperTranslate = function (axis) {
1709            if (typeof axis === 'undefined') {
1710                axis = isH() ? 'x' : 'y';
1711            }
1712            return s.getTranslate(s.wrapper[0], axis);
1713        };
1714        
1715        /*=========================
1716          Observer
1717          ===========================*/
1718        s.observers = [];
1719        function initObserver(target, options) {
1720            options = options || {};
1721            // create an observer instance
1722            var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
1723            var observer = new ObserverFunc(function (mutations) {
1724                mutations.forEach(function (mutation) {
1725                    s.onResize();
1726                    s.emit('onObserverUpdate', s, mutation);
1727                });
1728            });
1729             
1730            observer.observe(target, {
1731                attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
1732                childList: typeof options.childList === 'undefined' ? true : options.childList,
1733                characterData: typeof options.characterData === 'undefined' ? true : options.characterData
1734            });
1735        
1736            s.observers.push(observer);
1737        }
1738        s.initObservers = function () {
1739            if (s.params.observeParents) {
1740                var containerParents = s.container.parents();
1741                for (var i = 0; i < containerParents.length; i++) {
1742                    initObserver(containerParents[i]);
1743                }
1744            }
1745        
1746            // Observe container
1747            initObserver(s.container[0], {childList: false});
1748        
1749            // Observe wrapper
1750            initObserver(s.wrapper[0], {attributes: false});
1751        };
1752        s.disconnectObservers = function () {
1753            for (var i = 0; i < s.observers.length; i++) {
1754                s.observers[i].disconnect();
1755            }
1756            s.observers = [];
1757        };
1758        /*=========================
1759          Loop
1760          ===========================*/
1761        // Create looped slides
1762        s.createLoop = function () {
1763            // Remove duplicated slides
1764            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
1765        
1766            var slides = s.wrapper.children('.' + s.params.slideClass);
1767            s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);
1768            s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;
1769            if (s.loopedSlides > slides.length) {
1770                s.loopedSlides = slides.length;
1771            }
1772        
1773            var prependSlides = [], appendSlides = [], i;
1774            slides.each(function (index, el) {
1775                var slide = $(this);
1776                if (index < s.loopedSlides) appendSlides.push(el);
1777                if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);
1778                slide.attr('data-swiper-slide-index', index);
1779            });
1780            for (i = 0; i < appendSlides.length; i++) {
1781                s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
1782            }
1783            for (i = prependSlides.length - 1; i >= 0; i--) {
1784                s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
1785            }
1786        };
1787        s.destroyLoop = function () {
1788            s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
1789        };
1790        s.fixLoop = function () {
1791            var newIndex;
1792            //Fix For Negative Oversliding
1793            if (s.activeIndex < s.loopedSlides) {
1794                newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;
1795                newIndex = newIndex + s.loopedSlides;
1796                s.slideTo(newIndex, 0, false, true);
1797            }
1798            //Fix For Positive Oversliding
1799            else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {
1800                newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;
1801                newIndex = newIndex + s.loopedSlides;
1802                s.slideTo(newIndex, 0, false, true);
1803            }
1804        };
1805        /*=========================
1806          Append/Prepend/Remove Slides
1807          ===========================*/
1808        s.appendSlide = function (slides) {
1809            if (s.params.loop) {
1810                s.destroyLoop();
1811            }
1812            if (typeof slides === 'object' && slides.length) {
1813                for (var i = 0; i < slides.length; i++) {
1814                    if (slides[i]) s.wrapper.append(slides[i]);
1815                }
1816            }
1817            else {
1818                s.wrapper.append(slides);
1819            }
1820            if (s.params.loop) {
1821                s.createLoop();
1822            }
1823            if (!(s.params.observer && s.support.observer)) {
1824                s.update(true);
1825            }
1826        };
1827        s.prependSlide = function (slides) {
1828            if (s.params.loop) {
1829                s.destroyLoop();
1830            }
1831            var newActiveIndex = s.activeIndex + 1;
1832            if (typeof slides === 'object' && slides.length) {
1833                for (var i = 0; i < slides.length; i++) {
1834                    if (slides[i]) s.wrapper.prepend(slides[i]);
1835                }
1836                newActiveIndex = s.activeIndex + slides.length;
1837            }
1838            else {
1839                s.wrapper.prepend(slides);
1840            }
1841            if (s.params.loop) {
1842                s.createLoop();
1843            }
1844            if (!(s.params.observer && s.support.observer)) {
1845                s.update(true);
1846            }
1847            s.slideTo(newActiveIndex, 0, false);
1848        };
1849        s.removeSlide = function (slidesIndexes) {
1850            if (s.params.loop) {
1851                s.destroyLoop();
1852            }
1853            var newActiveIndex = s.activeIndex,
1854                indexToRemove;
1855            if (typeof slidesIndexes === 'object' && slidesIndexes.length) {
1856                for (var i = 0; i < slidesIndexes.length; i++) {
1857                    indexToRemove = slidesIndexes[i];
1858                    if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
1859                    if (indexToRemove < newActiveIndex) newActiveIndex--;
1860                }
1861                newActiveIndex = Math.max(newActiveIndex, 0);
1862            }
1863            else {
1864                indexToRemove = slidesIndexes;
1865                if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
1866                if (indexToRemove < newActiveIndex) newActiveIndex--;
1867                newActiveIndex = Math.max(newActiveIndex, 0);
1868            }
1869        
1870            if (!(s.params.observer && s.support.observer)) {
1871                s.update(true);
1872            }
1873            s.slideTo(newActiveIndex, 0, false);
1874        };
1875        s.removeAllSlides = function () {
1876            var slidesIndexes = [];
1877            for (var i = 0; i < s.slides.length; i++) {
1878                slidesIndexes.push(i);
1879            }
1880            s.removeSlide(slidesIndexes);
1881        };
1882        
1883
1884        /*=========================
1885          Effects
1886          ===========================*/
1887        s.effects = {
1888            fade: {
1889                setTranslate: function () {
1890                    for (var i = 0; i < s.slides.length; i++) {
1891                        var slide = s.slides.eq(i);
1892                        var offset = slide[0].swiperSlideOffset;
1893                        var tx = -offset;
1894                        if (!s.params.virtualTranslate) tx = tx - s.translate;
1895                        var ty = 0;
1896                        if (!isH()) {
1897                            ty = tx;
1898                            tx = 0;
1899                        }
1900                        var slideOpacity = s.params.fade.crossFade ?
1901                                Math.max(1 - Math.abs(slide[0].progress), 0) :
1902                                1 + Math.min(Math.max(slide[0].progress, -1), 0);
1903                        slide
1904                            .css({
1905                                opacity: slideOpacity
1906                            })
1907                            .transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');
1908        
1909                    }
1910                },
1911                setTransition: function (duration) {
1912                    s.slides.transition(duration);
1913                    if (s.params.virtualTranslate && duration !== 0) {
1914                        s.slides.eq(s.activeIndex).transitionEnd(function () {
1915                            var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
1916                            for (var i = 0; i < triggerEvents.length; i++) {
1917                                s.wrapper.trigger(triggerEvents[i]);
1918                            }
1919                        });
1920                    }
1921                }
1922            },
1923            cube: {
1924                setTranslate: function () {
1925                    var wrapperRotate = 0, cubeShadow;
1926                    if (s.params.cube.shadow) {
1927                        if (isH()) {
1928                            cubeShadow = s.wrapper.find('.swiper-cube-shadow');
1929                            if (cubeShadow.length === 0) {
1930                                cubeShadow = $('<div class="swiper-cube-shadow"></div>');
1931                                s.wrapper.append(cubeShadow);
1932                            }
1933                            cubeShadow.css({height: s.width + 'px'});
1934                        }
1935                        else {
1936                            cubeShadow = s.container.find('.swiper-cube-shadow');
1937                            if (cubeShadow.length === 0) {
1938                                cubeShadow = $('<div class="swiper-cube-shadow"></div>');
1939                                s.container.append(cubeShadow);
1940                            }
1941                        }
1942                    }
1943                    for (var i = 0; i < s.slides.length; i++) {
1944                        var slide = s.slides.eq(i);
1945                        var slideAngle = i * 90;
1946                        var round = Math.floor(slideAngle / 360);
1947                        if (s.rtl) {
1948                            slideAngle = -slideAngle;
1949                            round = Math.floor(-slideAngle / 360);
1950                        }
1951                        var progress = Math.max(Math.min(slide[0].progress, 1), -1);
1952                        var tx = 0, ty = 0, tz = 0;
1953                        if (i % 4 === 0) {
1954                            tx = - round * 4 * s.size;
1955                            tz = 0;
1956                        }
1957                        else if ((i - 1) % 4 === 0) {
1958                            tx = 0;
1959                            tz = - round * 4 * s.size;
1960                        }
1961                        else if ((i - 2) % 4 === 0) {
1962                            tx = s.size + round * 4 * s.size;
1963                            tz = s.size;
1964                        }
1965                        else if ((i - 3) % 4 === 0) {
1966                            tx = - s.size;
1967                            tz = 3 * s.size + s.size * 4 * round;
1968                        }
1969                        if (s.rtl) {
1970                            tx = -tx;
1971                        }
1972                        
1973                        if (!isH()) {
1974                            ty = tx;
1975                            tx = 0;
1976                        }
1977                        
1978                        var transform = 'rotateX(' + (isH() ? 0 : -slideAngle) + 'deg) rotateY(' + (isH() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';
1979                        if (progress <= 1 && progress > -1) {
1980                            wrapperRotate = i * 90 + progress * 90;
1981                            if (s.rtl) wrapperRotate = -i * 90 - progress * 90;
1982                        }
1983                        slide.transform(transform);
1984                        if (s.params.cube.slideShadows) {
1985                            //Set shadows
1986                            var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
1987                            var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
1988                            if (shadowBefore.length === 0) {
1989                                shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>');
1990                                slide.append(shadowBefore);
1991                            }
1992                            if (shadowAfter.length === 0) {
1993                                shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>');
1994                                slide.append(shadowAfter);
1995                            }
1996                            var shadowOpacity = slide[0].progress;
1997                            if (shadowBefore.length) shadowBefore[0].style.opacity = -slide[0].progress;
1998                            if (shadowAfter.length) shadowAfter[0].style.opacity = slide[0].progress;
1999                        }
2000                    }
2001                    s.wrapper.css({
2002                        '-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2003                        '-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2004                        '-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
2005                        'transform-origin': '50% 50% -' + (s.size / 2) + 'px'
2006                    });
2007                        
2008                    if (s.params.cube.shadow) {
2009                        if (isH()) {
2010                            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) + ')');
2011                        }
2012                        else {
2013                            var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
2014                            var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
2015                            var scale1 = s.params.cube.shadowScale,
2016                                scale2 = s.params.cube.shadowScale / multiplier,
2017                                offset = s.params.cube.shadowOffset;
2018                            cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');
2019                        }
2020                    }
2021                    var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;
2022                    s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (isH() ? 0 : wrapperRotate) + 'deg) rotateY(' + (isH() ? -wrapperRotate : 0) + 'deg)');
2023                },
2024                setTransition: function (duration) {
2025                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
2026                    if (s.params.cube.shadow && !isH()) {
2027                        s.container.find('.swiper-cube-shadow').transition(duration);
2028                    }
2029                }
2030            },
2031            coverflow: {
2032                setTranslate: function () {
2033                    var transform = s.translate;
2034                    var center = isH() ? -transform + s.width / 2 : -transform + s.height / 2;
2035                    var rotate = isH() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;
2036                    var translate = s.params.coverflow.depth;
2037                    //Each slide offset from center
2038                    for (var i = 0, length = s.slides.length; i < length; i++) {
2039                        var slide = s.slides.eq(i);
2040                        var slideSize = s.slidesSizesGrid[i];
2041                        var slideOffset = slide[0].swiperSlideOffset;
2042                        var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;
2043        
2044                        var rotateY = isH() ? rotate * offsetMultiplier : 0;
2045                        var rotateX = isH() ? 0 : rotate * offsetMultiplier;
2046                        // var rotateZ = 0
2047                        var translateZ = -translate * Math.abs(offsetMultiplier);
2048        
2049                        var translateY = isH() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);
2050                        var translateX = isH() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;
2051        
2052                        //Fix for ultra small values
2053                        if (Math.abs(translateX) < 0.001) translateX = 0;
2054                        if (Math.abs(translateY) < 0.001) translateY = 0;
2055                        if (Math.abs(translateZ) < 0.001) translateZ = 0;
2056                        if (Math.abs(rotateY) < 0.001) rotateY = 0;
2057                        if (Math.abs(rotateX) < 0.001) rotateX = 0;
2058        
2059                        var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px)  rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
2060        
2061                        slide.transform(slideTransform);
2062                        slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
2063                        if (s.params.coverflow.slideShadows) {
2064                            //Set shadows
2065                            var shadowBefore = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
2066                            var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
2067                            if (shadowBefore.length === 0) {
2068                                shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>');
2069                                slide.append(shadowBefore);
2070                            }
2071                            if (shadowAfter.length === 0) {
2072                                shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>');
2073                                slide.append(shadowAfter);
2074                            }
2075                            if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
2076                            if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;
2077                        }
2078                    }
2079        
2080                    //Set correct perspective for IE10
2081                    if (s.browser.ie) {
2082                        var ws = s.wrapper[0].style;
2083                        ws.perspectiveOrigin = center + 'px 50%';
2084                    }
2085                },
2086                setTransition: function (duration) {
2087                    s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
2088                }
2089            }
2090        };
2091
2092        /*=========================
2093          Images Lazy Loading
2094          ===========================*/
2095        s.lazy = {
2096            initialImageLoaded: false,
2097            loadImageInSlide: function (index) {
2098                if (typeof index === 'undefined') return;
2099                if (s.slides.length === 0) return;
2100                
2101                var slide = s.slides.eq(index);
2102                var img = slide.find('img.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');
2103                if (img.length === 0) return;
2104        
2105                img.each(function () {
2106                    var _img = $(this);
2107                    _img.addClass('swiper-lazy-loading');
2108        
2109                    var src = _img.attr('data-src');
2110        
2111                    s.loadImage(_img[0], src, false, function () {
2112                        _img.attr('src', src);
2113                        _img.removeAttr('data-src');
2114                        _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');
2115                        slide.find('.swiper-lazy-preloader, .preloader').remove();
2116        
2117                        s.emit('onLazyImageReady', s, slide[0], _img[0]);
2118                    });
2119                    
2120                    s.emit('onLazyImageLoad', s, slide[0], _img[0]);
2121                });
2122                    
2123            },
2124            load: function () {
2125                if (s.params.watchSlidesVisibility) {
2126                    s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {
2127                        s.lazy.loadImageInSlide($(this).index());
2128                    });
2129                }
2130                else {
2131                    if (s.params.slidesPerView > 1) {
2132                        for (var i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {
2133                            if (s.slides[i]) s.lazy.loadImageInSlide(i);
2134                        }
2135                    }
2136                    else {
2137                        s.lazy.loadImageInSlide(s.activeIndex);    
2138                    }
2139                }
2140                if (s.params.lazyLoadingInPrevNext) {
2141                    var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);
2142                    if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());
2143        
2144                    var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);
2145                    if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());
2146                }
2147            },
2148            onTransitionStart: function () {
2149                if (s.params.lazyLoading) {
2150                    if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {
2151                        s.lazy.initialImageLoaded = true;
2152                        s.lazy.load();
2153                    }
2154                }
2155            },
2156            onTransitionEnd: function () {
2157                if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {
2158                    s.lazy.load();
2159                }
2160            }
2161        };
2162        
2163
2164        /*=========================
2165          Scrollbar
2166          ===========================*/
2167        s.scrollbar = {
2168            set: function () {
2169                if (!s.params.scrollbar) return;
2170                var sb = s.scrollbar;
2171                sb.track = $(s.params.scrollbar);
2172                sb.drag = sb.track.find('.swiper-scrollbar-drag');
2173                if (sb.drag.length === 0) {
2174                    sb.drag = $('<div class="swiper-scrollbar-drag"></div>');
2175                    sb.track.append(sb.drag);
2176                }
2177                sb.drag[0].style.width = '';
2178                sb.drag[0].style.height = '';
2179                sb.trackSize = isH() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;
2180                
2181                sb.divider = s.size / s.virtualSize;
2182                sb.moveDivider = sb.divider * (sb.trackSize / s.size);
2183                sb.dragSize = sb.trackSize * sb.divider;
2184        
2185                if (isH()) {
2186                    sb.drag[0].style.width = sb.dragSize + 'px';
2187                }
2188                else {
2189                    sb.drag[0].style.height = sb.dragSize + 'px';
2190                }
2191        
2192                if (sb.divider >= 1) {
2193                    sb.track[0].style.display = 'none';
2194                }
2195                else {
2196                    sb.track[0].style.display = '';
2197                }
2198                if (s.params.scrollbarHide) {
2199                    sb.track[0].style.opacity = 0;
2200                }
2201            },
2202            setTranslate: function () {
2203                if (!s.params.scrollbar) return;
2204                var diff;
2205                var sb = s.scrollbar;
2206                var translate = s.translate || 0;
2207                var newPos;
2208                
2209                var newSize = sb.dragSize;
2210                newPos = (sb.trackSize - sb.dragSize) * s.progress;
2211                if (s.rtl && isH()) {
2212                    newPos = -newPos;
2213                    if (newPos > 0) {
2214                        newSize = sb.dragSize - newPos;
2215                        newPos = 0;
2216                    }
2217                    else if (-newPos + sb.dragSize > sb.trackSize) {
2218                        newSize = sb.trackSize + newPos;
2219                    }
2220                }
2221                else {
2222                    if (newPos < 0) {
2223                        newSize = sb.dragSize + newPos;
2224                        newPos = 0;
2225                    }
2226                    else if (newPos + sb.dragSize > sb.trackSize) {
2227                        newSize = sb.trackSize - newPos;
2228                    }
2229                }
2230                if (isH()) {
2231                    if (s.support.transforms3d) {
2232                        sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');
2233                    }
2234                    else {
2235                        sb.drag.transform('translateX(' + (newPos) + 'px)');   
2236                    }
2237                    sb.drag[0].style.width = newSize + 'px';
2238                }
2239                else {
2240                    if (s.support.transforms3d) {
2241                        sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');
2242                    }
2243                    else {
2244                        sb.drag.transform('translateY(' + (newPos) + 'px)');   
2245                    }
2246                    sb.drag[0].style.height = newSize + 'px';
2247                }
2248                if (s.params.scrollbarHide) {
2249                    clearTimeout(sb.timeout);
2250                    sb.track[0].style.opacity = 1;
2251                    sb.timeout = setTimeout(function () {
2252                        sb.track[0].style.opacity = 0;
2253                        sb.track.transition(400);
2254                    }, 1000);
2255                }
2256            },
2257            setTransition: function (duration) {
2258                if (!s.params.scrollbar) return;
2259                s.scrollbar.drag.transition(duration);
2260            }
2261        };
2262
2263        /*=========================
2264          Controller
2265          ===========================*/
2266        s.controller = {
2267            setTranslate: function (translate, byController) {
2268                var controlled = s.params.control;
2269                var multiplier, controlledTranslate;
2270                if (s.isArray(controlled)) {
2271                    for (var i = 0; i < controlled.length; i++) {
2272                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
2273                            translate = controlled[i].rtl && controlled[i].params.direction === 'horizontal' ? -s.translate : s.translate;
2274                            multiplier = (controlled[i].maxTranslate() - controlled[i].minTranslate()) / (s.maxTranslate() - s.minTranslate());
2275                            controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled[i].minTranslate();
2276                            if (s.params.controlInverse) {
2277                                controlledTranslate = controlled[i].maxTranslate() - controlledTranslate;
2278                            }
2279                            controlled[i].updateProgress(controlledTranslate);
2280                            controlled[i].setWrapperTranslate(controlledTranslate, false, s);
2281                            controlled[i].updateActiveIndex();
2282                        }
2283                    }
2284                }
2285                else if (controlled instanceof Swiper && byController !== controlled) {
2286                    translate = controlled.rtl && controlled.params.direction === 'horizontal' ? -s.translate : s.translate;
2287                    multiplier = (controlled.maxTranslate() - controlled.minTranslate()) / (s.maxTranslate() - s.minTranslate());
2288                    controlledTranslate = (translate - s.minTranslate()) * multiplier + controlled.minTranslate();
2289                    if (s.params.controlInverse) {
2290                        controlledTranslate = controlled.maxTranslate() - controlledTranslate;
2291                    }
2292                    controlled.updateProgress(controlledTranslate);
2293                    controlled.setWrapperTranslate(controlledTranslate, false, s);
2294                    controlled.updateActiveIndex();
2295                }
2296            },
2297            setTransition: function (duration, byController) {
2298                var controlled = s.params.control;
2299                if (s.isArray(controlled)) {
2300                    for (var i = 0; i < controlled.length; i++) {
2301                        if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
2302                            controlled[i].setWrapperTransition(duration, s);
2303                        }
2304                    }
2305                }
2306                else if (controlled instanceof Swiper && byController !== controlled) {
2307                    controlled.setWrapperTransition(duration, s);
2308                }
2309            }
2310        };
2311
2312        /*=========================
2313          Hash Navigation
2314          ===========================*/
2315        s.hashnav = {
2316            init: function () {
2317                if (!s.params.hashnav) return;
2318                s.hashnav.initialized = true;
2319                var hash = document.location.hash.replace('#', '');
2320                if (!hash) return;
2321                var speed = 0;
2322                for (var i = 0, length = s.slides.length; i < length; i++) {
2323                    var slide = s.slides.eq(i);
2324                    var slideHash = slide.attr('data-hash');
2325                    if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {
2326                        var index = slide.index();
2327                        s.slideTo(index, speed, s.params.runCallbacksOnInit, true);
2328                    }
2329                }
2330            },
2331            setHash: function () {
2332                if (!s.hashnav.initialized || !s.params.hashnav) return;
2333                document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';
2334            }
2335        };
2336
2337        /*=========================
2338          Keyboard Control
2339          ===========================*/
2340        function handleKeyboard(e) {
2341            if (e.originalEvent) e = e.originalEvent; //jquery fix
2342            var kc = e.keyCode || e.charCode;
2343            if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
2344                return;
2345            }
2346            if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {
2347                return;
2348            }
2349            if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
2350                var inView = false;
2351                //Check that swiper should be inside of visible area of window
2352                if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {
2353                    return;
2354                }
2355                var windowScroll = {
2356                    left: window.pageXOffset,
2357                    top: window.pageYOffset
2358                };
2359                var windowWidth = window.innerWidth;
2360                var windowHeight = window.innerHeight;
2361                var swiperOffset = s.container.offset();
2362                
2363                var swiperCoord = [
2364                    [swiperOffset.left, swiperOffset.top],
2365                    [swiperOffset.left + s.width, swiperOffset.top],
2366                    [swiperOffset.left, swiperOffset.top + s.height],
2367                    [swiperOffset.left + s.width, swiperOffset.top + s.height]
2368                ];
2369                for (var i = 0; i < swiperCoord.length; i++) {
2370                    var point = swiperCoord[i];
2371                    if (
2372                        point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&
2373                        point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight
2374                    ) {
2375                        inView = true;
2376                    }
2377        
2378                }
2379                if (!inView) return;
2380            }
2381            if (isH()) {
2382                if (kc === 37 || kc === 39) {
2383                    if (e.preventDefault) e.preventDefault();
2384                    else e.returnValue = false;
2385                }
2386                if (kc === 39) s.slideNext();
2387                if (kc === 37) s.slidePrev();
2388            }
2389            else {
2390                if (kc === 38 || kc === 40) {
2391                    if (e.preventDefault) e.preventDefault();
2392                    else e.returnValue = false;
2393                }
2394                if (kc === 40) s.slideNext();
2395                if (kc === 38) s.slidePrev();
2396            }
2397        }
2398        s.disableKeyboardControl = function () {
2399            $(document).off('keydown', handleKeyboard);
2400        };
2401        s.enableKeyboardControl = function () {
2402            $(document).on('keydown', handleKeyboard);
2403        };
2404        
2405
2406        /*=========================
2407          Mousewheel Control
2408          ===========================*/
2409        s._wheelEvent = false;
2410        s._lastWheelScrollTime = (new Date()).getTime();
2411        if (s.params.mousewheelControl) {
2412            if (document.onmousewheel !== undefined) {
2413                s._wheelEvent = 'mousewheel';
2414            }
2415            if (!s._wheelEvent) {
2416                try {
2417                    new WheelEvent('wheel');
2418                    s._wheelEvent = 'wheel';
2419                } catch (e) {}
2420            }
2421            if (!s._wheelEvent) {
2422                s._wheelEvent = 'DOMMouseScroll';
2423            }
2424        }
2425        function handleMousewheel(e) {
2426            if (e.originalEvent) e = e.originalEvent; //jquery fix
2427            var we = s._wheelEvent;
2428            var delta = 0;
2429            //Opera & IE
2430            if (e.detail) delta = -e.detail;
2431            //WebKits
2432            else if (we === 'mousewheel') {
2433                if (s.params.mousewheelForceToAxis) {
2434                    if (isH()) {
2435                        if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX;
2436                        else return;
2437                    }
2438                    else {
2439                        if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;
2440                        else return;
2441                    }
2442                }
2443                else {
2444                    delta = e.wheelDelta;
2445                }
2446            }
2447            //Old FireFox
2448            else if (we === 'DOMMouseScroll') delta = -e.detail;
2449            //New FireFox
2450            else if (we === 'wheel') {
2451                if (s.params.mousewheelForceToAxis) {
2452                    if (isH()) {
2453                        if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX;
2454                        else return;
2455                    }
2456                    else {
2457                        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;
2458                        else return;
2459                    }
2460                }
2461                else {
2462                    delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX : - e.deltaY;
2463                }
2464            }
2465        
2466            if (!s.params.freeMode) {
2467                if ((new Date()).getTime() - s._lastWheelScrollTime > 60) {
2468                    if (delta < 0) s.slideNext();
2469                    else s.slidePrev();
2470                }
2471                s._lastWheelScrollTime = (new Date()).getTime();
2472        
2473            }
2474            else {
2475                //Freemode or scrollContainer:
2476                var position = s.getWrapperTranslate() + delta;
2477        
2478                if (position > 0) position = 0;
2479                if (position < s.maxTranslate()) position = s.maxTranslate();
2480        
2481                s.setWrapperTransition(0);
2482                s.setWrapperTranslate(position);
2483                s.updateProgress();
2484                s.updateActiveIndex();
2485        
2486                // Return page scroll on edge positions
2487                if (position === 0 || position === s.maxTranslate()) return;
2488            }
2489            if (s.params.autoplay) s.stopAutoplay();
2490        
2491            if (e.preventDefault) e.preventDefault();
2492            else e.returnValue = false;
2493            return false;
2494        }
2495        s.disableMousewheelControl = function () {
2496            if (!s._wheelEvent) return false;
2497            s.container.off(s._wheelEvent, handleMousewheel);
2498            return true;
2499        };
2500        
2501        s.enableMousewheelControl = function () {
2502            if (!s._wheelEvent) return false;
2503            s.container.on(s._wheelEvent, handleMousewheel);
2504            return true;
2505        };
2506
2507        /*=========================
2508          Parallax
2509          ===========================*/
2510        function setParallaxTransform(el, progress) {
2511            el = $(el);
2512            var p, pX, pY;
2513            
2514            p = el.attr('data-swiper-parallax') || '0';
2515            pX = el.attr('data-swiper-parallax-x');
2516            pY = el.attr('data-swiper-parallax-y');
2517            if (pX || pY) {
2518                pX = pX || '0';
2519                pY = pY || '0';
2520            }
2521            else {
2522                if (isH()) {
2523                    pX = p;
2524                    pY = '0';
2525                }
2526                else {
2527                    pY = p;
2528                    pX = '0';
2529                }
2530            }
2531            if ((pX).indexOf('%') >= 0) {
2532                pX = parseInt(pX, 10) * progress + '%';
2533            }
2534            else {
2535                pX = pX * progress + 'px' ;
2536            }
2537            if ((pY).indexOf('%') >= 0) {
2538                pY = parseInt(pY, 10) * progress + '%';
2539            }
2540            else {
2541                pY = pY * progress + 'px' ;
2542            }
2543            el.transform('translate3d(' + pX + ', ' + pY + ',0px)');
2544        }   
2545        s.parallax = {
2546            setTranslate: function () {
2547                s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
2548                    setParallaxTransform(this, s.progress);
2549                    
2550                });
2551                s.slides.each(function () {
2552                    var slide = $(this);
2553                    slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {
2554                        var progress = Math.min(Math.max(slide[0].progress, -1), 1);
2555                        setParallaxTransform(this, progress);
2556                    });
2557                });
2558            },
2559            setTransition: function (duration) {
2560                if (typeof duration === 'undefined') duration = s.params.speed;
2561                s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
2562                    var el = $(this);
2563                    var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;
2564                    if (duration === 0) parallaxDuration = 0;
2565                    el.transition(parallaxDuration);
2566                });
2567            }
2568        };
2569        
2570
2571        /*=========================
2572          Plugins API. Collect all and init all plugins
2573          ===========================*/
2574        s._plugins = [];
2575        for (var plugin in s.plugins) {
2576            var p = s.plugins[plugin](s, s.params[plugin]);
2577            if (p) s._plugins.push(p);
2578        }
2579        // Method to call all plugins event/method
2580        s.callPlugins = function (eventName) {
2581            for (var i = 0; i < s._plugins.length; i++) {
2582                if (eventName in s._plugins[i]) {
2583                    s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
2584                }
2585            }
2586        };
2587
2588        /*=========================
2589          Events/Callbacks/Plugins Emitter
2590          ===========================*/
2591        function normalizeEventName (eventName) {
2592            if (eventName.indexOf('on') !== 0) {
2593                if (eventName[0] !== eventName[0].toUpperCase()) {
2594                    eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);
2595                }
2596                else {
2597                    eventName = 'on' + eventName;
2598                }
2599            }
2600            return eventName;
2601        }
2602        s.emitterEventListeners = {
2603        
2604        };
2605        s.emit = function (eventName) {
2606            // Trigger callbacks
2607            if (s.params[eventName]) {
2608                s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
2609            }
2610            var i;
2611            // Trigger events
2612            if (s.emitterEventListeners[eventName]) {
2613                for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
2614                    s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
2615                }
2616            }
2617            // Trigger plugins
2618            if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
2619        };
2620        s.on = function (eventName, handler) {
2621            eventName = normalizeEventName(eventName);
2622            if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];
2623            s.emitterEventListeners[eventName].push(handler);
2624            return s;
2625        };
2626        s.off = function (eventName, handler) {
2627            var i;
2628            eventName = normalizeEventName(eventName);
2629            if (typeof handler === 'undefined') {
2630                // Remove all handlers for such event
2631                s.emitterEventListeners[eventName] = [];
2632                return s;
2633            }
2634            if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;
2635            for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
2636                if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);
2637            }
2638            return s;
2639        };
2640        s.once = function (eventName, handler) {
2641            eventName = normalizeEventName(eventName);
2642            var _handler = function () {
2643                handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
2644                s.off(eventName, _handler);
2645            };
2646            s.on(eventName, _handler);
2647            return s;
2648        };
2649
2650        // Accessibility tools
2651        s.a11y = {
2652            makeFocusable: function ($el) {
2653                $el[0].tabIndex = '0';
2654                return $el;
2655            },
2656            addRole: function ($el, role) {
2657                $el.attr('role', role);
2658                return $el;
2659            },
2660        
2661            addLabel: function ($el, label) {
2662                $el.attr('aria-label', label);
2663                return $el;
2664            },
2665        
2666            disable: function ($el) {
2667                $el.attr('aria-disabled', true);
2668                return $el;
2669            },
2670        
2671            enable: function ($el) {
2672                $el.attr('aria-disabled', false);
2673                return $el;
2674            },
2675        
2676            onEnterKey: function (event) {
2677                if (event.keyCode !== 13) return;
2678                if ($(event.target).is(s.params.nextButton)) {
2679                    s.onClickNext(event);
2680                    if (s.isEnd) {
2681                        s.a11y.notify(s.params.lastSlideMsg);
2682                    }
2683                    else {
2684                        s.a11y.notify(s.params.nextSlideMsg);
2685                    }
2686                }
2687                else if ($(event.target).is(s.params.prevButton)) {
2688                    s.onClickPrev(event);
2689                    if (s.isBeginning) {
2690                        s.a11y.notify(s.params.firstSlideMsg);
2691                    }
2692                    else {
2693                        s.a11y.notify(s.params.prevSlideMsg);
2694                    }
2695                }
2696            },
2697        
2698            liveRegion: $('<span class="swiper-notification" aria-l
2698ive="assertive" aria-atomic="true"></span>'),
2699        
2700            notify: function (message) {
2701                var notification = s.a11y.liveRegion;
2702                if (notification.length === 0) return;
2703                notification.html('');
2704                notification.html(message);
2705            },
2706            init: function () {
2707                // Setup accessibility
2708                if (s.params.nextButton) {
2709                    var nextButton = $(s.params.nextButton);
2710                    s.a11y.makeFocusable(nextButton);
2711                    s.a11y.addRole(nextButton, 'button');
2712                    s.a11y.addLabel(nextButton, s.params.nextSlideMsg);
2713                }
2714                if (s.params.prevButton) {
2715                    var prevButton = $(s.params.prevButton);
2716                    s.a11y.makeFocusable(prevButton);
2717                    s.a11y.addRole(prevButton, 'button');
2718                    s.a11y.addLabel(prevButton, s.params.prevSlideMsg);
2719                }
2720        
2721                $(s.container).append(s.a11y.liveRegion);
2722            },
2723            destroy: function () {
2724                if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();
2725            }
2726        };
2727        
2728
2729        /*=========================
2730          Init/Destroy
2731          ===========================*/
2732        s.init = function () {
2733            if (s.params.loop) s.createLoop();
2734            s.updateContainerSize();
2735            s.updateSlidesSize();
2736            s.updatePagination();
2737            if (s.params.scrollbar && s.scrollbar) {
2738                s.scrollbar.set();
2739            }
2740            if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
2741                if (!s.params.loop) s.updateProgress();
2742                s.effects[s.params.effect].setTranslate();
2743            }
2744            if (s.params.loop) {
2745                s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);
2746            }
2747            else {
2748                s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);
2749                if (s.params.initialSlide === 0) {
2750                    if (s.parallax && s.params.parallax) s.parallax.setTranslate();
2751                    if (s.lazy && s.params.lazyLoading) s.lazy.load();
2752                }
2753            }
2754            s.attachEvents();
2755            if (s.params.observer && s.support.observer) {
2756                s.initObservers();
2757            }
2758            if (s.params.preloadImages && !s.params.lazyLoading) {
2759                s.preloadImages();
2760            }
2761            if (s.params.autoplay) {
2762                s.startAutoplay();
2763            }
2764            if (s.params.keyboardControl) {
2765                if (s.enableKeyboardControl) s.enableKeyboardControl();
2766            }
2767            if (s.params.mousewheelControl) {
2768                if (s.enableMousewheelControl) s.enableMousewheelControl();
2769            }
2770            if (s.params.hashnav) {
2771                if (s.hashnav) s.hashnav.init();
2772            }
2773            if (s.params.a11y && s.a11y) s.a11y.init();
2774            s.emit('onInit', s);
2775        };
2776        
2777        // Destroy
2778        s.destroy = function (deleteInstance) {
2779            s.detachEvents();
2780            s.disconnectObservers();
2781            if (s.params.keyboardControl) {
2782                if (s.disableKeyboardControl) s.disableKeyboardControl();
2783            }
2784            if (s.params.mousewheelControl) {
2785                if (s.disableMousewheelControl) s.disableMousewheelControl();
2786            }
2787            if (s.params.a11y && s.a11y) s.a11y.destroy();
2788            s.emit('onDestroy');
2789            if (deleteInstance !== false) s = null;
2790        };
2791        
2792        s.init();
2793        
2794        
2795
2796        
2797        // Return swiper instance
2798        return s;
2799    };
2800    
2801
2802    /*==================================================
2803        Prototype
2804    ====================================================*/
2805    Swiper.prototype = {
2806        isSafari: (function () {
2807            var ua = navigator.userAgent.toLowerCase();
2808            return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);
2809        })(),
2810        isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),
2811        isArray: function (arr) {
2812            return Object.prototype.toString.apply(arr) === '[object Array]';
2813        },
2814        /*==================================================
2815        Browser
2816        ====================================================*/
2817        browser: {
2818            ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
2819            ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1),
2820        },
2821        /*==================================================
2822        Devices
2823        ====================================================*/
2824        device: (function () {
2825            var ua = navigator.userAgent;
2826            var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
2827            var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
2828            var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
2829            var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
2830            return {
2831                ios: ipad || iphone || ipad,
2832                android: android
2833            };
2834        })(),
2835        /*==================================================
2836        Feature Detection
2837        ====================================================*/
2838        support: {
2839            touch : (window.Modernizr && Modernizr.touch === true) || (function () {
2840                return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
2841            })(),
2842    
2843            transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
2844                var div = document.createElement('div').style;
2845                return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
2846            })(),
2847    
2848            flexbox: (function () {
2849                var div = document.createElement('div').style;
2850                var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
2851                for (var i = 0; i < styles.length; i++) {
2852                    if (styles[i] in div) return true;
2853                }
2854            })(),
2855    
2856            observer: (function () {
2857                return ('MutationObserver' in window || 'WebkitMutationObserver' in window);
2858            })()
2859        },
2860        /*==================================================
2861        Plugins
2862        ====================================================*/
2863        plugins: {}
2864    };
2865    
2866
2867    /*===========================
2868    Dom7 Library
2869    ===========================*/
2870    var Dom7 = (function () {
2871        var Dom7 = function (arr) {
2872            var _this = this, i = 0;
2873            // Create array-like object
2874            for (i = 0; i < arr.length; i++) {
2875                _this[i] = arr[i];
2876            }
2877            _this.length = arr.length;
2878            // Return collection with methods
2879            return this;
2880        };
2881        var $ = function (selector, context) {
2882            var arr = [], i = 0;
2883            if (selector && !context) {
2884                if (selector instanceof Dom7) {
2885                    return selector;
2886                }
2887            }
2888            if (selector) {
2889                // String
2890                if (typeof selector === 'string') {
2891                    var els, tempParent, html = selector.trim();
2892                    if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
2893                        var toCreate = 'div';
2894                        if (html.indexOf('<li') === 0) toCreate = 'ul';
2895                        if (html.indexOf('<tr') === 0) toCreate = 'tbody';
2896                        if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';
2897                        if (html.indexOf('<tbody') === 0) toCreate = 'table';
2898                        if (html.indexOf('<option') === 0) toCreate = 'select';
2899                        tempParent = document.createElement(toCreate);
2900                        tempParent.innerHTML = selector;
2901                        for (i = 0; i < tempParent.childNodes.length; i++) {
2902                            arr.push(tempParent.childNodes[i]);
2903                        }
2904                    }
2905                    else {
2906                        if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {
2907                            // Pure ID selector
2908                            els = [document.getElementById(selector.split('#')[1])];
2909                        }
2910                        else {
2911                            // Other selectors
2912                            els = (context || document).querySelectorAll(selector);
2913                        }
2914                        for (i = 0; i < els.length; i++) {
2915                            if (els[i]) arr.push(els[i]);
2916                        }
2917                    }
2918                }
2919                // Node/element
2920                else if (selector.nodeType || selector === window || selector === document) {
2921                    arr.push(selector);
2922                }
2923                //Array of elements or instance of Dom
2924                else if (selector.length > 0 && selector[0].nodeType) {
2925                    for (i = 0; i < selector.length; i++) {
2926                        arr.push(selector[i]);
2927                    }
2928                }
2929            }
2930            return new Dom7(arr);
2931        };
2932        Dom7.prototype = {
2933            // Classes and attriutes
2934            addClass: function (className) {
2935                if (typeof className === 'undefined') {
2936                    return this;
2937                }
2938                var classes = className.split(' ');
2939                for (var i = 0; i < classes.length; i++) {
2940                    for (var j = 0; j < this.length; j++) {
2941                    		//pagenation error under ie9
2942                    		try{
2943                         		this[j].classList.add(classes[i]);
2944                       	} catch(e){}
2945                    }
2946                }
2947                return this;
2948            },
2949            removeClass: function (className) {
2950                var classes = className.split(' ');
2951                for (var i = 0; i < classes.length; i++) {
2952                    for (var j = 0; j < this.length; j++) {
2953                    		//pagenation error under ie9
2954                    		try{
2955                         		this[j].classList.remove(classes[i]);
2956                       	} catch(e){}
2957                    }
2958                }
2959                return this;
2960            },
2961            hasClass: function (className) {
2962                if (!this[0]) return false;
2963                else return this[0].classList.contains(className);
2964            },
2965            toggleClass: function (className) {
2966                var classes = className.split(' ');
2967                for (var i = 0; i < classes.length; i++) {
2968                    for (var j = 0; j < this.length; j++) {
2969                        this[j].classList.toggle(classes[i]);
2970                    }
2971                }
2972                return this;
2973            },
2974            attr: function (attrs, value) {
2975                if (arguments.length === 1 && typeof attrs === 'string') {
2976                    // Get attr
2977                    if (this[0]) return this[0].getAttribute(attrs);
2978                    else return undefined;
2979                }
2980                else {
2981                    // Set attrs
2982                    for (var i = 0; i < this.length; i++) {
2983                        if (arguments.length === 2) {
2984                            // String
2985                            this[i].setAttribute(attrs, value);
2986                        }
2987                        else {
2988                            // Object
2989                            for (var attrName in attrs) {
2990                                this[i][attrName] = attrs[attrName];
2991                                this[i].setAttribute(attrName, attrs[attrName]);
2992                            }
2993                        }
2994                    }
2995                    return this;
2996                }
2997            },
2998            removeAttr: function (attr) {
2999                for (var i = 0; i < this.length; i++) {
3000                    this[i].removeAttribute(attr);
3001                }
3002            },
3003            data: function (key, value) {
3004                if (typeof value === 'undefined') {
3005                    // Get value
3006                    if (this[0]) {
3007                        var dataKey = this[0].getAttribute('data-' + key);
3008                        if (dataKey) return dataKey;
3009                        else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];
3010                        else return undefined;
3011                    }
3012                    else return undefined;
3013                }
3014                else {
3015                    // Set value
3016                    for (var i = 0; i < this.length; i++) {
3017                        var el = this[i];
3018                        if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};
3019                        el.dom7ElementDataStorage[key] = value;
3020                    }
3021                    return this;
3022                }
3023            },
3024            // Transforms
3025            transform : function (transform) {
3026                for (var i = 0; i < this.length; i++) {
3027                    var elStyle = this[i].style;
3028                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;
3029                }
3030                return this;
3031            },
3032            transition: function (duration) {
3033                if (typeof duration !== 'string') {
3034                    duration = duration + 'ms';
3035                }
3036                for (var i = 0; i < this.length; i++) {
3037                    var elStyle = this[i].style;
3038                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;
3039                }
3040                return this;
3041            },
3042            //Events
3043            on: function (eventName, targetSelector, listener, capture) {
3044                function handleLiveEvent(e) {
3045                    var target = e.target;
3046                    if ($(target).is(targetSelector)) listener.call(target, e);
3047                    else {
3048                        var parents = $(target).parents();
3049                        for (var k = 0; k < parents.length; k++) {
3050                            if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);
3051                        }
3052                    }
3053                }
3054                var events = eventName.split(' ');
3055                var i, j;
3056                for (i = 0; i < this.length; i++) {
3057                    if (typeof targetSelector === 'function' || targetSelector === false) {
3058                        // Usual events
3059                        if (typeof targetSelector === 'function') {
3060                            listener = arguments[1];
3061                            capture = arguments[2] || false;
3062                        }
3063                        for (j = 0; j < events.length; j++) {
3064                            this[i].addEventListener(events[j], listener, capture);
3065                        }
3066                    }
3067                    else {
3068                        //Live events
3069                        for (j = 0; j < events.length; j++) {
3070                            if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];
3071                            this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});
3072                            this[i].addEventListener(events[j], handleLiveEvent, capture);
3073                        }
3074                    }
3075                }
3076    
3077                return this;
3078            },
3079            off: function (eventName, targetSelector, listener, capture) {
3080                var events = eventName.split(' ');
3081                for (var i = 0; i < events.length; i++) {
3082                    for (var j = 0; j < this.length; j++) {
3083                        if (typeof targetSelector === 'function' || targetSelector === false) {
3084                            // Usual events
3085                            if (typeof targetSelector === 'function') {
3086                                listener = arguments[1];
3087                                capture = arguments[2] || false;
3088                            }
3089                            this[j].removeEventListener(events[i], listener, capture);
3090                        }
3091                        else {
3092                            // Live event
3093                            if (this[j].dom7LiveListeners) {
3094                                for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {
3095                                    if (this[j].dom7LiveListeners[k].listener === listener) {
3096                                        this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);
3097                                    }
3098                                }
3099                            }
3100                        }
3101                    }
3102                }
3103                return this;
3104            },
3105            once: function (eventName, targetSelector, listener, capture) {
3106                var dom = this;
3107                if (typeof targetSelector === 'function') {
3108                    targetSelector = false;
3109                    listener = arguments[1];
3110                    capture = arguments[2];
3111                }
3112                function proxy(e) {
3113                    listener(e);
3114                    dom.off(eventName, targetSelector, proxy, capture);
3115                }
3116                dom.on(eventName, targetSelector, proxy, capture);
3117            },
3118            trigger: function (eventName, eventData) {
3119                for (var i = 0; i < this.length; i++) {
3120                    var evt;
3121                    try {
3122                        evt = new CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});
3123                    }
3124                    catch (e) {
3125                        evt = document.createEvent('Event');
3126                        evt.initEvent(eventName, true, true);
3127                        evt.detail = eventData;
3128                    }
3129                    this[i].dispatchEvent(evt);
3130                }
3131                return this;
3132            },
3133            transitionEnd: function (callback) {
3134                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
3135                    i, j, dom = this;
3136                function fireCallBack(e) {
3137                    /*jshint validthis:true */
3138                    if (e.target !== this) return;
3139                    callback.call(this, e);
3140                    for (i = 0; i < events.length; i++) {
3141                        dom.off(events[i], fireCallBack);
3142                    }
3143                }
3144                if (callback) {
3145                    for (i = 0; i < events.length; i++) {
3146                        dom.on(events[i], fireCallBack);
3147                    }
3148                }
3149                return this;
3150            },
3151            // Sizing/Styles
3152            width: function () {
3153                if (this[0] === window) {
3154                    return window.innerWidth;
3155                }
3156                else {
3157                    if (this.length > 0) {
3158                        return parseFloat(this.css('width'));
3159                    }
3160                    else {
3161                        return null;
3162                    }
3163                }
3164            },
3165            outerWidth: function (includeMargins) {
3166                if (this.length > 0) {
3167                    if (includeMargins)
3168                        return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('margin-left'));
3169                    else
3170                        return this[0].offsetWidth;
3171                }
3172                else return null;
3173            },
3174            height: function () {
3175                if (this[0] === window) {
3176                    return window.innerHeight;
3177                }
3178                else {
3179                    if (this.length > 0) {
3180                        return parseFloat(this.css('height'));
3181                    }
3182                    else {
3183                        return null;
3184                    }
3185                }
3186            },
3187            outerHeight: function (includeMargins) {
3188                if (this.length > 0) {
3189                    if (includeMargins)
3190                        return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('margin-bottom'));
3191                    else
3192                        return this[0].offsetHeight;
3193                }
3194                else return null;
3195            },
3196            offset: function () {
3197                if (this.length > 0) {
3198                    var el = this[0];
3199                    var box = el.getBoundingClientRect();
3200                    var body = document.body;
3201                    var clientTop  = el.clientTop  || body.clientTop  || 0;
3202                    var clientLeft = el.clientLeft || body.clientLeft || 0;
3203                    var scrollTop  = window.pageYOffset || el.scrollTop;
3204                    var scrollLeft = window.pageXOffset || el.scrollLeft;
3205                    return {
3206                        top: box.top  + scrollTop  - clientTop,
3207                        left: box.left + scrollLeft - clientLeft
3208                    };
3209                }
3210                else {
3211                    return null;
3212                }
3213            },
3214            css: function (props, value) {
3215                var i;
3216                if (arguments.length === 1) {
3217                    if (typeof props === 'string') {
3218                        if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);
3219                    }
3220                    else {
3221                        for (i = 0; i < this.length; i++) {
3222                            for (var prop in props) {
3223                                this[i].style[prop] = props[prop];
3224                            }
3225                        }
3226                        return this;
3227                    }
3228                }
3229                if (arguments.length === 2 && typeof props === 'string') {
3230                    for (i = 0; i < this.length; i++) {
3231                        this[i].style[props] = value;
3232                    }
3233                    return this;
3234                }
3235                return this;
3236            },
3237            
3238            //Dom manipulation
3239            each: function (callback) {
3240                for (var i = 0; i < this.length; i++) {
3241                    callback.call(this[i], i, this[i]);
3242                }
3243                return this;
3244            },
3245            html: function (html) {
3246                if (typeof html === 'undefined') {
3247                    return this[0] ? this[0].innerHTML : undefined;
3248                }
3249                else {
3250                    for (var i = 0; i < this.length; i++) {
3251                        this[i].innerHTML = html;
3252                    }
3253                    return this;
3254                }
3255            },
3256            is: function (selector) {
3257                if (!this[0]) return false;
3258                var compareWith, i;
3259                if (typeof selector === 'string') {
3260                    var el = this[0];
3261                    if (el === document) return selector === document;
3262                    if (el === window) return selector === window;
3263    
3264                    if (el.matches) return el.matches(selector);
3265                    else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);
3266                    else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);
3267                    else if (el.msMatchesSelector) return el.msMatchesSelector(selector);
3268                    else {
3269                        compareWith = $(selector);
3270                        for (i = 0; i < compareWith.length; i++) {
3271                            if (compareWith[i] === this[0]) return true;
3272                        }
3273                        return false;
3274                    }
3275                }
3276                else if (selector === document) return this[0] === document;
3277                else if (selector === window) return this[0] === window;
3278                else {
3279                    if (selector.nodeType || selector instanceof Dom7) {
3280                        compareWith = selector.nodeType ? [selector] : selector;
3281                        for (i = 0; i < compareWith.length; i++) {
3282                            if (compareWith[i] === this[0]) return true;
3283                        }
3284                        return false;
3285                    }
3286                    return false;
3287                }
3288                
3289            },
3290            index: function () {
3291                if (this[0]) {
3292                    var child = this[0];
3293                    var i = 0;
3294                    while ((child = child.previousSibling) !== null) {
3295                        if (child.nodeType === 1) i++;
3296                    }
3297                    return i;
3298                }
3299                else return undefined;
3300            },
3301            eq: function (index) {
3302                if (typeof index === 'undefined') return this;
3303                var length = this.length;
3304                var returnIndex;
3305                if (index > length - 1) {
3306                    return new Dom7([]);
3307                }
3308                if (index < 0) {
3309                    returnIndex = length + index;
3310                    if (returnIndex < 0) return new Dom7([]);
3311                    else return new Dom7([this[returnIndex]]);
3312                }
3313                return new Dom7([this[index]]);
3314            },
3315            append: function (newChild) {
3316                var i, j;
3317                for (i = 0; i < this.length; i++) {
3318                    if (typeof newChild === 'string') {
3319                        var tempDiv = document.createElement('div');
3320                        tempDiv.innerHTML = newChild;
3321                        while (tempDiv.firstChild) {
3322                            this[i].appendChild(tempDiv.firstChild);
3323                        }
3324                    }
3325                    else if (newChild instanceof Dom7) {
3326                        for (j = 0; j < newChild.length; j++) {
3327                            this[i].appendChild(newChild[j]);
3328                        }
3329                    }
3330                    else {
3331                        this[i].appendChild(newChild);
3332                    }
3333                }
3334                return this;
3335            },
3336            prepend: function (newChild) {
3337                var i, j;
3338                for (i = 0; i < this.length; i++) {
3339                    if (typeof newChild === 'string') {
3340                        var tempDiv = document.createElement('div');
3341                        tempDiv.innerHTML = newChild;
3342                        for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {
3343                            this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
3344                        }
3345                        // this[i].insertAdjacentHTML('afterbegin', newChild);
3346                    }
3347                    else if (newChild instanceof Dom7) {
3348                        for (j = 0; j < newChild.length; j++) {
3349                            this[i].insertBefore(newChild[j], this[i].childNodes[0]);
3350                        }
3351                    }
3352                    else {
3353                        this[i].insertBefore(newChild, this[i].childNodes[0]);
3354                    }
3355                }
3356                return this;
3357            },
3358            insertBefore: function (selector) {
3359                var before = $(selector);
3360                for (var i = 0; i < this.length; i++) {
3361                    if (before.length === 1) {
3362                        before[0].parentNode.insertBefore(this[i], before[0]);
3363                    }
3364                    else if (before.length > 1) {
3365                        for (var j = 0; j < before.length; j++) {
3366                            before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
3367                        }
3368                    }
3369                }
3370            },
3371            insertAfter: function (selector) {
3372                var after = $(selector);
3373                for (var i = 0; i < this.length; i++) {
3374                    if (after.length === 1) {
3375                        after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
3376                    }
3377                    else if (after.length > 1) {
3378                        for (var j = 0; j < after.length; j++) {
3379                            after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
3380                        }
3381                    }
3382                }
3383            },
3384            next: function (selector) {
3385                if (this.length > 0) {
3386                    if (selector) {
3387                        if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);
3388                        else return new Dom7([]);
3389                    }
3390                    else {
3391                        if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);
3392                        else return new Dom7([]);
3393                    }
3394                }
3395                else return new Dom7([]);
3396            },
3397            nextAll: function (selector) {
3398                var nextEls = [];
3399                var el = this[0];
3400                if (!el) return new Dom7([]);
3401                while (el.nextElementSibling) {
3402                    var next = el.nextElementSibling;
3403                    if (selector) {
3404                        if($(next).is(selector)) nextEls.push(next);
3405                    }
3406                    else nextEls.push(next);
3407                    el = next;
3408                }
3409                return new Dom7(nextEls);
3410            },
3411            prev: function (selector) {
3412                if (this.length > 0) {
3413                    if (selector) {
3414                        if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);
3415                        else return new Dom7([]);
3416                    }
3417                    else {
3418                        if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);
3419                        else return new Dom7([]);
3420                    }
3421                }
3422                else return new Dom7([]);
3423            },
3424            prevAll: function (selector) {
3425                var prevEls = [];
3426                var el = this[0];
3427                if (!el) return new Dom7([]);
3428                while (el.previousElementSibling) {
3429                    var prev = el.previousElementSibling;
3430                    if (selector) {
3431                        if($(prev).is(selector)) prevEls.push(prev);
3432                    }
3433                    else prevEls.push(prev);
3434                    el = prev;
3435                }
3436                return new Dom7(prevEls);
3437            },
3438            parent: function (selector) {
3439                var parents = [];
3440                for (var i = 0; i < this.length; i++) {
3441                    if (selector) {
3442                        if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);
3443                    }
3444                    else {
3445                        parents.push(this[i].parentNode);
3446                    }
3447                }
3448                return $($.unique(parents));
3449            },
3450            parents: function (selector) {
3451                var parents = [];
3452                for (var i = 0; i < this.length; i++) {
3453                    var parent = this[i].parentNode;
3454                    while (parent) {
3455                        if (selector) {
3456                            if ($(parent).is(selector)) parents.push(parent);
3457                        }
3458                        else {
3459                            parents.push(parent);
3460                        }
3461                        parent = parent.parentNode;
3462                    }
3463                }
3464                return $($.unique(parents));
3465            },
3466            find : function (selector) {
3467                var foundElements = [];
3468                for (var i = 0; i < this.length; i++) {
3469                    var found = this[i].querySelectorAll(selector);
3470                    for (var j = 0; j < found.length; j++) {
3471                        foundElements.push(found[j]);
3472                    }
3473                }
3474                return new Dom7(foundElements);
3475            },
3476            children: function (selector) {
3477                var children = [];
3478                for (var i = 0; i < this.length; i++) {
3479                    var childNodes = this[i].childNodes;
3480    
3481                    for (var j = 0; j < childNodes.length; j++) {
3482                        if (!selector) {
3483                            if (childNodes[j].nodeType === 1) children.push(childNodes[j]);
3484                        }
3485                        else {
3486                            if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);
3487                        }
3488                    }
3489                }
3490                return new Dom7($.unique(children));
3491            },
3492            remove: function () {
3493                for (var i = 0; i < this.length; i++) {
3494                    if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);
3495                }
3496                return this;
3497            },
3498            add: function () {
3499                var dom = this;
3500                var i, j;
3501                for (i = 0; i < arguments.length; i++) {
3502                    var toAdd = $(arguments[i]);
3503                    for (j = 0; j < toAdd.length; j++) {
3504                        dom[dom.length] = toAdd[j];
3505                        dom.length++;
3506                    }
3507                }
3508                return dom;
3509            }
3510        };
3511        $.fn = Dom7.prototype;
3512        $.unique = function (arr) {
3513            var unique = [];
3514            for (var i = 0; i < arr.length; i++) {
3515                if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);
3516            }
3517            return unique;
3518        };
3519    
3520        return $;
3521    })();
3522    
3523
3524    /*===========================
3525    Add .swiper plugin from Dom libraries
3526    ===========================*/
3527    var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];
3528    function addLibraryPlugin(lib) {
3529        lib.fn.swiper = function (params) {
3530            var firstInstance;
3531            lib(this).each(function () {
3532                var s = new Swiper(this, params);
3533                if (!firstInstance) firstInstance = s;
3534            });
3535            return firstInstance;
3536        };
3537    }
3538    for (var i = 0; i < swiperDomPlugins.length; i++) {
3539        if (window[swiperDomPlugins[i]]) {
3540            addLibraryPlugin(window[swiperDomPlugins[i]]);
3541        }
3542    }
3543    // Required DOM Plugins
3544    var domLib;
3545    if (typeof Dom7 === 'undefined') {
3546        domLib = window.Dom7 || window.Zepto || window.jQuery;
3547    }
3548    else {
3549        domLib = Dom7;
3550    }
3551    if (domLib) {
3552        if (!('transitionEnd' in domLib.fn)) {
3553            domLib.fn.transitionEnd = function (callback) {
3554                var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
3555                    i, j, dom = this;
3556                function fireCallBack(e) {
3557                    /*jshint validthis:true */
3558                    if (e.target !== this) return;
3559                    callback.call(this, e);
3560                    for (i = 0; i < events.length; i++) {
3561                        dom.off(events[i], fireCallBack);
3562                    }
3563                }
3564                if (callback) {
3565                    for (i = 0; i < events.length; i++) {
3566                        dom.on(events[i], fireCallBack);
3567                    }
3568                }
3569                return this;
3570            };
3571        }
3572        if (!('transform' in domLib.fn)) {
3573            domLib.fn.transform = function (transform) {
3574                for (var i = 0; i < this.length; i++) {
3575                    var elStyle = this[i].style;
3576                    elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;
3577                }
3578                return this;
3579            };
3580        }
3581        if (!('transition' in domLib.fn)) {
3582            domLib.fn.transition = function (duration) {
3583                if (typeof duration !== 'string') {
3584                    duration = duration + 'ms';
3585                }
3586                for (var i = 0; i < this.length; i++) {
3587                    var elStyle = this[i].style;
3588                    elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;
3589                }
3590                return this;
3591            };
3592        }
3593    }
3594        
3595    
3596
3597})();
3598/*===========================
3599Swiper AMD Export
3600===========================*/
3601if (typeof(module) !== 'undefined')
3602{
3603    module.exports = Swiper;
3604}
3605else if (typeof define === 'function' && define.amd) {
3606    define([], function () {
3607        'use strict';
3608        return Swiper;
3609    });
3610}

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.