PageSourceSearch

https://delektulum.com/scripts/Main/lightgallery-all.min.js

js delektulum.com collected 2026-09-26 17:54:16 UTC 45,469 bytes, 1,378 lines download raw bytes

1/*! lightgallery - v1.8.0 - 2020-08-29
2* http://sachinchoolur.github.io/lightGallery/
3* Copyright (c) 2020 Sachin N; Licensed GPLv3 */
4(function (root, factory) {
5  if (typeof define === 'function' && define.amd) {
6    // AMD. Register as an anonymous module unless amdModuleId is set
7    define(['jquery'], function (a0) {
8      return (factory(a0));
9    });
10  } else if (typeof module === 'object' && module.exports) {
11    // Node. Does not work with strict CommonJS, but
12    // only CommonJS-like environments that support module.exports,
13    // like Node.
14    module.exports = factory(require('jquery'));
15  } else {
16    factory(root["jQuery"]);
17  }
18}(this, function ($) {
19
20(function() {
21    'use strict';
22
23    var defaults = {
24
25        mode: 'lg-slide',
26
27        // Ex : 'ease'
28        cssEasing: 'ease',
29
30        //'for jquery animation'
31        easing: 'linear',
32        speed: 600,
33        height: '100%',
34        width: '100%',
35        addClass: '',
36        startClass: 'lg-start-zoom',
37        backdropDuration: 150,
38        hideBarsDelay: 6000,
39
40        useLeft: false,
41
42        // aria-labelledby attribute fot gallery
43        ariaLabelledby: '',
44
45        //aria-describedby attribute for gallery
46        ariaDescribedby: '',
47
48        closable: true,
49        loop: true,
50        escKey: true,
51        keyPress: true,
52        controls: true,
53        slideEndAnimatoin: true,
54        hideControlOnEnd: false,
55        mousewheel: true,
56
57        getCaptionFromTitleOrAlt: true,
58
59        // .lg-item || '.lg-sub-html'
60        appendSubHtmlTo: '.lg-sub-html',
61
62        subHtmlSelectorRelative: false,
63
64        /**
65         * @desc number of preload slides
66         * will exicute only after the current slide is fully loaded.
67         *
68         * @ex you clicked on 4th image and if preload = 1 then 3rd slide and 5th
69         * slide will be loaded in the background after the 4th slide is fully loaded..
70         * if preload is 2 then 2nd 3rd 5th 6th slides will be preloaded.. ... ...
71         *
72         */
73        preload: 1,
74        showAfterLoad: true,
75        selector: '',
76        selectWithin: '',
77        nextHtml: '',
78        prevHtml: '',
79
80        // 0, 1
81        index: false,
82
83        iframeMaxWidth: '100%',
84
85        download: true,
86        counter: true,
87        appendCounterTo: '.lg-toolbar',
88
89        swipeThreshold: 50,
90        enableSwipe: true,
91        enableDrag: true,
92
93        dynamic: false,
94        dynamicEl: [],
95        galleryId: 1
96    };
97
98    function Plugin(element, options) {
99
100        // Current lightGallery element
101        this.el = element;
102
103        // Current jquery element
104        this.$el = $(element);
105
106        // lightGallery settings
107        this.s = $.extend({}, defaults, options);
108
109        // When using dynamic mode, ensure dynamicEl is an array
110        if (this.s.dynamic && this.s.dynamicEl !== 'undefined' && this.s.dynamicEl.constructor === Array && !this.s.dynamicEl.length) {
111            throw ('When using dynamic mode, you must also define dynamicEl as an Array.');
112        }
113
114        // lightGallery modules
115        this.modules = {};
116
117        // false when lightgallery complete first slide;
118        this.lGalleryOn = false;
119
120        this.lgBusy = false;
121
122        // Timeout function for hiding controls;
123        this.hideBartimeout = false;
124
125        // To determine browser supports for touch events;
126        this.isTouch = ('ontouchstart' in document.documentElement);
127
128        // Disable hideControlOnEnd if sildeEndAnimation is true
129        if (this.s.slideEndAnimatoin) {
130            this.s.hideControlOnEnd = false;
131        }
132
133        // Gallery items
134        if (this.s.dynamic) {
135            this.$items = this.s.dynamicEl;
136        } else {
137            if (this.s.selector === 'this') {
138                this.$items = this.$el;
139            } else if (this.s.selector !== '') {
140                if (this.s.selectWithin) {
141                    this.$items = $(this.s.selectWithin).find(this.s.selector);
142                } else {
143                    this.$items = this.$el.find($(this.s.selector));
144                }
145            } else {
146                this.$items = this.$el.children();
147            }
148        }
149
150        // .lg-item
151        this.$slide = '';
152
153        // .lg-outer
154        this.$outer = '';
155
156        this.init();
157
158        return this;
159    }
160
161    Plugin.prototype.init = function() {
162
163        var _this = this;
164
165        // s.preload should not be more than $item.length
166        if (_this.s.preload > _this.$items.length) {
167            _this.s.preload = _this.$items.length;
168        }
169
170        // if dynamic option is enabled execute immediately
171        var _hash = window.location.hash;
172        if (_hash.indexOf('lg=' + this.s.galleryId) > 0) {
173
174            _this.index = parseInt(_hash.split('&slide=')[1], 10);
175
176            $('body').addClass('lg-from-hash');
177            if (!$('body').hasClass('lg-on')) {
178                setTimeout(function() {
179                    _this.build(_this.index);
180                });
181
182                $('body').addClass('lg-on');
183            }
184        }
185
186        if (_this.s.dynamic) {
187
188            _this.$el.trigger('onBeforeOpen.lg');
189
190            _this.index = _this.s.index || 0;
191
192            // prevent accidental double execution
193            if (!$('body').hasClass('lg-on')) {
194                setTimeout(function() {
195                    _this.build(_this.index);
196                    $('body').addClass('lg-on');
197                });
198            }
199        } else {
200
201            // Using different namespace for click because click event should not unbind if selector is same object('this')
202            _this.$items.on('click.lgcustom', function(event) {
203
204                // For IE8
205                try {
206                    event.preventDefault();
207                    event.preventDefault();
208                } catch (er) {
209                    event.returnValue = false;
210                }
211
212                _this.$el.trigger('onBeforeOpen.lg');
213
214                _this.index = _this.s.index || _this.$items.index(this);
215
216                // prevent accidental double execution
217                if (!$('body').hasClass('lg-on')) {
218                    _this.build(_this.index);
219                    $('body').addClass('lg-on');
220                }
221            });
222        }
223
224    };
225
226    Plugin.prototype.build = function(index) {
227
228        var _this = this;
229
230        _this.structure();
231
232        // module constructor
233        $.each($.fn.lightGallery.modules, function(key) {
234            _this.modules[key] = new $.fn.lightGallery.modules[key](_this.el);
235        });
236
237        // initiate slide function
238        _this.slide(index, false, false, false);
239
240        if (_this.s.keyPress) {
241            _this.keyPress();
242        }
243
244        if (_this.$items.length > 1) {
245
246            _this.arrow();
247
248            setTimeout(function() {
249                _this.enableDrag();
250                _this.enableSwipe();
251            }, 50);
252
253            if (_this.s.mousewheel) {
254                _this.mousewheel();
255            }
256        } else {
257            _this.$slide.on('click.lg', function() {
258                _this.$el.trigger('onSlideClick.lg');
259            });
260        }
261
262        _this.counter();
263
264        _this.closeGallery();
265
266        _this.$el.trigger('onAfterOpen.lg');
267
268        // Hide controllers if mouse doesn't move for some period
269        _this.$outer.on('mousemove.lg click.lg touchstart.lg', function() {
270
271            _this.$outer.removeClass('lg-hide-items');
272
273            clearTimeout(_this.hideBartimeout);
274
275            // Timeout will be cleared on each slide movement also
276            _this.hideBartimeout = setTimeout(function() {
277                _this.$outer.addClass('lg-hide-items');
278            }, _this.s.hideBarsDelay);
279
280        });
281
282        _this.$outer.trigger('mousemove.lg');
283
284    };
285
286    Plugin.prototype.structure = function() {
287        var list = '';
288        var controls = '';
289        var i = 0;
290        var subHtmlCont = '';
291        var template;
292        var _this = this;
293
294        $('body').append('<div class="lg-backdrop"></div>');
295        $('.lg-backdrop').css('transition-duration', this.s.backdropDuration + 'ms');
296
297        // Create gallery items
298        for (i = 0; i < this.$items.length; i++) {
299            list += '<div class="lg-item"></div>';
300        }
301
302        // Create controlls
303        if (this.s.controls && this.$items.length > 1) {
304            controls = '<div class="lg-actions">' +
305                '<button type="button" aria-label="Previous slide" class="lg-prev lg-icon">' + this.s.prevHtml + '</button>' +
306                '<button type="button" aria-label="Next slide" class="lg-next lg-icon">' + this.s.nextHtml + '</button>' +
307                '</div>';
308        }
309
310        if (this.s.appendSubHtmlTo === '.lg-sub-html') {
311            subHtmlCont = '<div role="status" aria-live="polite" class="lg-sub-html"></div>';
312        }
313
314        var ariaLabelledby = this.s.ariaLabelledby ?
315            'aria-labelledby="' + this.s.ariaLabelledby + '"' : '';
316        var ariaDescribedby = this.s.ariaDescribedby ?
317            'aria-describedby="' + this.s.ariaDescribedby + '"' : '';
318
319        template = '<div tabindex="-1" aria-modal="true" ' + ariaLabelledby + ' ' + ariaDescribedby + ' role="dialog" class="lg-outer ' + this.s.addClass + ' ' + this.s.startClass + '">' +
320            '<div class="lg" style="width:' + this.s.width + '; height:' + this.s.height + '">' +
321            '<div class="lg-inner">' + list + '</div>' +
322            '<div class="lg-toolbar lg-group">' +
323            '<button type="button" aria-label="Close gallery" class="lg-close lg-icon"></button>' +
324            '</div>' +
325            controls +
326            subHtmlCont +
327            '</div>' +
328            '</div>';
329
330        $('body').append(template);
331        this.$outer = $('.lg-outer');
332        this.$outer.focus();
333        this.$slide = this.$outer.find('.lg-item');
334
335        if (this.s.useLeft) {
336            this.$outer.addClass('lg-use-left');
337
338            // Set mode lg-slide if use left is true;
339            this.s.mode = 'lg-slide';
340        } else {
341            this.$outer.addClass('lg-use-css3');
342        }
343
344        // For fixed height gallery
345        _this.setTop();
346        $(window).on('resize.lg orientationchange.lg', function() {
347            setTimeout(function() {
348                _this.setTop();
349            }, 100);
350        });
351
352        // add class lg-current to remove initial transition
353        this.$slide.eq(this.index).addClass('lg-current');
354
355        // add Class for css support and transition mode
356        if (this.doCss()) {
357            this.$outer.addClass('lg-css3');
358        } else {
359            this.$outer.addClass('lg-css');
360
361            // Set speed 0 because no animation will happen if browser doesn't support css3
362            this.s.speed = 0;
363        }
364
365        this.$outer.addClass(this.s.mode);
366
367        if (this.s.enableDrag && this.$items.length > 1) {
368            this.$outer.addClass('lg-grab');
369        }
370
371        if (this.s.showAfterLoad) {
372            this.$outer.addClass('lg-show-after-load');
373        }
374
375        if (this.doCss()) {
376            var $inner = this.$outer.find('.lg-inner');
377            $inner.css('transition-timing-function', this.s.cssEasing);
378            $inner.css('transition-duration', this.s.speed + 'ms');
379        }
380
381        setTimeout(function() {
382            $('.lg-backdrop').addClass('in');
383        });
384
385        setTimeout(function() {
386            _this.$outer.addClass('lg-visible');
387        }, this.s.backdropDuration);
388
389        if (this.s.download) {
390            this.$outer.find('.lg-toolbar').append('<a id="lg-download" aria-label="Download" target="_blank" download class="lg-download lg-icon"></a>');
391        }
392
393        // Store the current scroll top value to scroll back after closing the gallery..
394        this.prevScrollTop = $(window).scrollTop();
395
396    };
397
398    // For fixed height gallery
399    Plugin.prototype.setTop = function() {
400        if (this.s.height !== '100%') {
401            var wH = $(window).height();
402            var top = (wH - parseInt(this.s.height, 10)) / 2;
403            var $lGallery = this.$outer.find('.lg');
404            if (wH >= parseInt(this.s.height, 10)) {
405                $lGallery.css('top', top + 'px');
406            } else {
407                $lGallery.css('top', '0px');
408            }
409        }
410    };
411
412    // Find css3 support
413    Plugin.prototype.doCss = function() {
414        // check for css animation support
415        var support = function() {
416            var transition = ['transition', 'MozTransition', 'WebkitTransition', 'OTransition', 'msTransition', 'KhtmlTransition'];
417            var root = document.documentElement;
418            var i = 0;
419            for (i = 0; i < transition.length; i++) {
420                if (transition[i] in root.style) {
421                    return true;
422                }
423            }
424        };
425
426        if (support()) {
427            return true;
428        }
429
430        return false;
431    };
432
433    /**
434     *  @desc Check the given src is video
435     *  @param {String} src
436     *  @return {Object} video type
437     *  Ex:{ youtube  :  ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] }
438     */
439    Plugin.prototype.isVideo = function(src, index) {
440
441        var html;
442        if (this.s.dynamic) {
443            html = this.s.dynamicEl[index].html;
444        } else {
445            html = this.$items.eq(index).attr('data-html');
446        }
447
448        if (!src) {
449            if (html) {
450                return {
451                    html5: true
452                };
453            } else {
454                console.error('lightGallery :- data-src is not provided on slide item ' + (index + 1) + '. Please make sure the selector property is properly configured. More info - http://sachinchoolur.github.io/lightGallery/demos/html-markup.html');
455                return false;
456            }
457        }
458
459        var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)/i);
460        var vimeo = src.match(/\/\/(?:www\.)?vimeo.com\/([0-9a-z\-_]+)/i);
461        var dailymotion = src.match(/\/\/(?:www\.)?dai.ly\/([0-9a-z\-_]+)/i);
462        var vk = src.match(/\/\/(?:www\.)?(?:vk\.com|vkontakte\.ru)\/(?:video_ext\.php\?)(.*)/i);
463
464        if (youtube) {
465            return {
466                youtube: youtube
467            };
468        } else if (vimeo) {
469            return {
470                vimeo: vimeo
471            };
472        } else if (dailymotion) {
473            return {
474                dailymotion: dailymotion
475            };
476        } else if (vk) {
477            return {
478                vk: vk
479            };
480        }
481    };
482
483    /**
484     *  @desc Create image counter
485     *  Ex: 1/10
486     */
487    Plugin.prototype.counter = function() {
488        if (this.s.counter) {
489            $(this.s.appendCounterTo).append('<div id="lg-counter" role="status" aria-l
489ive="polite"><span id="lg-counter-current">' + (parseInt(this.index, 10) + 1) + '</span> / <span id="lg-counter-all">' + this.$items.length + '</span></div>');
490        }
491    };
492
493    /**
494     *  @desc add sub-html into the slide
495     *  @param {Number} index - index of the slide
496     */
497    Plugin.prototype.addHtml = function(index) {
498        var subHtml = null;
499        var subHtmlUrl;
500        var $currentEle;
501        if (this.s.dynamic) {
502            if (this.s.dynamicEl[index].subHtmlUrl) {
503                subHtmlUrl = this.s.dynamicEl[index].subHtmlUrl;
504            } else {
505                subHtml = this.s.dynamicEl[index].subHtml;
506            }
507        } else {
508            $currentEle = this.$items.eq(index);
509            if ($currentEle.attr('data-sub-html-url')) {
510                subHtmlUrl = $currentEle.attr('data-sub-html-url');
511            } else {
512                subHtml = $currentEle.attr('data-sub-html');
513                if (this.s.getCaptionFromTitleOrAlt && !subHtml) {
514                    subHtml = $currentEle.attr('title') || $currentEle.find('img').first().attr('alt');
515                }
516            }
517        }
518
519        if (!subHtmlUrl) {
520            if (typeof subHtml !== 'undefined' && subHtml !== null) {
521
522                // get first letter of subhtml
523                // if first letter starts with . or # get the html form the jQuery object
524                var fL = subHtml.substring(0, 1);
525                if (fL === '.' || fL === '#') {
526                    if (this.s.subHtmlSelectorRelative && !this.s.dynamic) {
527                        subHtml = $currentEle.find(subHtml).html();
528                    } else {
529                        subHtml = $(subHtml).html();
530                    }
531                }
532            } else {
533                subHtml = '';
534            }
535        }
536
537        if (this.s.appendSubHtmlTo === '.lg-sub-html') {
538
539            if (subHtmlUrl) {
540                this.$outer.find(this.s.appendSubHtmlTo).load(subHtmlUrl);
541            } else {
542                this.$outer.find(this.s.appendSubHtmlTo).html(subHtml);
543            }
544
545        } else {
546
547            if (subHtmlUrl) {
548                this.$slide.eq(index).load(subHtmlUrl);
549            } else {
550                this.$slide.eq(index).append(subHtml);
551            }
552        }
553
554        // Add lg-empty-html class if title doesn't exist
555        if (typeof subHtml !== 'undefined' && subHtml !== null) {
556            if (subHtml === '') {
557                this.$outer.find(this.s.appendSubHtmlTo).addClass('lg-empty-html');
558            } else {
559                this.$outer.find(this.s.appendSubHtmlTo).removeClass('lg-empty-html');
560            }
561        }
562
563        this.$el.trigger('onAfterAppendSubHtml.lg', [index]);
564    };
565
566    /**
567     *  @desc Preload slides
568     *  @param {Number} index - index of the slide
569     */
570    Plugin.prototype.preload = function(index) {
571        var i = 1;
572        var j = 1;
573        for (i = 1; i <= this.s.preload; i++) {
574            if (i >= this.$items.length - index) {
575                break;
576            }
577
578            this.loadContent(index + i, false, 0);
579        }
580
581        for (j = 1; j <= this.s.preload; j++) {
582            if (index - j < 0) {
583                break;
584            }
585
586            this.loadContent(index - j, false, 0);
587        }
588    };
589
590    /**
591     *  @desc Load slide content into slide.
592     *  @param {Number} index - index of the slide.
593     *  @param {Boolean} rec - if true call loadcontent() function again.
594     *  @param {Boolean} delay - delay for adding complete class. it is 0 except first time.
595     */
596    Plugin.prototype.loadContent = function(index, rec, delay) {
597
598        var _this = this;
599        var _hasPoster = false;
600        var _$img;
601        var _src;
602        var _poster;
603        var _srcset;
604        var _sizes;
605        var _html;
606        var _alt;
607        var getResponsiveSrc = function(srcItms) {
608            var rsWidth = [];
609            var rsSrc = [];
610            for (var i = 0; i < srcItms.length; i++) {
611                var __src = srcItms[i].split(' ');
612
613                // Manage empty space
614                if (__src[0] === '') {
615                    __src.splice(0, 1);
616                }
617
618                rsSrc.push(__src[0]);
619                rsWidth.push(__src[1]);
620            }
621
622            var wWidth = $(window).width();
623            for (var j = 0; j < rsWidth.length; j++) {
624                if (parseInt(rsWidth[j], 10) >
624 wWidth) {
625                    _src = rsSrc[j];
626                    break;
627                }
628            }
629        };
630
631        if (_this.s.dynamic) {
632
633            if (_this.s.dynamicEl[index].poster) {
634                _hasPoster = true;
635                _poster = _this.s.dynamicEl[index].poster;
636            }
637
638            _html = _this.s.dynamicEl[index].html;
639            _src = _this.s.dynamicEl[index].src;
640            _alt = _this.s.dynamicEl[index].alt;
641
642            if (_this.s.dynamicEl[index].responsive) {
643                var srcDyItms = _this.s.dynamicEl[index].responsive.split(',');
644                getResponsiveSrc(srcDyItms);
645            }
646
647            _srcset = _this.s.dynamicEl[index].srcset;
648            _sizes = _this.s.dynamicEl[index].sizes;
649
650        } else {
651            var $currentEle = _this.$items.eq(index);
652            if ($currentEle.attr('data-poster')) {
653                _hasPoster = true;
654                _poster = $currentEle.attr('data-poster');
655            }
656
657            _html = $currentEle.attr('data-html');
658            _src = $currentEle.attr('href') || $currentEle.attr('data-src');
659            _alt = $currentEle.attr('title') || $currentEle.find('img').first().attr('alt');
660
661            if ($currentEle.attr('data-responsive')) {
662                var srcItms = $currentEle.attr('data-responsive').split(',');
663                getResponsiveSrc(srcItms);
664            }
665
666            _srcset = $currentEle.attr('data-srcset');
667            _sizes = $currentEle.attr('data-sizes');
668
669        }
670
671        //if (_src || _srcset || _sizes || _poster) {
672
673        var iframe = false;
674        if (_this.s.dynamic) {
675            if (_this.s.dynamicEl[index].iframe) {
676                iframe = true;
677            }
678        } else {
679            if (_this.$items.eq(index).attr('data-iframe') === 'true') {
680                iframe = true;
681            }
682        }
683
684        var _isVideo = _this.isVideo(_src, index);
685        if (!_this.$slide.eq(index).hasClass('lg-loaded')) {
686            if (iframe) {
687                _this.$slide.eq(index).prepend('<div class="lg-video-cont lg-has-iframe" style="max-width:' + _this.s.iframeMaxWidth + '"><div class="lg-video"><iframe class="lg-object" frameborder="0" src="' + _src + '"  allowfullscreen="true"></iframe></div></div>');
688            } else if (_hasPoster) {
689                var videoClass = '';
690                if (_isVideo && _isVideo.youtube) {
691                    videoClass = 'lg-has-youtube';
692                } else if (_isVideo && _isVideo.vimeo) {
693                    videoClass = 'lg-has-vimeo';
694                } else {
695                    videoClass = 'lg-has-html5';
696                }
697
698                _this.$slide.eq(index).prepend('<div class="lg-video-cont ' + videoClass + ' "><div class="lg-video"><span class="lg-video-play"></span><img class="lg-object lg-has-poster" src="' + _poster + '" /></div></div>');
699
700            } else if (_isVideo) {
701                _this.$slide.eq(index).prepend('<div class="lg-video-cont "><div class="lg-video"></div></div>');
702                _this.$el.trigger('hasVideo.lg', [index, _src, _html]);
703            } else {
704                _alt = _alt ? 'alt="' + _alt + '"' : '';
705                _this.$slide.eq(index).prepend('<div class="lg-img-wrap"><img class="lg-object lg-image" ' + _alt + ' src="' + _src + '" /></div>');
706            }
707
708            _this.$el.trigger('onAferAppendSlide.lg', [index]);
709
710            _$img = _this.$slide.eq(index).find('.lg-object');
711            if (_sizes) {
712                _$img.attr('sizes', _sizes);
713            }
714
715            if (_srcset) {
716                _$img.attr('srcset', _srcset);
717                try {
718                    picturefill({
719                        elements: [_$img[0]]
720                    });
721                } catch (e) {
722                    console.warn('lightGallery :- If you want srcset to be supported for older browser please include picturefil version 2 javascript library in your document.');
723                }
724            }
725
726            if (this.s.appendSubHtmlTo !== '.lg-sub-html') {
727                _this.addHtml(index);
728            }
729
730            _this.$slide.eq(index).addClass('lg-loaded');
731        }
732
733        _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() {
734
735            // For first time add some delay for displaying the start animation.
736            var _speed = 0;
737
738            // Do not change the delay value because it is required for zoom plugin.
739            // If gallery opened from direct url (hash) speed value should be 0
740            if (delay && !$('body').hasClass('lg-from-hash')) {
741                _speed = delay;
742            }
743
744            setTimeout(function() {
745                _this.$slide.eq(index).addClass('lg-complete');
746                _this.$el.trigger('onSlideItemLoad.lg', [index, delay || 0]);
747            }, _speed);
748
749        });
750
751        // @todo check load state for html5 videos
752        if (_isVideo && _isVideo.html5 && !_hasPoster) {
753            _this.$slide.eq(index).addClass('lg-complete');
754        }
755
756        if (rec === true) {
757            if (!_this.$slide.eq(index).hasClass('lg-complete')) {
758                _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() {
759                    _this.preload(index);
760                });
761            } else {
762                _this.preload(index);
763            }
764        }
765
766        //}
767    };
768
769    /**
770    *   @desc slide function for lightgallery
771        ** Slide() gets call on start
772        ** ** Set lg.on true once slide() function gets called.
773        ** Call loadContent() on slide() function inside setTimeout
774        ** ** On first slide we do not want any animation like slide of fade
775        ** ** So on first slide( if lg.on if false that is first slide) loadContent() should start loading immediately
776        ** ** Else loadContent() should wait for the transition to complete.
777        ** ** So set timeout s.speed + 50
778    <=> ** loadContent() will load slide content in to the particular slide
779        ** ** It has recursion (rec) parameter. if rec === true loadContent() will call preload() function.
780        ** ** preload will execute only when the previous slide is fully loaded (images iframe)
781        ** ** avoid simultaneous image load
782    <=> ** Preload() will check for s.preload value and call loadContent() again accoring to preload value
783        ** loadContent()  <====> Preload();
784
785    *   @param {Number} index - index of the slide
786    *   @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
787    *   @param {Boolean} fromThumb - true if slide function called via thumbnail click
788    *   @param {String} direction - Direction of the slide(next/prev)
789    */
790    Plugin.prototype.slide = function(index, fromTouch, fromThumb, direction) {
791
792        var _prevIndex = this.$outer.find('.lg-current').index();
793        var _this = this;
794
795        // Prevent if multiple call
796        // Required for hsh plugin
797        if (_this.lGalleryOn && (_prevIndex === index)) {
798            return;
799        }
800
801        var _length = this.$slide.length;
802        var _time = _this.lGalleryOn ? this.s.speed : 0;
803
804        if (!_this.lgBusy) {
805
806            if (this.s.download) {
807                var _src;
808                if (_this.s.dynamic) {
809                    _src = _this.s.dynamicEl[index].downloadUrl !== false && (_this.s.dynamicEl[index].downloadUrl || _this.s.dynamicEl[index].src);
810                } else {
811                    _src = _this.$items.eq(index).attr('data-download-url') !== 'false' && (_this.$items.eq(index).attr('data-download-url') || _this.$items.eq(index).attr('href') || _this.$items.eq(index).attr('data-src'));
812
813                }
814
815                if (_src) {
816                    $('#lg-download').attr('href', _src);
817                    _this.$outer.removeClass('lg-hide-download');
818                } else {
819                    _this.$outer.addClass('lg-hide-download');
820                }
821            }
822
823            this.$el.trigger('onBeforeSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
824
825            _this.lgBusy = true;
826
827            clearTimeout(_this.hideBartimeout);
828
829            // Add title if this.s.appendSubHtmlTo === lg-sub-html
830            if (this.s.appendSubHtmlTo === '.lg-sub-html') {
831
832                // wait for slide animation to complete
833                setTimeout(function() {
834                    _this.addHtml(index);
835                }, _time);
836            }
837
838            this.arrowDisable(index);
839
840            if (!direction) {
841                if (index < _prevIndex) {
842                    direction = 'prev';
843                } else if (index > _prevIndex) {
844                    direction = 'next';
845                }
846            }
847
848            if (!fromTouch) {
849
850                // remove all transitions
851                _this.$outer.addClass('lg-no-trans');
852
853                this.$slide.removeClass('lg-prev-slide lg-next-slide');
854
855                if (direction === 'prev') {
856
857                    //prevslide
858                    this.$slide.eq(index).addClass('lg-prev-slide');
859                    this.$slide.eq(_prevIndex).addClass('lg-next-slide');
860                } else {
861
862                    // next slide
863                    this.$slide.eq(index).addClass('lg-next-slide');
864                    this.$slide.eq(_prevIndex).addClass('lg-prev-slide');
865                }
866
867                // give 50 ms for browser to add/remove class
868                setTimeout(function() {
869                    _this.$slide.removeClass('lg-current');
870
871                    //_this.$slide.eq(_prevIndex).removeClass('lg-current');
872                    _this.$slide.eq(index).addClass('lg-current');
873
874                    // reset all transitions
875                    _this.$outer.removeClass('lg-no-trans');
876                }, 50);
877            } else {
878
879                this.$slide.removeClass('lg-prev-slide lg-current lg-next-slide');
880                var touchPrev;
881                var touchNext;
882                if (_length > 2) {
883                    touchPrev = index - 1;
884                    touchNext = index + 1;
885
886                    if ((index === 0) && (_prevIndex === _length - 1)) {
887
888                        // next slide
889                        touchNext = 0;
890                        touchPrev = _length - 1;
891                    } else if ((index === _length - 1) && (_prevIndex === 0)) {
892
893                        // prev slide
894                        touchNext = 0;
895                        touchPrev = _length - 1;
896                    }
897
898                } else {
899                    touchPrev = 0;
900                    touchNext = 1;
901                }
902
903                if (direction === 'prev') {
904                    _this.$slide.eq(touchNext).addClass('lg-next-slide');
905                } else {
906                    _this.$slide.eq(touchPrev).addClass('lg-prev-slide');
907                }
908
909                _this.$slide.eq(index).addClass('lg-current');
910            }
911
912            if (_this.lGalleryOn) {
913                setTimeout(function() {
914                    _this.loadContent(index, true, 0);
915                }, this.s.speed + 50);
916
917                setTimeout(function() {
918                    _this.lgBusy = false;
919                    _this.$el.trigger('onAfterSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
920                }, this.s.speed);
921
922            } else {
923                _this.loadContent(index, true, _this.s.backdropDuration);
924
925                _this.lgBusy = false;
926                _this.$el.trigger('onAfterSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
927            }
928
929            _this.lGalleryOn = true;
930
931            if (this.s.counter) {
932                $('#lg-counter-current').text(index + 1);
933            }
934
935        }
936        _this.index = index;
937
938    };
939
940    /**
941     *  @desc Go to next slide
942     *  @param {Boolean} fromTouch - true if slide function called via touch event
943     */
944    Plugin.prototype.goToNextSlide = function(fromTouch) {
945        var _this = this;
946        var _loop = _this.s.loop;
947        if (fromTouch && _this.$slide.length < 3) {
948            _loop = false;
949        }
950
951        if (!_this.lgBusy) {
952            if ((_this.index + 1) < _this.$slide.length) {
953                _this.index++;
954                _this.$el.trigger('onBeforeNextSlide.lg', [_this.index]);
955                _this.slide(_this.index, fromTouch, false, 'next');
956            } else {
957                if (_loop) {
958                    _this.index = 0;
959                    _this.$el.trigger('onBeforeNextSlide.lg', [_this.index]);
960                    _this.slide(_this.index, fromTouch, false, 'next');
961                } else if (_this.s.slideEndAnimatoin && !fromTouch) {
962                    _this.$outer.addClass('lg-right-end');
963                    setTimeout(function() {
964                        _this.$outer.removeClass('lg-right-end');
965                    }, 400);
966                }
967            }
968        }
969    };
970
971    /**
972     *  @desc Go to previous slide
973     *  @param {Boolean} fromTouch - true if slide function called via touch event
974     */
975    Plugin.prototype.goToPrevSlide = function(fromTouch) {
976        var _this = this;
977        var _loop = _this.s.loop;
978        if (fromTouch && _this.$slide.length < 3) {
979            _loop = false;
980        }
981
982        if (!_this.lgBusy) {
983            if (_this.index > 0) {
984                _this.index--;
985                _this.$el.trigger('onBeforePrevSlide.lg', [_this.index, fromTouch]);
986                _this.slide(_this.index, fromTouch, false, 'prev');
987            } else {
988                if (_loop) {
989                    _this.index = _this.$items.length - 1;
990                    _this.$el.trigger('onBeforePrevSlide.lg', [_this.index, fromTouch]);
991                    _this.slide(_this.index, fromTouch, false, 'prev');
992                } else if (_this.s.slideEndAnimatoin && !fromTouch) {
993                    _this.$outer.addClass('lg-left-end');
994                    setTimeout(function() {
995                        _this.$outer.removeClass('lg-left-end');
996                    }, 400);
997                }
998            }
999        }
1000    };
1001
1002    Plugin.prototype.keyPress = function() {
1003        var _this = this;
1004        if (this.$items.length > 1) {
1005            $(window).on('keyup.lg', function(e) {
1006                if (_this.$items.length > 1) {
1007                    if (e.keyCode === 37) {
1008                        e.preventDefault();
1009                        _this.goToPrevSlide();
1010                    }
1011
1012                    if (e.keyCode === 39) {
1013                        e.preventDefault();
1014                        _this.goToNextSlide();
1015                    }
1016                }
1017            });
1018        }
1019
1020        $(window).on('keydown.lg', function(e) {
1021            if (_this.s.escKey === true && e.keyCode === 27) {
1022                e.preventDefault();
1023                if (!_this.$outer.hasClass('lg-thumb-open')) {
1024                    _this.destroy();
1025                } else {
1026                    _this.$outer.removeClass('lg-thumb-open');
1027                }
1028            }
1029        });
1030    };
1031
1032    Plugin.prototype.arrow = function() {
1033        var _this = this;
1034        this.$outer.find('.lg-prev').on('click.lg', function() {
1035            _this.goToPrevSlide();
1036        });
1037
1038        this.$outer.find('.lg-next').on('click.lg', function() {
1039            _this.goToNextSlide();
1040        });
1041    };
1042
1043    Plugin.prototype.arrowDisable = function(index) {
1044
1045        // Disable arrows if s.hideControlOnEnd is true
1046        if (!this.s.loop && this.s.hideControlOnEnd) {
1047            if ((index + 1) < this.$slide.length) {
1048                this.$outer.find('.lg-next').removeAttr('disabled').removeClass('disabled');
1049            } else {
1050                this.$outer.find('.lg-next').attr('disabled', 'disabled').addClass('disabled');
1051            }
1052
1053            if (index > 0) {
1054                this.$outer.find('.lg-prev').removeAttr('disabled').removeClass('disabled');
1055            } else {
1056                this.$outer.find('.lg-prev').attr('disabled', 'disabled').addClass('disabled');
1057            }
1058        }
1059    };
1060
1061    Plugin.prototype.setTranslate = function($el, xValue, yValue) {
1062        // jQuery supports Automatic CSS prefixing since jQuery 1.8.0
1063        if (this.s.useLeft) {
1064            $el.css('left', xValue);
1065        } else {
1066            $el.css({
1067                transform: 'translate3d(' + (xValue) + 'px, ' + yValue + 'px, 0px)'
1068            });
1069        }
1070    };
1071
1072    Plugin.prototype.touchMove = function(startCoords, endCoords) {
1073
1074        var distance = endCoords - startCoords;
1075
1076        if (Math.abs(distance) > 15) {
1077            // reset opacity and transition duration
1078            this.$outer.addClass('lg-dragging');
1079
1080            // move current slide
1081            this.setTranslate(this.$slide.eq(this.index), distance, 0);
1082
1083            // move next and prev slide with current slide
1084            this.setTranslate($('.lg-prev-slide'), -this.$slide.eq(this.index).width() + distance, 0);
1085            this.setTranslate($('.lg-next-slide'), this.$slide.eq(this.index).width() + distance, 0);
1086        }
1087    };
1088
1089    Plugin.prototype.touchEnd = function(distance) {
1090        var _this = this;
1091
1092        // keep slide animation for any mode while dragg/swipe
1093        if (_this.s.mode !== 'lg-slide') {
1094            _this.$outer.addClass('lg-slide');
1095        }
1096
1097        this.$slide.not('.lg-current, .lg-prev-slide, .lg-next-slide').css('opacity', '0');
1098
1099        // set transition duration
1100        setTimeout(function() {
1101            _this.$outer.removeClass('lg-dragging');
1102            if ((distance < 0) && (Math.abs(distance) > _this.s.swipeThreshold)) {
1103                _this.goToNextSlide(true);
1104            } else if ((distance > 0) && (Math.abs(distance) > _this.s.swipeThreshold)) {
1105                _this.goToPrevSlide(true);
1106            } else if (Math.abs(distance) < 5) {
1107
1108                // Trigger click if distance is less than 5 pix
1109                _this.$el.trigger('onSlideClick.lg');
1110            }
1111
1112            _this.$slide.removeAttr('style');
1113        });
1114
1115        // remove slide class once drag/swipe is completed if mode is not slide
1116        setTimeout(function() {
1117            if (!_this.$outer.hasClass('lg-dragging') && _this.s.mode !== 'lg-slide') {
1118                _this.$outer.removeClass('lg-slide');
1119            }
1120        }, _this.s.speed + 100);
1121
1122    };
1123
1124    Plugin.prototype.enableSwipe = function() {
1125        var _this = this;
1126        var startCoords = 0;
1127        var endCoords = 0;
1128        var isMoved = false;
1129
1130        if (_this.s.enableSwipe && _this.doCss()) {
1131
1132            _this.$slide.on('touchstart.lg', function(e) {
1133                if (!_this.$outer.hasClass('lg-zoomed') && !_this.lgBusy) {
1134                    e.preventDefault();
1135                    _this.manageSwipeClass();
1136                    startCoords = e.originalEvent.targetTouches[0].pageX;
1137                }
1138            });
1139
1140            _this.$slide.on('touchmove.lg', function(e) {
1141                if (!_this.$outer.hasClass('lg-zoomed')) {
1142                    e.preventDefault();
1143                    endCoords = e.originalEvent.targetTouches[0].pageX;
1144                    _this.touchMove(startCoords, endCoords);
1145                    isMoved = true;
1146                }
1147            });
1148
1149            _this.$slide.on('touchend.lg', function() {
1150                if (!_this.$outer.hasClass('lg-zoomed')) {
1151                    if (isMoved) {
1152                        isMoved = false;
1153                        _this.touchEnd(endCoords - startCoords);
1154                    } else {
1155                        _this.$el.trigger('onSlideClick.lg');
1156                    }
1157                }
1158            });
1159        }
1160
1161    };
1162
1163    Plugin.prototype.enableDrag = function() {
1164        var _this = this;
1165        var startCoords = 0;
1166        var endCoords = 0;
1167        var isDraging = false;
1168        var isMoved = false;
1169        if (_this.s.enableDrag && _this.doCss()) {
1170            _this.$slide.on('mousedown.lg', function(e) {
1171                if (!_this.$outer.hasClass('lg-zoomed') && !_this.lgBusy && !$(e.target).text().trim()) {
1172                    e.preventDefault();
1173                    _this.manageSwipeClass();
1174                    startCoords = e.pageX;
1175                    isDraging = true;
1176
1177                    // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
1178                    _this.$outer.scrollLeft += 1;
1179                    _this.$outer.scrollLeft -= 1;
1180
1181                    // *
1182
1183                    _this.$outer.removeClass('lg-grab').addClass('lg-grabbing');
1184
1185                    _this.$el.trigger('onDragstart.lg');
1186                }
1187            });
1188
1189            $(window).on('mousemove.lg', function(e) {
1190                if (isDraging) {
1191                    isMoved = true;
1192                    endCoords = e.pageX;
1193                    _this.touchMove(startCoords, endCoords);
1194                    _this.$el.trigger('onDragmove.lg');
1195                }
1196            });
1197
1198            $(window).on('mouseup.lg', function(e) {
1199                if (isMoved) {
1200                    isMoved = false;
1201                    _this.touchEnd(endCoords - startCoords);
1202                    _this.$el.trigger('onDragend.lg');
1203                } else if ($(e.target).hasClass('lg-object') || $(e.target).hasClass('lg-video-play')) {
1204                    _this.$el.trigger('onSlideClick.lg');
1205                }
1206
1207                // Prevent execution on click
1208                if (isDraging) {
1209                    isDraging = false;
1210                    _this.$outer.removeClass('lg-grabbing').addClass('lg-grab');
1211                }
1212            });
1213
1214        }
1215    };
1216
1217    Plugin.prototype.manageSwipeClass = function() {
1218        var _touchNext = this.index + 1;
1219        var _touchPrev = this.index - 1;
1220        if (this.s.loop && this.$slide.length > 2) {
1221            if (this.index === 0) {
1222                _touchPrev = this.$slide.length - 1;
1223            } else if (this.index === this.$slide.length - 1) {
1224                _touchNext = 0;
1225            }
1226        }
1227
1228        this.$slide.removeClass('lg-next-slide lg-prev-slide');
1229        if (_touchPrev > -1) {
1230            this.$slide.eq(_touchPrev).addClass('lg-prev-slide');
1231        }
1232
1233        this.$slide.eq(_touchNext).addClass('lg-next-slide');
1234    };
1235
1236    Plugin.prototype.mousewheel = function() {
1237        var _this = this;
1238        _this.$outer.on('mousewheel.lg', function(e) {
1239
1240            if (!e.deltaY) {
1241                return;
1242            }
1243
1244            if (e.deltaY > 0) {
1245                _this.goToPrevSlide();
1246            } else {
1247                _this.goToNextSlide();
1248            }
1249
1250            e.preventDefault();
1251        });
1252
1253    };
1254
1255    Plugin.prototype.closeGallery = function() {
1256
1257        var _this = this;
1258        var mousedown = false;
1259        this.$outer.find('.lg-close').on('click.lg', function() {
1260            _this.destroy();
1261        });
1262
1263        if (_this.s.closable) {
1264
1265            // If you drag the slide and release outside gallery gets close on chrome
1266            // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
1267            _this.$outer.on('mousedown.lg', function(e) {
1268
1269                if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap')) {
1270                    mousedown = true;
1271                } else {
1272                    mousedown = false;
1273                }
1274
1275            });
1276
1277            _this.$outer.on('mousemove.lg', function() {
1278                mousedown = false;
1279            });
1280
1281            _this.$outer.on('mouseup.lg', function(e) {
1282
1283                if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap') && mousedown) {
1284                    if (!_this.$outer.hasClass('lg-dragging')) {
1285                        _this.destroy();
1286                    }
1287                }
1288
1289            });
1290
1291        }
1292
1293    };
1294
1295    Plugin.prototype.destroy = function(d) {
1296
1297        var _this = this;
1298
1299        if (!d) {
1300            _this.$el.trigger('onBeforeClose.lg');
1301            $(window).scrollTop(_this.prevScrollTop);
1302        }
1303
1304
1305        /**
1306         * if d is false or undefined destroy will only close the gallery
1307         * plugins instance remains with the element
1308         *
1309         * if d is true destroy will completely remove the plugin
1310         */
1311
1312        if (d) {
1313            if (!_this.s.dynamic) {
1314                // only when not using dynamic mode is $items a jquery collection
1315                this.$items.off('click.lg click.lgcustom');
1316            }
1317
1318            $.removeData(_this.el, 'lightGallery');
1319        }
1320
1321        // Unbind all events added by lightGallery
1322        this.$el.off('.lg.tm');
1323
1324        // destroy all lightGallery modules
1325        $.each($.fn.lightGallery.modules, function(key) {
1326            if (_this.modules[key]) {
1327                _this.modules[key].destroy();
1328            }
1329        });
1330
1331        this.lGalleryOn = false;
1332
1333        clearTimeout(_this.hideBartimeout);
1334        this.hideBartimeout = false;
1335        $(window).off('.lg');
1336        $('body').removeClass('lg-on lg-from-hash');
1337
1338        if (_this.$outer) {
1339            _this.$outer.removeClass('lg-visible');
1340        }
1341
1342        $('.lg-backdrop').removeClass('in');
1343
1344        setTimeout(function() {
1345            if (_this.$outer) {
1346                _this.$outer.remove();
1347            }
1348
1349            $('.lg-backdrop').remove();
1350
1351            if (!d) {
1352                _this.$el.trigger('onCloseAfter.lg');
1353            }
1354            _this.$el.focus();
1355
1356        }, _this.s.backdropDuration + 50);
1357    };
1358
1359    $.fn.lightGallery = function(options) {
1360        return this.each(function() {
1361            if (!$.data(this, 'lightGallery')) {
1362                $.data(this, 'lightGallery', new Plugin(this, options));
1363            } else {
1364                try {
1365                    $(this).data('lightGallery').init();
1366                } catch (err) {
1367                    console.error('lightGallery has not initiated properly');
1368                }
1369            }
1370        });
1371    };
1372
1373    $.fn.lightGallery.modules = {};
1374
1375})();
1376
1377
1378}));

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.