PageSourceSearch

https://somersetacademybethany.org/js/lightgallery.js

js somersetacademybethany.org collected 2026-09-29 19:06:58 UTC 45,168 bytes, 1,364 lines download raw bytes

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

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.