PageSourceSearch

https://icp-smartservice.com/wp-content/plugins/theia-post-slider/dist/js/tps.js?ver=2.1.3

js icp-smartservice.com collected 2026-10-04 06:11:16 UTC 36,835 bytes, 1,045 lines download raw bytes

1/*
2 * Copyright 2012-2018, Theia Post Slider, WeCodePixels, https://wecodepixels.com
3 */
4var tps = tps || {};
5tps.slideshowsOnPage = 0;
6tps.createSlideshowDefaults = {
7    slideContainer: '',
8    nav: [],
9    navText: '%{currentSlide} of %{totalSlides}',
10    helperText: '',
11    defaultSlide: 0,
12    transitionEffect: 'none',
13    transitionSpeed: 400,
14    keyboardShortcuts: false,
15    scrollAfterRefresh: true,
16    numberOfSlides: 0, // Total number of slides, including the ones not loaded.
17    slides: [],
18    useSlideSources: false,
19    themeType: 'classic',
20    prevPost: null,
21    nextPost: null,
22    prevText: null,
23    nextText: null,
24    buttonWidth: 0,
25    prevText_post: null,
26    nextText_post: null,
27    buttonWidth_post: 0,
28    onShowPost: null,
29    postUrl: null,
30    postId: null,
31    refreshAds: false,
32    refreshAdsEveryNSlides: 1,
33    adRefreshingMechanism: 'javascript',
34    ajaxUrl: '/',
35    loopSlides: false,
36    scrollTopOffset: 0,
37    isRtl: false,
38    excludedWords: []
39};
40tps.createSlideshow = function (options) {
41    var i, j;
42    var me = this;
43    var $ = jQuery;
44
45    // Merge options with defaults and sanitize values.
46    me.options = $.extend(tps.createSlideshowDefaults, options);
47    for (i in me.options) {
48        // If the default is a number and the option is a string, then convert it to a number if possible.
49        if (!isNaN(tps.createSlideshowDefaults[i]) && (typeof me.options[i] == 'string')) {
50            var value = parseFloat(me.options[i]);
51            if (!isNaN(value)) {
52                me.options[i] = value;
53            }
54        }
55    }
56
57    me.slides = [];
58    me.slideContainer = $(me.options.slideContainer);
59    if (me.slideContainer.length == 0) {
60        return null;
61    }
62
63    tps.slideshowsOnPage++;
64    me.navEl = [];
65    for (i = 0; i < me.options.nav.length; i++) {
66        var e = $(me.options.nav[i]).get();
67        for (j = 0; j < e.length; j++) {
68            me.navEl.push({
69                container: $(e[j])
70            });
71        }
72    }
73
74    // Initialize variables.
75    me.currentPostId = me.options.postId;
76    me.isLoading = false;
77    me.slidesSinceLastAdRefresh = 0;
78
79    // Remote loading queue.
80    me.remoteLoadingQueue = async.queue(function (task, callback) {
81        callback();
82    }, 1);
83
84    // The current slide.
85    me.currentSlide = null;
86
87    // The slide that is currently displayed. This may lag behind "me.currentSlide" because of the animations.
88    me.currentlyDisplayedSlide = null;
89
90    // The number of animations that are currently running.
91    me.animations = 0;
92
93    // A queue that is executed when no animation is running.
94    me.semaphore = 0;
95    me.asyncQueue = async.queue(function (task, callback) {
96        callback();
97    }, 1);
98
99    me.incrementSemaphore = function () {
100        me.asyncQueue.pause();
101        me.semaphore++;
102    };
103
104    me.decrementSemaphore = function () {
105        me.semaphore--;
106        if (me.semaphore == 0) {
107            me.asyncQueue.resume();
108        }
109    };
110
111    // Initialization function
112    me.init = function () {
113        var i;
114
115        // Load scroll position, if available.
116        me.loadScrollTop();
117
118        // Get slides from me.options.slides
119        for (i in me.options.slides) {
120            if ('content' in me.options.slides[i]) {
121                if (me.options.useSlideSources) {
122                    me.options.slides[i].source = me.options.slides[i].content;
123                }
124
125                me.options.slides[i].content = $('<div>').html(me.options.slides[i].content);
126            }
127
128            me.slides[i] = me.options.slides[i];
129        }
130        me.options.slides = null;
131
132        // Get slides from HTML. The first slide is considered the default one, while the rest are detached.
133        me.slideContainer.children('.theiaPostSlider_preloadedSlide').each(function (index, slide) {
134            index = me.options.defaultSlide + index;
135            slide = $(slide);
136            me.slides[index] = me.slides[index] || {};
137            me.slides[index].title = document.title;
138            me.slides[index].permalink = document.location.href;
139            me.slides[index].content = slide;
140
141            if (index != me.options.defaultSlide) {
142                slide.detach();
143            }
144        });
145
146        // Count the slides.
147        me.numberOfSlides = me.options.numberOfSlides;
148
149        // Setup the navigation bars.
150        for (i = 0; i < me.navEl.length; i++) {
151            var navEl = me.navEl[i];
152            navEl.text = navEl.container.find('._text');
153            navEl.prev = navEl.container.find('._prev')
154                .click(function (me) {
155                    return function (event) {
156                        me.onNavClick(this, 'prev', event);
157                    }
158                }(me));
159            navEl.next = navEl.container.find('._next')
160                .click(function (me) {
161                    return function (event) {
162                        me.onNavClick(this, 'next', event);
163                    }
164                }(me));
165
166            navEl.title = navEl.container.find('._title');
167
168            // Get the default slide's title. The title will be the same for all navigation bars, so get it only from the first.
169            if (i === 0) {
170                me.slides[me.options.defaultSlide].shortCodeTitle = navEl.title.html();
171            }
172
173            /*
174             Add _active class on mousedown. This is a fix for IE and Opera which don't match :active on container elements.
175             Also, return false to prevent double click context menu in Opera.
176             */
177            navEl.container.find('._prev, ._next')
178                .mousedown(function () {
179                    $(this).addClass('_active');
180                })
181                .mouseup(function () {
182                    $(this).removeClass('_active');
183                });
184        }
185
186        // Skip loading the slide if we're not going to display another one anyway.
187        if (me.numberOfSlides == 1 || (me.options.refreshAds && me.options.adRefreshingMechanism == 'page' && me.options.refreshAdsEveryNSlides <= 1)
187) {
188            me.currentSlide = me.options.defaultSlide;
189        }
190        else {
191            // Show the first slide
192            me.setSlide(me.options.defaultSlide);
193
194            // Add history handler.
195            var history = window.History;
196            if (history.enabled) {
197                history.Adapter.bind(window, 'statechange', function (me) {
198                    return function () {
199                        var state = History.getState();
200                        if (state.data.currentPostId != undefined) {
201                            if (state.data.currentSlide != undefined) {
202                                me.setSlide(state.data.currentSlide);
203                            }
204                            else {
205                                me.setSlide(me.options.defaultSlide);
206                            }
207                        }
208                    };
209                }(me));
210            }
211        }
212
213        // Set up touch events.
214        if (typeof Hammer !== 'undefined') {
215            me.previousTouch = 0;
216            me.minimumTimeBetweenGestures = 500;
217
218            // Eanble text selection.
219            delete Hammer.defaults.cssProps.userSelect;
220
221            // Create hammer.js instance.
222            var hammertime = new Hammer(me.slideContainer[0], {
223                inputClass: Hammer.TouchInput
224            });
225
226            hammertime
227                .on('swipeleft', function () {
228                    var t = (new Date).getTime();
229                    if (t - me.minimumTimeBetweenGestures >= me.previousTouch) {
230                        me.setNext();
231                        me.previousTouch = t;
232                    }
233                })
234                .on('swiperight', function () {
235                    var t = (new Date).getTime();
236                    if (t - me.minimumTimeBetweenGestures >= me.previousTouch) {
237                        me.setPrev();
238                        me.previousTouch = t;
239                    }
240                });
241        }
242
243        // Enable keyboard shortcuts
244        if (me.options.keyboardShortcuts) {
245            $(document).keydown(function (me) {
246                return function (e) {
247                    // Disable shortcut if there is more than one slideshow on the page.
248                    if (tps.slideshowsOnPage > 1) {
249                        return true;
250                    }
251
252                    // Disable shortcut if the target element is editable (input boxes, textareas, etc.).
253                    if (
254                        this !== e.target &&
255                        (
256                            /textarea|select/i.test(e.target.nodeName) ||
257                            e.target.type === "text" ||
258                            (
259                                $(e.target).prop &&
260                                $(e.target).prop('contenteditable') == 'true'
261                            )
262                        )
263                    ) {
264                        return true;
265                    }
266
267                    switch (e.which) {
268                        case 37:
269                            me.navEl[0].prev[0].click();
270                            return false;
271
272                        case 39:
273                            me.navEl[0].next[0].click();
274                            return false;
275                    }
276
277                    return true;
278                };
279            }(me));
280        }
281    };
282
283    // Load slides remotely
284    me.loadSlides = function (slides, callback) {
285        me.remoteLoadingQueue.push({name: ''}, function (me, slides, callback) {
286            return function (err) {
287                // Check if the slides are already loaded.
288                var allSlidesAreLoaded = true;
289                for (var i in slides) {
290                    if (!(slides[i] in me.slides) || !('content' in me.slides[slides[i]])) {
291                        allSlidesAreLoaded = false;
292                        break;
293                    }
294                }
295                if (allSlidesAreLoaded) {
296                    if (callback) {
297                        callback();
298                    }
299                    return;
300                }
301
302                // Load the slides and don't load anything else in the meantime.
303                me.remoteLoadingQueue.concurrency = 0;
304                $.ajax({
305                    method: 'POST',
306                    dataType: 'json',
307                    data: {
308                        action: 'tps_get_slides',
309                        postId: me.currentPostId,
310                        slides: slides
311                    },
312                    url: me.options.ajaxUrl,
313                    success: function (me) {
314                        return function (data) {
315                            if (!data) {
316                                return;
317                            }
318                            if (data.postId == me.currentPostId) {
319                                // Add each slide.
320                                for (var i in data.slides) {
321                                    if (!(i in me.slides)) {
322                                        me.slides[i] = {};
323                                    }
324
325                                    // Add content.
326                                    if ('content' in data.slides[i]) {
327                                        if (me.options.useSlideSources) {
328                                            data.slides[i].source = data.slides[i].content;
329                                        }
330
331                                        data.slides[i].content = $('<div>').html(data.slides[i].content);
332                                    }
333
334                                    // Overwrite old data with new data.
335                                    for (var j in data.slides[i]) {
336                                        me.slides[i][j] = data.slides[i][j];
337                                    }
338                                }
339                            }
340                            else {
341                                console.error('Received AJAX results for a different post ID.');
342                            }
343                        };
344                    }(me),
345                    complete: function (me, callback) {
346                        return function () {
347                            if (callback) {
348                                callback();
349                            }
350                            me.remoteLoadingQueue.concurrency = 1;
351                            me.remoteLoadingQueue.push({});
352                        };
353                    }(me, callback)
354                });
355            };
356        }(me, slides, callback));
357    };
358
359    // Set the current slide.
360    me.setSlide = function (index, isCallback) {
361        if (me.isLoading == true && isCallback != true) {
362            return;
363        }
364
365        // Is the slide already displayed?
366        if (me.currentSlide == index) {
367            return;
368        }
369
370        // Do we need to refresh the ads by refreshing the entire page?
371        if (me.needToRefreshPage() && index in me.slides) {
372            me.saveScrollTop();
373            window.location = me.slides[index].permalink;
374
375            return;
376        }
377
378        // Fire events.
379        $(document).trigger('theiaPostSlider.willChangeSlide', [index]);
380
381        // Is the slide not yet loaded?
382        if (!me.isSlideLoaded(index)) {
383            if (!isCallback) {
384                me.showLoading();
385                me.loadSlides([index], function (me, index) {
386                    return function () {
387                        me.hideLoading();
388                        me.setSlide(index, true);
389                    }
390                }(me, index));
391
392                return;
393            }
394            else {
395                // The slide could not be loaded via AJAX. Abort.
396                console.error("The slide could not be loaded via AJAX.");
397                return;
398            }
399        }
400
401        //
402        var slideContent = me.slides[index].source;
403        if (slideContent) {
404            for (i = 0; i < me.options.excludedWords.length; i++) {
405                var word = me.options.excludedWords[i];
406
407                // Check if word is actually a string.
408                if (typeof word !== 'string') {
409                    continue;
410                }
411
412                // Trim string.
413                word = word.trim();
414
415                // Length must be at least one.
416                if (word.length == 0) {
417                    continue;
418                }
419
420                // Search for string and redirect if necessary.
421                if (slideContent.indexOf(word) !== -1) {
422                    me.showLoading();
423                    window.location = me.slides[index].permalink;
424
425                    return;
426                }
427            }
428        }
429
430        var previousSlide = me.currentSlide;
431        me.currentSlide = index;
432
433        if (previousSlide != null) {
434            var i;
435
436            // Scroll the window up, if the beginning of the slide is out-of-view.
437            // Get the lowest offset.top
438            var scrollTop = me.slideContainer.offset().top;
439            for (i = 0; i < me.navEl.length; i++) {
440                scrollTop = Math.min(scrollTop, me.navEl[i].container.offset().top);
441            }
442            scrollTop += me.options.scrollTopOffset;
443            scrollTop = Math.max(0, scrollTop);
444            if ($(window).scrollTop() > scrollTop) {
445                $('body,html').animate({scrollTop: scrollTop});
446            }
447
448            // Remove number class.
449            for (i = 0; i < me.navEl.length; i++) {
450                var navEl = me.navEl[i];
451                navEl.container.removeClass('_slide_number_' + previousSlide);
452            }
453        }
454
455        // Set the title text.
456        me.updateTitleText();
457
458        // Change URL, but only if this isn't the first slide set (i.e. the default slide).
459        var history = window.History;
460        if (history.enabled) {
461            var url = me.slides[me.currentSlide].permalink;
462
463            // Replace protocol and domain (e.g. using CloudFlare's HTTPS from an HTTP source).
464            var a = document.createElement('a');
465            a.href = url;
466            url = window.location.protocol + '//' + window.location.host + a.pathname + a.search + a.hash;
467
468            if (url && previousSlide !== null) {
469                var f;
470                if (url == window.location) {
471                    f = history.replaceState;
472                }
473                else {
474                    f = history.pushState;
475                }
476                f({
477                    currentSlide: index,
478                    currentPostId: me.currentPostId
479                }, me.slides[me.currentSlide].title, url);
480            }
481        }
482
483        // Show the slide.
484        me.asyncQueue.push({name: ''}, me.showSlide);
485
486        // Set the navigation bars.
487        me.updateNavigationBars();
488
489        // Preload, but only if we don't have to refresh the page immediately after.
490        if (
491            !(
492                me.options.refreshAds &&
493                me.slidesSinceLastAdRefresh + 1 >= me.options.refreshAdsEveryNSlides &&
494                me.options.adRefreshingMechanism == 'page'
495            )
496        ) {
497            // Direction is either +1 if the user is browsing forward (i.e. using the "next" button), or -1 otherwise.
498            var direction;
499            if (previousSlide == null) {
500                direction = 1;
501            }
502            else if (me.currentSlide == 0 && previousSlide == me.numberOfSlides - 1) {
503                direction = 1;
504            }
505            else if (me.currentSlide == me.numberOfSlides - 1 && previousSlide == 0) {
506                direction = -1;
507            }
508            else {
509                direction = me.currentSlide - previousSlide;
510                direction = Math.max(Math.min(direction, 1), -1);
511            }
512
513            var slideToPreload = me.currentSlide + direction;
514
515            // If the loop-slides settings is activated, also preload the first/last slide when applicable.
516            if (slideToPreload == -1 && me.options.loopSlides) {
517                slideToPreload = me.numberOfSlides - 1;
518            }
519            else if (slideToPreload == me.numberOfSlides && me.options.loopSlides) {
520                slideToPreload = 0;
521            }
522
523            if (
524                slideToPreload >= 0 &&
525                slideToPreload < me.numberOfSlides && !me.isSlideLoaded((slideToPreload))
526            ) {
527                me.loadSlides([slideToPreload]);
528            }
529
530        }
531    };
532
533    // Show (display) the current slide using the chosen animation.
534    me.showSlide = function () {
535        // Don't do anything if the current slide is already shown.
536        if (me.currentlyDisplayedSlide == me.currentSlide) {
537            return;
538        }
539
540        // Track the pageview if this isn't the first slide displayed.
541        if (me.currentlyDisplayedSlide != null && me.slides[me.currentSlide]['permalink']) {
542            // URL Path
543            var path = me.slides[me.currentSlide]['permalink'].split('/');
544            if (path.length >= 4) {
545                path = '/' + path.slice(3).join('/');
546
547                // Global Site Tag (gtag.js)
548                // See: https://developers.google.com/analytics/devguides/collection/gtagjs/migration
549                if (typeof gtag !== 'undefined') {
550                    // Search for UA tag.
551                    var tag = '';
552                    for (var i = 0; i < window.dataLayer.length; i++) {
553                        if (window.dataLayer[i].length >= 1 && window.dataLayer[i][0] === 'config') {
554                            tag = window.dataLayer[i][1];
555                            break;
556                        }
557                    }
558                    gtag('config', tag, {
559                        'page_path': path
560                    });
561                }
562                // Google Analytics (ga.js, deprecated, but preferred if available)
563                // If using both old and new versions, the new version sometimes does not work.
564                // See http://stackoverflow.com/questions/18696998/ga-or-gaq-push-for-google-analytics-event-tracking
565                else if (typeof _gaq !== 'undefined' && typeof _gaq.pu
565sh !== 'undefined') {
566                    _gaq.push(['_trackPageview', path]);
567                }
568                // Google Analytics by Yoast, which renames the "ga" variable.
569                else if (typeof __gaTracker !== 'undefined') {
570                    __gaTracker('set', 'page', path);
571                    __gaTracker('send', 'pageview', path);
572                }
573                // Google Analytics (Analytics.js).
574                else if (typeof ga !== 'undefined') {
575                    ga('set', 'page', path);
576                    ga('send', 'pageview', path);
577                }
578                // Google Analytics Traditional.
579                else if (typeof pageTracker !== 'undefined' && typeof pageTracker._trackPageview !== 'undefined') {
580                    pageTracker._trackPageview(path);
581                }
582
583                // Piwik
584                if (typeof piwikTracker !== 'undefined' && typeof piwikTracker.trackPageView !== 'undefined') {
585                    piwikTracker.trackPageView(path);
586                }
587
588                // StatCounter
589                if (typeof sc_project !== 'undefined' && typeof sc_security !== 'undefined') {
590                    var img = new Image();
591                    img.src = '//c.statcounter.com/' + sc_project + '/0/' + sc_security + '/1/';
592                }
593
594                // Quantcast
595                if (typeof _qacct !== 'undefined') {
596                    var img = new Image();
597                    img.src = '//pixel.quantserve.com/pixel/' + _qacct + '.gif';
598                }
599            }
600        }
601
602        var previousIndex = me.currentlyDisplayedSlide;
603        me.currentlyDisplayedSlide = me.currentSlide;
604
605        me.createSlideContentFromSource(me.slides[me.currentSlide]);
606
607        // Change the slide while applying a certain effect/animation.
608        var animationsQueue = tps.transitions[me.options.transitionEffect](me, previousIndex, me.currentlyDisplayedSlide);
609
610        // Execute all "attachAnimation" methods before starting any animation.
611        // Otherwise, we might get a race condition when one animation finishes before others are started,
612        // thus triggering unwanted events before all animations have ended.
613        for (var i = 0; i < animationsQueue.length; i++) {
614            me.incrementSemaphore();
615        }
616
617        // This will be called after all animations finish, before any other items in the queue.
618        if (previousIndex !== null) {
619            me.asyncQueue.unshift({name: ''}, function (me, previousIndex) {
620                return function () {
621                    me.onRemovedSlide(previousIndex);
622                }
623            }(me, previousIndex));
624        }
625
626        // Start all animations.
627        for (var i = 0; i < animationsQueue.length; i++) {
628            animationsQueue[i]();
629        }
630    };
631
632    me.createSlideContentFromSource = function (slide) {
633        if (!('content' in slide) && ('source' in slide)) {
634            slide.content = $('<div>').html(slide.source);
635
636            if (false == me.options.useSlideSources) {
637                delete slide.source;
638            }
639        }
640    };
641
642    me.isSlideLoaded = function (index) {
643        if (!(index in me.slides)) {
644            return false;
645        }
646
647        // Only if this isn't the first slide.
648        if (me.currentlyDisplayedSlide !== null && me.options.useSlideSources && !('source' in me.slides[index])) {
649            return false;
650        }
651
652        if (!(('content' in me.slides[index]) || ('source' in me.slides[index]))) {
653            return false;
654        }
655
656        return true;
657    };
658
659    // Function that is called right after a new slide has been added to the DOM, and right before the animation (if available) has started.
660    me.onNewSlide = function () {
661        // "BJ Lazy Load" plugin.
662        $(".lazy-hidden").not(".data-lazy-ready").one("scrollin.bj_lazy_load", {
663            distance: 200
664        }, function () {
665            var b = $(this),
666                d = b.attr("data-lazy-type");
667            if (d == "image") {
668                b.hide().attr("src", b.attr("data-lazy-src")).removeClass("lazy-hidden").fadeIn()
669            } else if (d == "iframe") {
670                b.replaceWith(c(b.attr("data-lazy-src")))
671            }
672        }).addClass("data-lazy-ready");
673
674        // "Lazy Load" plugin.
675        var events = $('body').data('events');
676        if (events && events['post-load']) {
677            for (var i = 0; i < events['post-load'].length; i++) {
678                if (events['post-load'][i].handler.name == 'lazy_load_init') {
679                    events['post-load'][i].handler();
680                }
681            }
682        }
683
684        // WordPress [audio] and [video] shortcodes.
685        if (typeof _wpmejsSettings !== 'undefined') {
686            $('.wp-audio-shortcode, .wp-video-shortcode').mediaelementplayer(_wpmejsSettings);
687        }
688
689        // Instagram embeds.
690        if (typeof instgrm !== 'undefined' && typeof instgrm.Embeds !== 'undefined' && typeof instgrm.Embeds.process !== 'undefined') {
691            instgrm.Embeds.process();
692        }
693
694        // Fire events.
695        $(document).trigger('theiaPostSlider.changeSlide', [me.currentSlide]);
696    };
697
698    // Function that is called right after a slide has been removed from the DOM.
699    me.onRemovedSlide = function (slideId) {
700        if (me.options.useSlideSources) {
701            me.slides[slideId].content.remove();
702            delete me.slides[slideId].content;
703        }
704
705        // Refresh ads using JavaScript.
706        if (me.options.refreshAds) {
707            me.slidesSinceLastAdRefresh++;
708
709            if (me.slidesSinceLastAdRefresh >= me.options.refreshAdsEveryNSlides) {
710                me.slidesSinceLastAdRefresh = 0;
711
712                if (me.options.adRefreshingMechanism == 'javascript') {
713                    var p = null;
714
715                    if (typeof pubService === 'undefined') {
716                        if (typeof googletag !== 'undefined' && typeof googletag.pubads === 'function') {
717                            p = googletag.pubads();
718                        }
719                    }
720                    else {
721                        p = pubService;
722                    }
723
724                    if (p && typeof p.refresh === 'function') {
725                        p.refresh();
726                    }
727
728                    $(document).trigger('theiaPostSlider.refreshAds');
729                }
730            }
731        }
732    };
733
734    // Update the title text.
735    me.updateTitleText = function () {
736        var shortCodeTitle = me.slides[me.currentSlide].shortCodeTitle;
737        if (!shortCodeTitle) {
738            shortCodeTitle = '<span class="_helper">' + me.options['helperText'] + '</span>';
739        }
740        for (i = 0; i < me.navEl.length; i++) {
741            me.navEl[i].title.html(shortCodeTitle);
742        }
743    };
744
745    // Update the navigation bar's text and buttons.
746    me.updateNavigationBars = function () {
747        for (var i = 0; i < me.navEl.length; i++) {
748            var navEl = me.navEl[i];
749            var navText;
750            if (me.numberOfSlides == 1) {
751                navText = '';
752            }
753            else {
754                navText = me.options.navText;
755                navText = navText.replace('%{currentSlide}', me.currentSlide + 1);
756                navText = navText.replace('%{totalSlides}', me.numberOfSlides);
757            }
758            navEl.text.html(navText);
759
760            // Set number class.
761            navEl.container.addClass('_slide_number_' + me.currentSlide);
762
763            // Set first and last classes.
764            navEl.container.removeClass('_first_slide _last_slide _middle_slide');
765            if (me.currentSlide === 0) {
766                navEl.container.addClass('_first_slide');
767            }
768            else if (me.currentSlide === me.numberOfSlides - 1) {
769                navEl.container.addClass('_last_slide');
770            }
771            else {
772                navEl.container.addClass('_middle_slide');
773            }
774
775            // Update buttons.
776            me.updateNavigationBarButton(navEl, false);
777            me.updateNavigationBarButton(navEl, true);
778        }
779    };
780
781    // Update a button from a navigation bar.
782    me.updateNavigationBarButton = function (navEl, direction) {
783        var width,
784            html1 = '',
785            html2 = '',
786            html3 = '',
787            href,
788            directionName = direction ? 'next' : 'prev',
789            buttonEl = navEl[directionName];
790
791        if (me.options.themeType == 'font') {
792            width = 0;
793            html2 = me.options[directionName + 'FontIcon'];
794
795            if (direction == false) {
796                if (me.options.prevText_post) {
797                    if (me.currentSlide == 0) {
798                        html3 = me.options.prevText_post;
799                    } else {
800                        html3 = me.options.prevText;
801                    }
802                } else {
803                    html3 = me.options.prevText;
804                }
805            } else {
806                if (me.options.nextText_post) {
807                    if (me.currentSlide == me.numberOfSlides - 1) {
808                        html1 = me.options.nextText_post;
809                    } else {
810                        html1 = me.options.nextText;
811                    }
812                } else {
813                    html1 = me.options.nextText;
814                }
815            }
816        } else {
817            width = me.options.buttonWidth;
818
819            if (
820                (direction == false && me.options.prevPost && me.currentSlide == 0) ||
821                (direction == true && me.options.nextPost && me.currentSlide == me.numberOfSlides - 1)
822            ) {
823                html2 = me.options[directionName + 'Text_post'];
824                href = direction ? me.options.nextPost : me.options.prevPost;
825            }
826            else {
827                html2 = me.options[directionName + 'Text'];
828            }
829        }
830
831        // Set link.
832        {
833            var jumpToSlide = null;
834            if (direction == false && me.options.loopSlides && me.currentSlide == 0) {
835                jumpToSlide = me.numberOfSlides - 1;
836            }
837            else if (direction == true && me.options.loopSlides && me.currentSlide == me.numberOfSlides - 1) {
838                jumpToSlide = 0;
839            }
840            else if (
841                (direction == false && me.options.prevPost && me.currentSlide == 0) ||
842                (direction == true && me.options.nextPost && me.currentSlide == me.numberOfSlides - 1)
843            ) {
844                buttonEl.addClass('_another_post');
845                href = direction ? me.options.nextPost : me.options.prevPost;
846            } else {
847                buttonEl.removeClass('_another_post');
848                jumpToSlide = me.currentSlide + (direction ? 1 : -1);
849            }
850
851            if (jumpToSlide !== null) {
852                if (me.needToRefreshPage()) {
853                    var slide = me.slides[jumpToSlide];
854                    if (slide) {
855                        href = slide.permalink;
856                    }
857                }
858                else {
859                    href = '#';
860                }
861            }
862        }
863
864        buttonEl.find('._1').html(html1);
865        buttonEl.find('._2')
866            .css('width', width > 0 ? width : '')
867            .html(html2);
868        buttonEl.find('._3').html(html3);
869
870        // Disable or enable
871        if (
872            (direction == false && me.options.prevPost == null && !me.options.loopSlides && me.currentSlide == 0) ||
873            (direction == true && me.options.nextPost == null && !me.options.loopSlides && me.currentSlide == me.numberOfSlides - 1)
874        ) {
875            buttonEl.addClass('_disabled');
876            href = '#';
877        }
878        else {
879            buttonEl.removeClass('_disabled');
880        }
881
882        buttonEl.attr('href', href);
883    };
884
885    // Handler for previous and next buttons.
886    me.onNavClick = function (that, direction, event) {
887        var $that = $(that);
888
889        if (typeof $that.attr('href') === 'undefined') {
890            return;
891        }
892
893        // Jump to another page.
894        // Some 3rd party plugins misbehave and turn the '#' into '', namely https://github.com/medialize/URI.js with "Blackout Image Gallery".
895        if ($that.attr('href') != '#' && $that.attr('href') != '') {
896            me.showLoading();
897            me.saveScrollTop();
898            return;
899        }
900
901        if (direction == 'prev') {
902            me.setPrev();
903        } else {
904            me.setNext();
905        }
906
907        $that.focus();
908        if (event) {
909            event.preventDefault();
910        }
911    };
912
913    me.isHtml5StorageAvailable = function () {
914        try {
915            return 'localStorage' in window && window['localStorage'] !== null;
916        } catch (e) {
917            return false;
918        }
919    };
920
921    me.saveScrollTop = function () {
922        if (!me.options.scrollAfterRefresh) {
923            return;
924        }
925
926        if (!me.isHtml5StorageAvailable) {
927            return;
928        }
929
930        localStorage.setItem('scrollTop', JSON.stringify({
931            postId: me.postId,
932            scrollTop: $(window).scrollTop()
933        }));
934    };
935
936    me.loadScrollTop = function () {
937        if (!me.options.scrollAfterRefresh) {
938            return;
939        }
940
941        if (!me.isHtml5StorageAvailable) {
942            return;
943        }
944
945        var data = JSON.parse(localStorage.getItem('scrollTop'));
946        if (data && data.postId == me.postId) {
947            var scrollTop = Math.min(data.scrollTop, me.slideContainer.offset().top);
948            $(window).scrollTop(scrollTop);
949        }
950
951        localStorage.removeItem('scrollTop');
952    };
953
954    // Go to the previous slide.
955    me.setPrev = function () {
956        if (me.currentSlide == 0) {
957            if (me.options.loopSlides) {
958                me.setSlide(me.numberOfSlides - 1);
959            }
960            else if (me.options.prevPost) {
961                me.showPost(me.options.prevPost);
962            }
963        }
964        else {
965            me.setSlide(me.currentSlide - 1);
966        }
967    };
968
969    // Go to the next slide.
970    me.setNext = function () {
971        if (me.currentSlide == me.numberOfSlides - 1) {
972            if (me.options.loopSlides) {
973                me.setSlide(0);
974            }
975            else if (me.options.nextPost) {
976                me.showPost(me.options.nextPost);
977            }
978        }
979        else {
980            me.setSlide(me.currentSlide + 1);
981        }
982    };
983
984    // Go to another post. This method will be called when navigating using the keyboard shortcuts.
985    me.showPost = function (postUrl) {
986        document.location = postUrl;
987    };
988
989    // Set the transition properties (used in Live Preview).
990    me.setTransition = function (options) {
991        var defaults = {
992            'effect': me.options.transitionEffect,
993            'speed': me.options.transitionSpeed
994        };
995        options = $.extend(defaults, options);
996        me.options.transitionEffect = options.effect;
997        me.options.transitionSpeed = options.speed;
998    };
999
1000    // Set the navigation bar's text template (used in Live Preview).
1001    me.setNavText = function (text) {
1002        me.options.navText = text;
1003        me.updateNavigationBars();
1004    };
1005
1006    // Set the title for all slides (used in Live Preview).
1007    me.setTitleText = function (text) {
1008        for (i = 0; i < me.slides.length; i++) {
1009            me.slides[i].shortCodeTitle = '';
1010        }
1011        me.options.helperText = text;
1012        me.updateTitleText();
1013    };
1014
1015    me.showLoading = function () {
1016        me.isLoading = true;
1017        for (i = 0; i < me.navEl.length; i++) {
1018            me.navEl[i].container
1019                .append($('<div class="_loading"></div>'))
1020                .find('._buttons > a').addClass('_disabled');
1021        }
1022    };
1023
1024    me.hideLoading = function () {
1025        me.isLoading = false;
1026        for (i = 0; i < me.navEl.length; i++) {
1027            me.navEl[i].container.find('._loading').remove();
1028        }
1029        me.updateNavigationBars();
1030    };
1031
1032    me.needToRefreshPage = function () {
1033        return (
1034            me.currentSlide !== null &&
1035            me.options.refreshAds &&
1036            me.slidesSinceLastAdRefresh + 1 >= me.options.refreshAdsEveryNSlides &&
1037            me.options.adRefreshingMechanism == 'page'
1038        );
1039    };
1040
1041    // Initialize the slider.
1042    me.init();
1043
1044    return me;
1045};

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.