PageSourceSearch

https://faccwdc.org/sites/faccwdc.org/themes/Porto/js/theme.js?tlwd9d

js faccwdc.org collected 2026-09-28 10:37:51 UTC 81,626 bytes, 3,082 lines download raw bytes

1/*
2 Name: 			Theme Base
3 Written by: 	Okler Themes - (http://www.okler.net)
4 Theme Version:	5.2.0
5 */
6
7// Theme
8window.theme = {};
9
10// Animate
11(function(theme, $) {
12
13    theme = theme || {};
14
15    var instanceName = '__animate';
16
17    var PluginAnimate = function($el, opts) {
18        return this.initialize($el, opts);
19    };
20
21    PluginAnimate.defaults = {
22        accX: 0,
23        accY: -150,
24        delay: 1,
25        duration: '1s'
26    };
27
28    PluginAnimate.prototype = {
29        initialize: function($el, opts) {
30            if ($el.data(instanceName)) {
31                return this;
32            }
33
34            this.$el = $el;
35
36            this
37                .setData()
38                .setOptions(opts)
39                .build();
40
41            return this;
42        },
43
44        setData: function() {
45            this.$el.data(instanceName, this);
46
47            return this;
48        },
49
50        setOptions: function(opts) {
51            this.options = $.extend(true, {}, PluginAnimate.defaults, opts, {
52                wrapper: this.$el
53            });
54
55            return this;
56        },
57
58        build: function() {
59            var self = this,
60                $el = this.options.wrapper,
61                delay = 0,
62                duration = '1s';
63
64            $el.addClass('appear-animation animated');
65
66            if (!$('html').hasClass('no-csstransitions') && $(window).width() > 767) {
67
68                $el.appear(function() {
69
70                    $el.one('animation:show', function(ev) {
71                        delay = ($el.attr('data-appear-animation-delay') ? $el.attr('data-appear-animation-delay') : self.options.delay);
72                        duration = ($el.attr('data-appear-animation-duration') ? $el.attr('data-appear-animation-duration') : self.options.duration);
73
74                        if (duration != '1s') {
75                            $el.css('animation-duration', duration);
76                        }
77
78                        setTimeout(function() {
79                            $el.addClass($el.attr('data-appear-animation') + ' appear-animation-visible');
80                        }, delay);
81                    });
82
83                    $el.trigger('animation:show');
84
85                }, {
86                    accX: self.options.accX,
87                    accY: self.options.accY
88                });
89
90            } else {
91
92                $el.addClass('appear-animation-visible');
93
94            }
95
96            return this;
97        }
98    };
99
100    // expose to scope
101    $.extend(theme, {
102        PluginAnimate: PluginAnimate
103    });
104
105    // jquery plugin
106    $.fn.themePluginAnimate = function(opts) {
107        return this.map(function() {
108            var $this = $(this);
109
110            if ($this.data(instanceName)) {
111                return $this.data(instanceName);
112            } else {
113                return new PluginAnimate($this, opts);
114            }
115
116        });
117    };
118
119}).apply(this, [window.theme, jQuery]);
120
121// Carousel
122(function(theme, $) {
123
124    theme = theme || {};
125
126    var instanceName = '__carousel';
127
128    var PluginCarousel = function($el, opts) {
129        return this.initialize($el, opts);
130    };
131
132    PluginCarousel.defaults = {
133        loop: true,
134        responsive: {
135            0: {
136                items: 1
137            },
138            479: {
139                items: 1
140            },
141            768: {
142                items: 2
143            },
144            979: {
145                items: 3
146            },
147            1199: {
148                items: 4
149            }
150        },
151        navText: []
152    };
153
154    PluginCarousel.prototype = {
155        initialize: function($el, opts) {
156            if ($el.data(instanceName)) {
157                return this;
158            }
159
160            this.$el = $el;
161
162            this
163                .setData()
164                .setOptions(opts)
165                .build();
166
167            return this;
168        },
169
170        setData: function() {
171            this.$el.data(instanceName, this);
172
173            return this;
174        },
175
176        setOptions: function(opts) {
177            this.options = $.extend(true, {}, PluginCarousel.defaults, opts, {
178                wrapper: this.$el
179            });
180
181            return this;
182        },
183
184        build: function() {
185            if (!($.isFunction($.fn.owlCarousel))) {
186                return this;
187            }
188
189            var self = this,
190                $el = this.options.wrapper;
191
192            // Add Theme Class
193            $el.addClass('owl-theme');
194
195            // Force RTL according to HTML dir attribute
196            if ($('html').attr('dir') == 'rtl') {
197                this.options = $.extend(true, {}, this.options, {
198                    rtl: true
199                });
200            }
201
202            if (this.options.items == 1) {
203                this.options.responsive = {}
204            }
205
206            if (this.options.items > 4) {
207                this.options = $.extend(true, {}, this.options, {
208                    responsive: {
209                        1199: {
210                            items: this.options.items
211                        }
212                    }
213                });
214            }
215
216            // Auto Height Fixes
217            if (this.options.autoHeight) {
218                $(window).afterResize(function() {
219                    $el.find('.owl-stage-outer').height( $el.find('.owl-item.active').height() );
220                });
221
222                $(window).on('load', function() {
223                    $el.find('.owl-stage-outer').height( $el.find('.owl-item.active').height() );
224                });
225            }
226
227            // Initialize OwlCarousel
228            $el.owlCarousel(this.options).addClass('owl-carousel-init');
229
230            return this;
231        }
232    };
233
234    // expose to scope
235    $.extend(theme, {
236        PluginCarousel: PluginCarousel
237    });
238
239    // jquery plugin
240    $.fn.themePluginCarousel = function(opts) {
241        return this.map(function() {
242            var $this = $(this);
243
244            if ($this.data(instanceName)) {
245                return $this.data(instanceName);
246            } else {
247                return new PluginCarousel($this, opts);
248            }
249
250        });
251    }
252
253}).apply(this, [window.theme, jQuery]);
254
255// Chart Circular
256(function(theme, $) {
257
258    theme = theme || {};
259
260    var instanceName = '__chartCircular';
261
262    var PluginChartCircular = function($el, opts) {
263        return this.initialize($el, opts);
264    };
265
266    PluginChartCircular.defaults = {
267        accX: 0,
268        accY: -150,
269        delay: 1,
270        barColor: '#0088CC',
271        trackColor: '#f2f2f2',
272        scaleColor: false,
273        scaleLength: 5,
274        lineCap: 'round',
275        lineWidth: 13,
276        size: 175,
277        rotate: 0,
278        animate: ({
279            duration: 2500,
280            enabled: true
281        })
282    };
283
284    PluginChartCircular.prototype = {
285        initialize: function($el, opts) {
286            if ($el.data(instanceName)) {
287                return this;
288            }
289
290            this.$el = $el;
291
292            this
293                .setData()
294                .setOptions(opts)
295                .build();
296
297            return this;
298        },
299
300        setData: function() {
301            this.$el.data(instanceName, this);
302
303            return this;
304        },
305
306        setOptions: function(opts) {
307            this.options = $.extend(true, {}, PluginChartCircular.defaults, opts, {
308                wrapper: this.$el
309            });
310
311            return this;
312        },
313
314        build: function() {
315            if (!($.isFunction($.fn.appear)) || !($.isFunction($.fn.easyPieChart))) {
316                return this;
317            }
318
319            var self = this,
320                $el = this.options.wrapper,
321                value = ($el.attr('data-percent') ? $el.attr('data-percent') : 0),
322                percentEl = $el.find('.percent');
323
324            $.extend(true, self.options, {
325                onStep: function(from, to, currentValue) {
326                    percentEl.html(parseInt(currentValue));
327                }
328            });
329
330            $el.attr('data-percent', 0);
331
332            $el.appear(function() {
333
334                $el.easyPieChart(self.options);
335
336                setTimeout(function() {
337
338                    $el.data('easyPieChart').update(value);
339                    $el.attr('data-percent', value);
340
341                }, self.options.delay);
342
343            }, {
344                accX: self.options.accX,
345                accY: self.options.accY
346            });
347
348            return this;
349        }
350    };
351
352    // expose to scope
353    $.extend(theme, {
354        PluginChartCircular: PluginChartCircular
355    });
356
357    // jquery plugin
358    $.fn.themePluginChartCircular = function(opts) {
359        return this.map(function() {
360            var $this = $(this);
361
362            if ($this.data(instanceName)) {
363                return $this.data(instanceName);
364            } else {
365                return new PluginChartCircular($this, opts);
366            }
367
368        });
369    }
370
371}).apply(this, [window.theme, jQuery]);
372
373// Counter
374(function(theme, $) {
375
376    theme = theme || {};
377
378    var instanceName = '__counter';
379
380    var PluginCounter = function($el, opts) {
381        return this.initialize($el, opts);
382    };
383
384    PluginCounter.defaults = {
385        accX: 0,
386        accY: 0,
387        speed: 1000,
388        refreshInterval: 100,
389        decimals: 0,
390        onUpdate: null,
391        onComplete: null
392    };
393
394    PluginCounter.prototype = {
395        initialize: function($el, opts) {
396            if ($el.data(instanceName)) {
397                return this;
398            }
399
400            this.$el = $el;
401
402            this
403                .setData()
404                .setOptions(opts)
405                .build();
406
407            return this;
408        },
409
410        setData: function() {
411            this.$el.data(instanceName, this);
412
413            return this;
414        },
415
416        setOptions: function(opts) {
417            this.options = $.extend(true, {}, PluginCounter.defaults, opts, {
418                wrapper: this.$el
419            });
420
421            return this;
422        },
423
424        build: function() {
425            if (!($.isFunction($.fn.countTo))) {
426                return this;
427            }
428
429            var self = this,
430                $el = this.options.wrapper;
431
432            $.extend(self.options, {
433                onComplete: function() {
434                    if ($el.data('append')) {
435                        $el.html($el.html() + $el.data('append'));
436                    }
437
438                    if ($el.data('prepend')) {
439                        $el.html($el.data('prepend') + $el.html());
440                    }
441                }
442            });
443
444            $el.appear(function() {
445
446                $el.countTo(self.options);
447
448            }, {
449                accX: self.options.accX,
450                accY: self.options.accY
451            });
452
453            return this;
454        }
455    };
456
457    // expose to scope
458    $.extend(theme, {
459        PluginCounter: PluginCounter
460    });
461
462    // jquery plugin
463    $.fn.themePluginCounter = function(opts) {
464        return this.map(function() {
465            var $this = $(this);
466
467            if ($this.data(instanceName)) {
468                return $this.data(instanceName);
469            } else {
470                return new PluginCounter($this, opts);
471            }
472
473        });
474    }
475
476}).apply(this, [window.theme, jQuery]);
477
478// Lazy Load
479(function(theme, $) {
480
481    theme = theme || {};
482
483    var instanceName = '__lazyload';
484
485    var PluginLazyLoad = function($el, opts) {
486        return this.initialize($el, opts);
487    };
488
489    PluginLazyLoad.defaults = {
490        effect: 'show',
491        appearEffect: '',
492        appear: function(elements_left, settings) {
493
494        },
495        load: function(elements_left, settings) {
496            $(this).addClass($.trim('lazy-load-loaded ' + settings.appearEffect));
497        }
498    };
499
500    PluginLazyLoad.prototype = {
501        initialize: function($el, opts) {
502            if ($el.data(instanceName)) {
503                return this;
504            }
505
506            this.$el = $el;
507
508            this
509                .setData()
510                .setOptions(opts)
511                .build();
512
513            return this;
514        },
515
516        setData: function() {
517            this.$el.data(instanceName, this);
518
519            return this;
520        },
521
522        setOptions: function(opts) {
523            this.options = $.extend(true, {}, PluginLazyLoad.defaults, opts, {
524                wrapper: this.$el
525            });
526
527            return this;
528        },
529
530        build: function() {
531            if (!($.isFunction($.fn.lazyload))) {
532                return this;
533            }
534
535            var self = this;
536
537            self.options.wrapper.lazyload(this.options);
538
539            return this;
540        }
541    };
542
543    // expose to scope
544    $.extend(theme, {
545        PluginLazyLoad: PluginLazyLoad
546    });
547
548    // jquery plugin
549    $.fn.themePluginLazyLoad = function(opts) {
550        return this.map(function() {
551            var $this = $(this);
552
553            if ($this.data(instanceName)) {
554                return $this.data(instanceName);
555            } else {
556                return new PluginLazyLoad($this, opts);
557            }
558
559        });
560    }
561
562}).apply(this, [window.theme, jQuery]);
563
564// Lightbox
565(function(theme, $) {
566
567    theme = theme || {};
568
569    var instanceName = '__lightbox';
570
571    var PluginLightbox = function($el, opts) {
572        return this.initialize($el, opts);
573    };
574
575    PluginLightbox.defaults = {
576        tClose: 'Close (Esc)', // Alt text on close button
577        tLoading: 'Loading...', // Text that is displayed during loading. Can contain %curr% and %total% keys
578        gallery: {
579            tPrev: 'Previous (Left arrow key)', // Alt text on left arrow
580            tNext: 'Next (Right arrow key)', // Alt text on right arrow
581            tCounter: '%curr% of %total%' // Markup for "1 of 7" counter
582        },
583        image: {
584            tError: '<a href="%url%">The image</a> could not be loaded.' // Error message when image could not be loaded
585        },
586        ajax: {
587            tError: '<a href="%url%">The content</a> could not be loaded.' // Error message when ajax request failed
588        },
589        callbacks: {
590            open: function() {
591                $('html').addClass('lightbox-opened');
592            },
593            close: function() {
594                $('html').removeClass('lightbox-opened');
595            }
596        }
597    };
598
599    PluginLightbox.prototype = {
600        initialize: function($el, opts) {
601            if ($el.data(instanceName)) {
602                return this;
603            }
604
605            this.$el = $el;
606
607            this
608                .setData()
609                .setOptions(opts)
610                .build();
611
612            return this;
613        },
614
615        setData: function() {
616            this.$el.data(instanceName, this);
617
618            return this;
619        },
620
621        setOptions: function(opts) {
622            this.options = $.extend(true, {}, PluginLightbox.defaults, opts, {
623                wrapper: this.$el
624            });
625
626            return this;
627        },
628
629        build: function() {
630            if (!($.isFunction($.fn.magnificPopup))) {
631                return this;
632            }
633
634            this.options.wrapper.magnificPopup(this.options);
635
636            return this;
637        }
638    };
639
640    // expose to scope
641    $.extend(theme, {
642        PluginLightbox: PluginLightbox
643    });
644
645    // jquery plugin
646    $.fn.themePluginLightbox = function(opts) {
647        return this.map(function() {
648            var $this = $(this);
649
650            if ($this.data(instanceName)) {
651                return $this.data(instanceName);
652            } else {
653                return new PluginLightbox($this, opts);
654            }
655
656        });
657    }
658
659}).apply(this, [window.theme, jQuery]);
660
661// Loading Overlay
662(function(theme, $) {
663
664    'use strict';
665
666    theme = theme || {};
667
668    var loadingOverlayTemplate = [
669        '<div class="loading-overlay">',
670        '<div class="bounce-loader"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>',
671        '</div>'
672    ].join('');
673
674    var LoadingOverlay = function( $wrapper, options ) {
675        return this.initialize( $wrapper, options );
676    };
677
678    LoadingOverlay.prototype = {
679
680        options: {
681            css: {}
682        },
683
684        initialize: function( $wrapper, options ) {
685            this.$wrapper = $wrapper;
686
687            this
688                .setVars()
689                .setOptions( options )
690                .build()
691                .events();
692
693            this.$wrapper.data( 'loadingOverlay', this );
694        },
695
696        setVars: function() {
697            this.$overlay = this.$wrapper.find('.loading-overlay');
698
699            return this;
700        },
701
702        setOptions: function( options ) {
703            if ( !this.$overlay.get(0) ) {
704                this.matchProperties();
705            }
706            this.options     = $.extend( true, {}, this.options, options );
707            this.loaderClass = this.getLoaderClass( this.options.css.backgroundColor );
708
709            return this;
710        },
711
712        build: function() {
713            if ( !this.$overlay.closest(document.documentElement).get(0) ) {
714                if ( !this.$cachedOverlay ) {
715                    this.$overlay = $( loadingOverlayTemplate ).clone();
716
717                    if ( this.options.css ) {
718                        this.$overlay.css( this.options.css );
719                        this.$overlay.find( '.loader' ).addClass( this.loaderClass );
720                    }
721                } else {
722                    this.$overlay = this.$cachedOverlay.clone();
723                }
724
725                this.$wrapper.append( this.$overlay );
726            }
727
728            if ( !this.$cachedOverlay ) {
729                this.$cachedOverlay = this.$overlay.clone();
730            }
731
732            return this;
733        },
734
735        events: function() {
736            var _self = this;
737
738            if ( this.options.startShowing ) {
739                _self.show();
740            }
741
742            if ( this.$wrapper.is('body') || this.options.hideOnWindowLoad ) {
743                $( window ).on( 'load error', function() {
744                    _self.hide();
745                });
746            }
747
748            if ( this.options.listenOn ) {
749                $( this.options.listenOn )
750                    .on( 'loading-overlay:show beforeSend.ic', function( e ) {
751                        e.stopPropagation();
752                        _self.show();
753                    })
754                    .on( 'loading-overlay:hide complete.ic', function( e ) {
755                        e.stopPropagation();
756                        _self.hide();
757                    });
758            }
759
760            this.$wrapper
761                .on( 'loading-overlay:show beforeSend.ic', function( e ) {
762                    if ( e.target === _self.$wrapper.get(0) ) {
763                        e.stopPropagation();
764                        _self.show();
765                        return true;
766                    }
767                    return false;
768                })
769                .on( 'loading-overlay:hide complete.ic', function( e ) {
770                    if ( e.target === _self.$wrapper.get(0) ) {
771                        e.stopPropagation();
772                        _self.hide();
773                        return true;
774                    }
775                    return false;
776                });
777
778            return this;
779        },
780
781        show: function() {
782            this.build();
783
784            this.position = this.$wrapper.css( 'position' ).toLowerCase();
785            if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
786                this.$wrapper.css({
787                    position: 'relative'
788                });
789            }
790            this.$wrapper.addClass( 'loading-overlay-showing' );
791        },
792
793        hide: function() {
794            var _self = this;
795
796            this.$wrapper.removeClass( 'loading-overlay-showing' );
797            setTimeout(function() {
798                if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
799                    _self.$wrapper.css({ position: '' });
800                }
801            }, 500);
802        },
803
804        matchProperties: function() {
805            var i,
806                l,
807                properties;
808
809            properties = [
810                'backgroundColor',
811                'borderRadius'
812            ];
813
814            l = properties.length;
815
816            for( i = 0; i < l; i++ ) {
817                var obj = {};
818                obj[ properties[ i ] ] = this.$wrapper.css( properties[ i ] );
819
820                $.extend( this.options.css, obj );
821            }
822        },
823
824        getLoaderClass: function( backgroundColor ) {
825            if ( !backgroundColor || backgroundColor === 'transparent' || backgroundColor === 'inherit' ) {
826                return 'black';
827            }
828
829            var hexColor,
830                r,
831                g,
832                b,
833                yiq;
834
835            var colorToHex = function( color ){
836                var hex,
837                    rgb;
838
839                if( color.indexOf('#') >- 1 ){
840                    hex = color.replace('#', '');
841                } else {
842                    rgb = color.match(/\d+/g);
843                    hex = ('0' + parseInt(rgb[0], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[2], 10).toString(16)).slice(-2);
844                }
845
846                if ( hex.length === 3 ) {
847                    hex = hex + hex;
848                }
849
850                return hex;
851            };
852
853            hexColor = colorToHex( backgroundColor );
854
855            r = parseInt( hexColor.substr( 0, 2), 16 );
856            g = parseInt( hexColor.substr( 2, 2), 16 );
857            b = parseInt( hexColor.substr( 4, 2), 16 );
858            yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
859
860            return ( yiq >= 128 ) ? 'black' : 'white';
861        }
862
863    };
864
865    // expose to scope
866    $.extend(theme, {
867        LoadingOverlay: LoadingOverlay
868    });
869
870    // expose as a jquery plugin
871    $.fn.loadingOverlay = function( opts ) {
872        return this.each(function() {
873            var $this = $( this );
874
875            var loadingOverlay = $this.data( 'loadingOverlay' );
876            if ( loadingOverlay ) {
877                return loadingOverlay;
878            } else {
879                var options = opts || $this.data( 'loading-overlay-options' ) || {};
880                return new LoadingOverlay( $this, options );
881            }
882        });
883    }
884
885    // auto init
886    $('[data-loading-overlay]').loadingOverlay();
887
888}).apply(this, [window.theme, jQuery]);
889
890// Masonry
891(function(theme, $) {
892
893    theme = theme || {};
894
895    var instanceName = '__masonry';
896
897    var PluginMasonry = function($el, opts) {
898        return this.initialize($el, opts);
899    };
900
901    PluginMasonry.defaults = {
902        itemSelector: 'li'
903    };
904
905    PluginMasonry.prototype = {
906        initialize: function($el, opts) {
907            if ($el.data(instanceName)) {
908                return this;
909            }
910
911            this.$el = $el;
912
913            this
914                .setData()
915                .setOptions(opts)
916                .build();
917
918            return this;
919        },
920
921        setData: function() {
922            this.$el.data(instanceName, this);
923
924            return this;
925        },
926
927        setOptions: function(opts) {
928            this.options = $.extend(true, {}, PluginMasonry.defaults, opts, {
929                wrapper: this.$el
930            });
931
932            return this;
933        },
934
935        build: function() {
936            if (!($.isFunction($.fn.isotope))) {
937                return this;
938            }
939
940            var self = this,
941                $window = $(window);
942
943            self.$loader = false;
944
945            if (self.options.wrapper.parents('.masonry-loader').get(0)) {
946                self.$loader = self.options.wrapper.parents('.masonry-loader');
947                self.createLoader();
948            }
949
950            self.options.wrapper.one('layoutComplete', function(event, laidOutItems) {
951                self.removeLoader();
952            });
953
954            self.options.wrapper.waitForImages(function() {
955                self.options.wrapper.isotope(this.options);
956            });
957
958            setTimeout(function() {
959                self.removeLoader();
960            }, 3000);
961
962            return this;
963        },
964
965        createLoader: function() {
966            var self = this;
967
968            var loaderTemplate = [
969                '<div class="bounce-loader">',
970                '<div class="bounce1"></div>',
971                '<div class="bounce2"></div>',
972                '<div class="bounce3"></div>',
973                '</div>'
974            ].join('');
975
976            self.$loader.append(loaderTemplate);
977
978            return this;
979        },
980
981        removeLoader: function() {
982
983            var self = this;
984
985            if (self.$loader) {
986
987                self.$loader.removeClass('masonry-loader-showing');
988
989                setTimeout(function() {
990                    self.$loader.addClass('masonry-loader-loaded');
991                }, 300);
992
993            }
994
995        }
996    };
997
998    // expose to scope
999    $.extend(theme, {
1000        PluginMasonry: PluginMasonry
1001    });
1002
1003    // jquery plugin
1004    $.fn.themePluginMasonry = function(opts) {
1005        return this.map(function() {
1006            var $this = $(this);
1007
1008            if ($this.data(instanceName)) {
1009                return $this.data(instanceName);
1010            } else {
1011                return new PluginMasonry($this, opts);
1012            }
1013
1014        });
1015    }
1016
1017}).apply(this, [window.theme, jQuery]);
1018
1019// Match Height
1020(function(theme, $) {
1021
1022    theme = theme || {};
1023
1024    var instanceName = '__matchHeight';
1025
1026    var PluginMatchHeight = function($el, opts) {
1027        return this.initialize($el, opts);
1028    };
1029
1030    PluginMatchHeight.defaults = {
1031        byRow: true,
1032        property: 'height',
1033        target: null,
1034        remove: false
1035    };
1036
1037    PluginMatchHeight.prototype = {
1038        initialize: function($el, opts) {
1039            if ($el.data(instanceName)) {
1040                return this;
1041            }
1042
1043            this.$el = $el;
1044
1045            this
1046                .setData()
1047                .setOptions(opts)
1048                .build();
1049
1050            return this;
1051        },
1052
1053        setData: function() {
1054            this.$el.data(instanceName, this);
1055
1056            return this;
1057        },
1058
1059        setOptions: function(opts) {
1060            this.options = $.extend(true, {}, PluginMatchHeight.defaults, opts, {
1061                wrapper: this.$el
1062            });
1063
1064            return this;
1065        },
1066
1067        build: function() {
1068            if (!($.isFunction($.fn.matchHeight))) {
1069                return this;
1070            }
1071
1072            var self = this;
1073
1074            self.options.wrapper.matchHeight(self.options);
1075
1076            return this;
1077        }
1078
1079    };
1080
1081    // expose to scope
1082    $.extend(theme, {
1083        PluginMatchHeight: PluginMatchHeight
1084    });
1085
1086    // jquery plugin
1087    $.fn.themePluginMatchHeight = function(opts) {
1088        return this.map(function() {
1089            var $this = $(this);
1090
1091            if ($this.data(instanceName)) {
1092                return $this.data(instanceName);
1093            } else {
1094                return new PluginMatchHeight($this, opts);
1095            }
1096
1097        });
1098    }
1099
1100}).apply(this, [window.theme, jQuery]);
1101
1102// Parallax
1103(function(theme, $) {
1104
1105    theme = theme || {};
1106
1107    var instanceName = '__parallax';
1108
1109    var PluginParallax = function($el, opts) {
1110        return this.initialize($el, opts);
1111    };
1112
1113    PluginParallax.defaults = {
1114        speed: 1.5,
1115        horizontalPosition: '50%',
1116        offset: 0
1117    };
1118
1119    PluginParallax.prototype = {
1120        initialize: function($el, opts) {
1121            if ($el.data(instanceName)) {
1122                return this;
1123            }
1124
1125            this.$el = $el;
1126
1127            this
1128                .setData()
1129                .setOptions(opts)
1130                .build();
1131
1132            return this;
1133        },
1134
1135        setData: function() {
1136            this.$el.data(instanceName, this);
1137
1138            return this;
1139        },
1140
1141        setOptions: function(opts) {
1142            this.options = $.extend(true, {}, PluginParallax.defaults, opts, {
1143                wrapper: this.$el
1144            });
1145
1146            return this;
1147        },
1148
1149        build: function() {
1150            var self = this,
1151                $window = $(window),
1152                offset,
1153                yPos,
1154                bgpos;
1155
1156            self.options.wrapper.css('background-image', 'url(' + self.options.wrapper.data('image-src') + ')');
1157
1158            if (!$.browser.mobile) {
1159
1160                $window.on('scroll resize', function() {
1161                    offset = self.options.wrapper.offset();
1162                    yPos = -($window.scrollTop() - offset.top) / self.options.speed + (self.options.offset);
1163                    bgpos = self.options.horizontalPosition + ' ' + yPos + 'px';
1164                    self.options.wrapper.css('background-position', bgpos);
1165                });
1166
1167                $window.trigger('scroll');
1168
1169            } else {
1170                self.options.wrapper.addClass('parallax-disabled');
1171            }
1172
1173            return this;
1174        }
1175    };
1176
1177    // expose to scope
1178    $.extend(theme, {
1179        PluginParallax: PluginParallax
1180    });
1181
1182    // jquery plugin
1183    $.fn.themePluginParallax = function(opts) {
1184        return this.map(function() {
1185            var $this = $(this);
1186
1187            if ($this.data(instanceName)) {
1188                return $this.data(instanceName);
1189            } else {
1190                return new PluginParallax($this, opts);
1191            }
1192
1193        });
1194    }
1195
1196}).apply(this, [window.theme, jQuery]);
1197
1198// Progress Bar
1199(function(theme, $) {
1200
1201    theme = theme || {};
1202
1203    var instanceName = '__progressBar';
1204
1205    var PluginProgressBar = function($el, opts) {
1206        return this.initialize($el, opts);
1207    };
1208
1209    PluginProgressBar.defaults = {
1210        accX: 0,
1211        accY: -50,
1212        delay: 1
1213    };
1214
1215    PluginProgressBar.prototype = {
1216        initialize: function($el, opts) {
1217            if ($el.data(instanceName)) {
1218                return this;
1219            }
1220
1221            this.$el = $el;
1222
1223            this
1224                .setData()
1225                .setOptions(opts)
1226                .build();
1227
1228            return this;
1229        },
1230
1231        setData: function() {
1232            this.$el.data(instanceName, this);
1233
1234            return this;
1235        },
1236
1237        setOptions: function(opts) {
1238            this.options = $.extend(true, {}, PluginProgressBar.defaults, opts, {
1239                wrapper: this.$el
1240            });
1241
1242            return this;
1243        },
1244
1245        build: function() {
1246            if (!($.isFunction($.fn.appear))) {
1247                return this;
1248            }
1249
1250            var self = this,
1251                $el = this.options.wrapper,
1252                delay = 1;
1253
1254            $el.appear(function() {
1255
1256                delay = ($el.attr('data-appear-animation-delay') ? $el.attr('data-appear-animation-delay') : self.options.delay);
1257
1258                $el.addClass($el.attr('data-appear-animation'));
1259
1260                setTimeout(function() {
1261
1262                    $el.animate({
1263                        width: $el.attr('data-appear-progress-animation')
1264                    }, 1500, 'easeOutQuad', function() {
1265                        $el.find('.progress-bar-tooltip').animate({
1266                            opacity: 1
1267                        }, 500, 'easeOutQuad');
1268                    });
1269
1270                }, delay);
1271
1272            }, {
1273                accX: self.options.accX,
1274                accY: self.options.accY
1275            });
1276
1277            return this;
1278        }
1279    };
1280
1281    // expose to scope
1282    $.extend(theme, {
1283        PluginProgressBar: PluginProgressBar
1284    });
1285
1286    // jquery plugin
1287    $.fn.themePluginProgressBar = function(opts) {
1288        return this.map(function() {
1289            var $this = $(this);
1290
1291            if ($this.data(instanceName)) {
1292                return $this.data(instanceName);
1293            } else {
1294                return new PluginProgressBar($this, opts);
1295            }
1296
1297        });
1298    }
1299
1300}).apply(this, [window.theme, jQuery]);
1301
1302// Revolution Slider
1303(function(theme, $) {
1304
1305    theme = theme || {};
1306
1307    var instanceName = '__revolution';
1308
1309    var PluginRevolutionSlider = function($el, opts) {
1310        return this.initialize($el, opts);
1311    };
1312
1313    PluginRevolutionSlider.defaults = {
1314        sliderType: 'standard',
1315        sliderLayout: 'fullwidth',
1316        delay: 9000,
1317        gridwidth: 1170,
1318        gridheight: 500,
1319        spinner: 'spinner3',
1320        disableProgressBar: 'on',
1321        parallax: {
1322            type: 'off',
1323            bgparallax: 'off'
1324        },
1325        navigation: {
1326            keyboardNavigation: 'off',
1327            keyboard_direction: 'horizontal',
1328            mouseScrollNavigation: 'off',
1329            onHoverStop: 'off',
1330            touch: {
1331                touchenabled: 'on',
1332                swipe_threshold: 75,
1333                swipe_min_touches: 1,
1334                swipe_direction: 'horizontal',
1335                drag_block_vertical: false
1336            },
1337            arrows: {
1338                enable: true,
1339                hide_onmobile: false,
1340                hide_under: 0,
1341                hide_onleave: true,
1342                hide_delay: 200,
1343                hide_delay_mobile: 1200,
1344                left: {
1345                    h_align: 'left',
1346                    v_align: 'center',
1347                    h_offset: 30,
1348                    v_offset: 0
1349                },
1350                right: {
1351                    h_align: 'right',
1352                    v_align: 'center',
1353                    h_offset: 30,
1354                    v_offset: 0
1355                }
1356            }
1357        }
1358    };
1359
1360    PluginRevolutionSlider.prototype = {
1361        initialize: function($el, opts) {
1362            if ($el.data(instanceName)) {
1363                return this;
1364            }
1365
1366            this.$el = $el;
1367
1368            this
1369                .setData()
1370                .setOptions(opts)
1371                .build()
1372                .events();
1373
1374            return this;
1375        },
1376
1377        setData: function() {
1378            this.$el.data(instanceName, this);
1379
1380            return this;
1381        },
1382
1383        setOptions: function(opts) {
1384            this.options = $.extend(true, {}, PluginRevolutionSlider.defaults, opts, {
1385                wrapper: this.$el
1386            });
1387
1388            return this;
1389        },
1390
1391        build: function() {
1392            if (!($.isFunction($.fn.revolution))) {
1393                return this;
1394            }
1395
1396            // Single Slider Class
1397            if(this.options.wrapper.find('> ul > li').length == 1) {
1398                this.options.wrapper.addClass('slider-single-slide');
1399            }
1400
1401            this.options.wrapper.revolution(this.options);
1402
1403            return this;
1404        },
1405
1406        events: function() {
1407
1408            return this;
1409        }
1410    };
1411
1412    // expose to scope
1413    $.extend(theme, {
1414        PluginRevolutionSlider: PluginRevolutionSlider
1415    });
1416
1417    // jquery plugin
1418    $.fn.themePluginRevolutionSlider = function(opts) {
1419        return this.map(function() {
1420            var $this = $(this);
1421
1422            if ($this.data(instanceName)) {
1423                return $this.data(instanceName);
1424            } else {
1425                return new PluginRevolutionSlider($this, opts);
1426            }
1427
1428        });
1429    }
1430
1431}).apply(this, [window.theme, jQuery]);
1432
1433// Scroll to Top
1434(function(theme, $) {
1435
1436    theme = theme || {};
1437
1438    $.extend(theme, {
1439
1440        PluginScrollToTop: {
1441
1442            defaults: {
1443                wrapper: $('body'),
1444                offset: 150,
1445                buttonClass: 'scroll-to-top',
1446                iconClass: 'fa fa-chevron-up',
1447                delay: 1000,
1448                visibleMobile: false,
1449                label: false,
1450                easing: 'easeOutBack'
1451            },
1452
1453            initialize: function(opts) {
1454                initialized = true;
1455
1456                this
1457                    .setOptions(opts)
1458                    .build()
1459                    .events();
1460
1461                return this;
1462            },
1463
1464            setOptions: function(opts) {
1465                this.options = $.extend(true, {}, this.defaults, opts);
1466
1467                return this;
1468            },
1469
1470            build: function() {
1471                var self = this,
1472                    $el;
1473
1474                // Base HTML Markup
1475                $el = $('<a />')
1476                    .addClass(self.options.buttonClass)
1477                    .attr({
1478                        'href': '#',
1479                    })
1480                    .append(
1481                        $('<i />')
1482                            .addClass(self.options.iconClass)
1483                    );
1484
1485                // Visible Mobile
1486                if (!self.options.visibleMobile) {
1487                    $el.addClass('hidden-mobile');
1488                }
1489
1490                // Label
1491                if (self.options.label) {
1492                    $el.append(
1493                        $('<span />').html(self.options.label)
1494                    );
1495                }
1496
1497                this.options.wrapper.append($el);
1498
1499                this.$el = $el;
1500
1501                return this;
1502            },
1503
1504            events: function() {
1505                var self = this,
1506                    _isScrolling = false;
1507
1508                // Click Element Action
1509                self.$el.on('click', function(e) {
1510                    e.preventDefault();
1511                    $('body, html').animate({
1512                        scrollTop: 0
1513                    }, self.options.delay, self.options.easing);
1514                    return false;
1515                });
1516
1517                // Show/Hide Button on Window Scroll event.
1518                $(window).scroll(function() {
1519
1520                    if (!_isScrolling) {
1521
1522                        _isScrolling = true;
1523
1524                        if ($(window).scrollTop() > self.options.offset) {
1525
1526                            self.$el.stop(true, true).addClass('visible');
1527                            _isScrolling = false;
1528
1529                        } else {
1530
1531                            self.$el.stop(true, true).removeClass('visible');
1532                            _isScrolling = false;
1533
1534                        }
1535
1536                    }
1537
1538                });
1539
1540                return this;
1541            }
1542
1543        }
1544
1545    });
1546
1547}).apply(this, [window.theme, jQuery]);
1548
1549// Sort
1550(function(theme, $) {
1551
1552    theme = theme || {};
1553
1554    var instanceName = '__sort';
1555
1556    var PluginSort = function($el, opts) {
1557        return this.initialize($el, opts);
1558    };
1559
1560    PluginSort.defaults = {
1561        useHash: true,
1562        itemSelector: '.isotope-item',
1563        layoutMode: 'masonry',
1564        filter: '*',
1565        hiddenStyle: {
1566            opacity: 0
1567        },
1568        visibleStyle: {
1569            opacity: 1
1570        },
1571        stagger: 30,
1572        isOriginLeft: ($('html').attr('dir') == 'rtl' ? false : true)
1573    };
1574
1575    PluginSort.prototype = {
1576        initialize: function($el, opts) {
1577            if ($el.data(instanceName)) {
1578                return this;
1579            }
1580
1581            this.$el = $el;
1582
1583            this
1584                .setData()
1585                .setOptions(opts)
1586                .build();
1587
1588            return this;
1589        },
1590
1591        setData: function() {
1592            this.$el.data(instanceName, this);
1593
1594            return this;
1595        },
1596
1597        setOptions: function(opts) {
1598            this.options = $.extend(true, {}, PluginSort.defaults, opts, {
1599                wrapper: this.$el
1600            });
1601
1602            return this;
1603        },
1604
1605        build: function() {
1606            if (!($.isFunction($.fn.isotope))) {
1607                return this;
1608            }
1609
1610            var self = this,
1611                $source = this.options.wrapper,
1612                $destination = $('.sort-destination[data-sort-id="' + $source.attr('data-sort-id') + '"]'),
1613                $window = $(window);
1614
1615            if ($destination.get(0)) {
1616
1617                self.$source = $source;
1618                self.$destination = $destination;
1619                self.$loader = false;
1620
1621                self.setParagraphHeight($destination);
1622
1623                if (self.$destination.parents('.sort-destination-loader').get(0)) {
1624                    self.$loader = self.$destination.parents('.sort-destination-loader');
1625                    self.createLoader();
1626                }
1627
1628                $destination.attr('data-filter', '*');
1629
1630                $destination.one('layoutComplete', function(event, laidOutItems) {
1631                    self.removeLoader();
1632                });
1633
1634                $destination.waitForImages(function() {
1635                    $destination.isotope(self.options);
1636                    self.events();
1637                });
1638
1639                setTimeout(function() {
1640                    self.removeLoader();
1641                }, 3000);
1642
1643            }
1644
1645            return this;
1646        },
1647
1648        events: function() {
1649            var self = this,
1650                filter = null,
1651                $window = $(window);
1652
1653            self.$source.find('a').click(function(e) {
1654                e.preventDefault();
1655
1656                filter = $(this).parent().data('option-value');
1657
1658                self.setFilter(filter);
1659
1660                if (e.originalEvent) {
1661                    self.$source.trigger('filtered');
1662                }
1663
1664                return this;
1665            });
1666
1667            self.$destination.trigger('filtered');
1668            self.$source.trigger('filtered');
1669
1670            if (self.options.useHash) {
1671                self.hashEvents();
1672            }
1673
1674            $window.on('resize', function() {
1675                setTimeout(function() {
1676                    self.$destination.isotope('layout');
1677                }, 300);
1678            });
1679
1680            setTimeout(function() {
1681                $window.trigger('resize');
1682            }, 300);
1683
1684            return this;
1685        },
1686
1687        setFilter: function(filter) {
1688            var self = this,
1689                page = false,
1690                currentFilter = filter;
1691
1692            self.$source.find('li.active').removeClass('active');
1693            self.$source.find('li[data-option-value="' + filter + '"]').addClass('active');
1694
1695            self.options.filter = currentFilter;
1696
1697            if (self.$destination.attr('data-current-page')) {
1698                currentFilter = currentFilter + '[data-page-rel=' + self.$destination.attr('data-current-page') + ']';
1699            }
1700
1701            self.$destination.attr('data-filter', filter).isotope({
1702                filter: currentFilter
1703            }).one('arrangeComplete', function( event, filteredItems ) {
1704
1705                if (self.options.useHash) {
1706                    if (window.location.hash != '' || self.options.filter.replace('.', '') != '*') {
1707                        window.location.hash = self.options.filter.replace('.', '');
1708                    }
1709                }
1710
1711                $(window).trigger('scroll');
1712
1713            }).trigger('filtered');
1714
1715            return this;
1716        },
1717
1718        hashEvents: function() {
1719            var self = this,
1720                hash = null,
1721                hashFilter = null,
1722                initHashFilter = '.' + location.hash.replace('#', '');
1723
1724            if (initHashFilter != '.' && initHashFilter != '.*') {
1725                self.setFilter(initHashFilter);
1726            }
1727
1728            $(window).on('hashchange', function(e) {
1729
1730                hashFilter = '.' + location.hash.replace('#', '');
1731                hash = (hashFilter == '.' || hashFilter == '.*' ? '*' : hashFilter);
1732
1733                self.setFilter(hash);
1734
1735            });
1736
1737            return this;
1738        },
1739
1740        setParagraphHeight: function() {
1741            var self = this,
1742                minParagraphHeight = 0,
1743                paragraphs = $('span.thumb-info-caption p', self.$destination);
1744
1745            paragraphs.each(function() {
1746                if ($(this).height() > minParagraphHeight) {
1747                    minParagraphHeight = ($(this).height() + 10);
1748                }
1749            });
1750
1751            paragraphs.height(minParagraphHeight);
1752
1753            return this;
1754        },
1755
1756        createLoader: function() {
1757            var self = this;
1758
1759            var loaderTemplate = [
1760                '<div class="bounce-loader">',
1761                '<div class="bounce1"></div>',
1762                '<div class="bounce2"></div>',
1763                '<div class="bounce3"></div>',
1764                '</div>'
1765            ].join('');
1766
1767            self.$loader.append(loaderTemplate);
1768
1769            return this;
1770        },
1771
1772        removeLoader: function() {
1773
1774            var self = this;
1775
1776            if (self.$loader) {
1777
1778                self.$loader.removeClass('sort-destination-loader-showing');
1779
1780                setTimeout(function() {
1781                    self.$loader.addClass('sort-destination-loader-loaded');
1782                }, 300);
1783
1784            }
1785
1786        }
1787
1788    };
1789
1790    // expose to scope
1791    $.extend(theme, {
1792        PluginSort: PluginSort
1793    });
1794
1795    // jquery plugin
1796    $.fn.themePluginSort = function(opts) {
1797        return this.map(function() {
1798            var $this = $(this);
1799
1800            if ($this.data(instanceName)) {
1801                return $this.data(instanceName);
1802            } else {
1803                return new PluginSort($this, opts);
1804            }
1805
1806        });
1807    }
1808
1809}).apply(this, [window.theme, jQuery]);
1810
1811// Sticky
1812(function(theme, $) {
1813
1814    theme = theme || {};
1815
1816    var instanceName = '__sticky';
1817
1818    var PluginSticky = function($el, opts) {
1819        return this.initialize($el, opts);
1820    };
1821
1822    PluginSticky.defaults = {
1823        minWidth: 991,
1824        activeClass: 'sticky-active'
1825    };
1826
1827    PluginSticky.prototype = {
1828        initialize: function($el, opts) {
1829            if ( $el.data( instanceName ) ) {
1830                return this;
1831            }
1832
1833            this.$el = $el;
1834
1835            this
1836                .setData()
1837                .setOptions(opts)
1838                .build();
1839
1840            return this;
1841        },
1842
1843        setData: function() {
1844            this.$el.data(instanceName, this);
1845
1846            return this;
1847        },
1848
1849        setOptions: function(opts) {
1850            this.options = $.extend(true, {}, PluginSticky.defaults, opts, {
1851                wrapper: this.$el
1852            });
1853
1854            return this;
1855        },
1856
1857        build: function() {
1858            if (!($.isFunction($.fn.pin))) {
1859                return this;
1860            }
1861
1862            var self = this,
1863                $window = $(window);
1864
1865            self.options.wrapper.pin(self.options);
1866
1867            $window.afterResize(function() {
1868                self.options.wrapper.removeAttr('style').removeData('pin');
1869                self.options.wrapper.pin(self.options);
1870                $window.trigger('scroll');
1871            });
1872
1873            return this;
1874        }
1875    };
1876
1877    // expose to scope
1878    $.extend(theme, {
1879        PluginSticky: PluginSticky
1880    });
1881
1882    // jquery plugin
1883    $.fn.themePluginSticky = function(opts) {
1884        return this.map(function() {
1885            var $this = $(this);
1886
1887            if ($this.data(instanceName)) {
1888                return $this.data(instanceName);
1889            } else {
1890                return new PluginSticky($this, opts);
1891            }
1892
1893        });
1894    }
1895
1896}).apply(this, [ window.theme, jQuery ]);
1897
1898// Toggle
1899(function(theme, $) {
1900
1901    theme = theme || {};
1902
1903    var instanceName = '__toggle';
1904
1905    var PluginToggle = function($el, opts) {
1906        return this.initialize($el, opts);
1907    };
1908
1909    PluginToggle.defaults = {
1910        duration: 350,
1911        isAccordion: false
1912    };
1913
1914    PluginToggle.prototype = {
1915        initialize: function($el, opts) {
1916            if ($el.data(instanceName)) {
1917                return this;
1918            }
1919
1920            this.$el = $el;
1921
1922            this
1923                .setData()
1924                .setOptions(opts)
1925                .build();
1926
1927            return this;
1928        },
1929
1930        setData: function() {
1931            this.$el.data(instanceName, this);
1932
1933            return this;
1934        },
1935
1936        setOptions: function(opts) {
1937            this.options = $.extend(true, {}, PluginToggle.defaults, opts, {
1938                wrapper: this.$el
1939            });
1940
1941            return this;
1942        },
1943
1944        build: function() {
1945            var self = this,
1946                $wrapper = this.options.wrapper,
1947                $items = $wrapper.find('.toggle'),
1948                $el = null;
1949
1950            $items.each(function() {
1951                $el = $(this);
1952
1953                if ($el.hasClass('active')) {
1954                    $el.find('> p').addClass('preview-active');
1955                    $el.find('> .toggle-content').slideDown(self.options.duration);
1956                }
1957
1958                self.events($el);
1959            });
1960
1961            if (self.options.isAccordion) {
1962                self.options.duration = self.options.duration / 2;
1963            }
1964
1965            return this;
1966        },
1967
1968        events: function($el) {
1969            var self = this,
1970                previewParCurrentHeight = 0,
1971                previewParAnimateHeight = 0,
1972                toggleContent = null;
1973
1974            $el.find('> label').click(function(e) {
1975
1976                var $this = $(this),
1977                    parentSection = $this.parent(),
1978                    parentWrapper = $this.parents('.toggle'),
1979                    previewPar = null,
1980                    closeElement = null;
1981
1982                if (self.options.isAccordion && typeof(e.originalEvent) != 'undefined') {
1983                    closeElement = parentWrapper.find('.toggle.active > label');
1984
1985                    if (closeElement[0] == $this[0]) {
1986                        return;
1987                    }
1988                }
1989
1990                parentSection.toggleClass('active');
1991
1992                // Preview Paragraph
1993                if (parentSection.find('> p').get(0)) {
1994
1995                    previewPar = parentSection.find('> p');
1996                    previewParCurrentHeight = previewPar.css('height');
1997                    previewPar.css('height', 'auto');
1998                    previewParAnimateHeight = previewPar.css('height');
1999                    previewPar.css('height', previewParCurrentHeight);
2000
2001                }
2002
2003                // Content
2004                toggleContent = parentSection.find('> .toggle-content');
2005
2006                if (parentSection.hasClass('active')) {
2007
2008                    $(previewPar).animate({
2009                        height: previewParAnimateHeight
2010                    }, self.options.duration, function() {
2011                        $(this).addClass('preview-active');
2012                    });
2013
2014                    toggleContent.slideDown(self.options.duration, function() {
2015                        if (closeElement) {
2016                            closeElement.trigger('click');
2017                        }
2018                    });
2019
2020                } else {
2021
2022                    $(previewPar).animate({
2023                        height: 0
2024                    }, self.options.duration, function() {
2025                        $(this).removeClass('preview-active');
2026                    });
2027
2028                    toggleContent.slideUp(self.options.duration);
2029
2030                }
2031
2032            });
2033        }
2034    };
2035
2036    // expose to scope
2037    $.extend(theme, {
2038        PluginToggle: PluginToggle
2039    });
2040
2041    // jquery plugin
2042    $.fn.themePluginToggle = function(opts) {
2043        return this.map(function() {
2044            var $this = $(this);
2045
2046            if ($this.data(instanceName)) {
2047                return $this.data(instanceName);
2048            } else {
2049                return new PluginToggle($this, opts);
2050            }
2051
2052        });
2053    }
2054
2055}).apply(this, [window.theme, jQuery]);
2056
2057// Tweets
2058(function(theme, $) {
2059
2060    theme = theme || {};
2061
2062    var instanceName = '__tweets';
2063
2064    var PluginTweets = function($el, opts) {
2065        return this.initialize($el, opts);
2066    };
2067
2068    PluginTweets.defaults = {
2069        username: null,
2070        count: 2,
2071        URL: 'php/twitter-feed.php'
2072    };
2073
2074    PluginTweets.prototype = {
2075        initialize: function($el, opts) {
2076            if ($el.data(instanceName)) {
2077                return this;
2078            }
2079
2080            this.$el = $el;
2081
2082            this
2083                .setData()
2084                .setOptions(opts)
2085                .build();
2086
2087            return this;
2088        },
2089
2090        setData: function() {
2091            this.$el.data(instanceName, this);
2092
2093            return this;
2094        },
2095
2096        setOptions: function(opts) {
2097            this.options = $.extend(true, {}, PluginTweets.defaults, opts, {
2098                wrapper: this.$el
2099            });
2100
2101            return this;
2102        },
2103
2104        build: function() {
2105            if (this.options.username == null || this.options.username == '') {
2106                return this;
2107            }
2108
2109            var self = this,
2110                $wrapper = this.options.wrapper;
2111
2112            $.ajax({
2113                type: 'GET',
2114                data: {
2115                    twitter_screen_name: self.options.username,
2116                    tweets_to_display: self.options.count
2117                },
2118                url: self.options.URL,
2119            }).done(function(html) {
2120                $wrapper.html(html).find('a').attr('target','_blank');
2121            });
2122
2123            return this;
2124        }
2125    };
2126
2127    // expose to scope
2128    $.extend(theme, {
2129        PluginTweets: PluginTweets
2130    });
2131
2132    // jquery plugin
2133    $.fn.themePluginTweets = function(opts) {
2134        return this.map(function() {
2135            var $this = $(this);
2136
2137            if ($this.data(instanceName)) {
2138                return $this.data(instanceName);
2139            } else {
2140                return new PluginTweets($this, opts);
2141            }
2142
2143        });
2144    }
2145
2146}).apply(this, [window.theme, jQuery]);
2147
2148// Validation
2149(function(theme, $) {
2150
2151    theme = theme || {};
2152
2153    $.extend(theme, {
2154
2155        PluginValidation: {
2156
2157            defaults: {
2158                validator: {
2159                    highlight: function(element) {
2160                        $(element)
2161                            .parent()
2162                            .removeClass('has-success')
2163                            .addClass('has-error');
2164                    },
2165                    success: function(element) {
2166                        $(element)
2167                            .parent()
2168                            .removeClass('has-error')
2169                            .addClass('has-success')
2170                            .find('label.error')
2171                            .remove();
2172                    },
2173                    errorPlacement: function(error, element) {
2174                        if (element.attr('type') == 'radio' || element.attr('type') == 'checkbox') {
2175                            error.appendTo(element.parent().parent());
2176                        } else {
2177                            error.insertAfter(element);
2178                        }
2179                    }
2180                },
2181                validateCaptchaURL: 'php/contact-form-verify-captcha.php',
2182                refreshCaptchaURL: 'php/contact-form-refresh-captcha.php'
2183            },
2184
2185            initialize: function(opts) {
2186                initialized = true;
2187
2188                this
2189                    .setOptions(opts)
2190                    .build();
2191
2192                return this;
2193            },
2194
2195            setOptions: function(opts) {
2196                this.options = $.extend(true, {}, this.defaults, opts);
2197
2198                return this;
2199            },
2200
2201            build: function() {
2202                var self = this;
2203
2204                if (!($.isFunction($.validator))) {
2205                    return this;
2206                }
2207
2208                self.addMethods();
2209                self.setMessageGroups();
2210
2211                $.validator.setDefaults(self.options.validator);
2212
2213                return this;
2214            },
2215
2216            addMethods: function() {
2217                var self = this;
2218
2219                $.validator.addMethod('captcha', function(value, element, params) {
2220                    var captchaValid = false;
2221
2222                    $.ajax({
2223                        url: self.options.validateCaptchaURL,
2224                        type: 'POST',
2225                        async: false,
2226                        dataType: 'json',
2227                        data: {
2228                            captcha: $.trim(value)
2229                        },
2230                        success: function(data) {
2231                            if (data.response == 'success') {
2232                                captchaValid = true;
2233                            }
2234                        }
2235                    });
2236
2237                    if (captchaValid) {
2238                        return true;
2239                    }
2240
2241                }, '');
2242
2243                // Refresh Captcha
2244                $('#refreshCaptcha').on('click', function(e) {
2245                    e.preventDefault();
2246                    $.get(self.options.refreshCaptchaURL, function(url) {
2247                        $('#captcha-image').attr('src', url);
2248                    });
2249                });
2250
2251            },
2252
2253            setMessageGroups: function() {
2254
2255                $('.checkbox-group[data-msg-required], .radio-group[data-msg-required]').each(function() {
2256                    var message = $(this).data('msg-required');
2257                    $(this).find('input').attr('data-msg-required', message);
2258                });
2259
2260            }
2261
2262        }
2263
2264    });
2265
2266}).apply(this, [window.theme, jQuery]);
2267
2268// Video Background
2269(function(theme, $) {
2270
2271    theme = theme || {};
2272
2273    var instanceName = '__videobackground';
2274
2275    var PluginVideoBackground = function($el, opts) {
2276        return this.initialize($el, opts);
2277    };
2278
2279    PluginVideoBackground.defaults = {
2280        overlay: true,
2281        volume: 1,
2282        playbackRate: 1,
2283        muted: true,
2284        loop: true,
2285        autoplay: true,
2286        position: '50% 50%',
2287        posterType: 'detect'
2288    };
2289
2290    PluginVideoBackground.prototype = {
2291        initialize: function($el, opts) {
2292            this.$el = $el;
2293
2294            this
2295                .setData()
2296                .setOptions(opts)
2297                .build();
2298
2299            return this;
2300        },
2301
2302        setData: function() {
2303            this.$el.data(instanceName, this);
2304
2305            return this;
2306        },
2307
2308        setOptions: function(opts) {
2309            this.options = $.extend(true, {}, PluginVideoBackground.defaults, opts, {
2310                path: this.$el.data('video-path'),
2311                wrapper: this.$el
2312            });
2313
2314            return this;
2315        },
2316
2317        build: function() {
2318
2319            if (!($.isFunction($.fn.vide)) || (!this.options.path)) {
2320                return this;
2321            }
2322
2323            if (this.options.overlay) {
2324                this.options.wrapper.prepend(
2325                    $('<div />').addClass('video-overlay')
2326                );
2327            }
2328
2329            this.options.wrapper.vide(this.options.path, this.options);
2330
2331            return this;
2332        }
2333    };
2334
2335    // expose to scope
2336    $.extend(theme, {
2337        PluginVideoBackground: PluginVideoBackground
2338    });
2339
2340    // jquery plugin
2341    $.fn.themePluginVideoBackground = function(opts) {
2342        return this.map(function() {
2343            var $this = $(this);
2344
2345            if ($this.data(instanceName)) {
2346                return $this.data(instanceName);
2347            } else {
2348                return new PluginVideoBackground($this, opts);
2349            }
2350
2351        });
2352    }
2353
2354}).apply(this, [window.theme, jQuery]);
2355
2356// Word Rotate
2357(function(theme, $) {
2358
2359    theme = theme || {};
2360
2361    var instanceName = '__wordRotate';
2362
2363    var PluginWordRotate = function($el, opts) {
2364        return this.initialize($el, opts);
2365    };
2366
2367    PluginWordRotate.defaults = {
2368        delay: 2000,
2369        animDelay: 300
2370    };
2371
2372    PluginWordRotate.prototype = {
2373        initialize: function($el, opts) {
2374            if ( $el.data( instanceName ) ) {
2375                return this;
2376            }
2377
2378            this.$el = $el;
2379
2380            this
2381                .setData()
2382                .setOptions(opts)
2383                .build();
2384
2385            return this;
2386        },
2387
2388        setData: function() {
2389            this.$el.data(instanceName, this);
2390
2391            return this;
2392        },
2393
2394        setOptions: function(opts) {
2395            this.options = $.extend(true, {}, PluginWordRotate.defaults, opts, {
2396                wrapper: this.$el
2397            });
2398
2399            return this;
2400        },
2401
2402        build: function() {
2403            var self = this,
2404                $el = this.options.wrapper,
2405                itemsWrapper = $el.find(".word-rotate-items"),
2406                items = itemsWrapper.find("> span"),
2407                firstItem = items.eq(0),
2408                firstItemClone = firstItem.clone(),
2409                currentItem = 1,
2410                currentTop = 0,
2411                itemWidth = 0;
2412
2413            itemsWrapper
2414                .width(firstItem.width() + "px")
2415                .append(firstItemClone);
2416
2417            $el
2418                .addClass("active");
2419
2420            setInterval(function() {
2421
2422                currentTop = (currentItem * $el.height());
2423                currentItem++;
2424
2425                if(currentItem <= items.length) {
2426                    itemWidth = items.eq(currentItem-1).width();
2427                } else {
2428                    itemWidth = items.eq(0).width();
2429                }
2430
2431                itemsWrapper.animate({
2432                    top: -(currentTop) + "px",
2433                    width: itemWidth + "px"
2434                }, self.options.animDelay, "easeOutQuad", function() {
2435
2436                    if(currentItem > items.length) {
2437
2438                        itemsWrapper.css("top", 0);
2439                        currentItem = 1;
2440
2441                    }
2442
2443                });
2444
2445            }, self.options.delay);
2446
2447            return this;
2448        }
2449    };
2450
2451    // expose to scope
2452    $.extend(theme, {
2453        PluginWordRotate: PluginWordRotate
2454    });
2455
2456    // jquery plugin
2457    $.fn.themePluginWordRotate = function(opts) {
2458        return this.map(function() {
2459            var $this = $(this);
2460
2461            if ($this.data(instanceName)) {
2462                return $this.data(instanceName);
2463            } else {
2464                return new PluginWordRotate($this, opts);
2465            }
2466
2467        });
2468    }
2469
2470}).apply(this, [ window.theme, jQuery ]);
2471
2472// Account
2473(function(theme, $) {
2474
2475    theme = theme || {};
2476
2477    var initialized = false;
2478
2479    $.extend(theme, {
2480
2481        Account: {
2482
2483            defaults: {
2484                wrapper: $('#headerAccount')
2485            },
2486
2487            initialize: function($wrapper, opts) {
2488                if (initialized) {
2489                    return this;
2490                }
2491
2492                initialized = true;
2493                this.$wrapper = ($wrapper || this.defaults.wrapper);
2494
2495                this
2496                    .setOptions(opts)
2497                    .events();
2498
2499                return this;
2500            },
2501
2502            setOptions: function(opts) {
2503                this.options = $.extend(true, {}, this.defaults, opts, this.$wrapper.data('plugin-options'));
2504
2505                return this;
2506            },
2507
2508            events: function() {
2509                var self = this;
2510
2511                self.$wrapper.find('input').on('focus', function() {
2512                    self.$wrapper.addClass('open');
2513
2514                    $(document).mouseup(function(e) {
2515                        if (!self.$wrapper.is(e.target) && self.$wrapper.has(e.target).length === 0) {
2516                            self.$wrapper.removeClass('open');
2517                        }
2518                    });
2519                });
2520
2521                $('#headerSignUp').on('click', function(e) {
2522                    e.preventDefault();
2523                    self.$wrapper.addClass('signup').removeClass('signin').removeClass('recover');
2524                    self.$wrapper.find('.signup-form input:first').focus();
2525                });
2526
2527                $('#headerSignIn').on('click', function(e) {
2528                    e.preventDefault();
2529                    self.$wrapper.addClass('signin').removeClass('signup').removeClass('recover');
2530                    self.$wrapper.find('.signin-form input:first').focus();
2531                });
2532
2533                $('#headerRecover').on('click', function(e) {
2534                    e.preventDefault();
2535                    self.$wrapper.addClass('recover').removeClass('signup').removeClass('signin');
2536                    self.$wrapper.find('.recover-form input:first').focus();
2537                });
2538
2539                $('#headerRecoverCancel').on('click', function(e) {
2540                    e.preventDefault();
2541                    self.$wrapper.addClass('signin').removeClass('signup').removeClass('recover');
2542                    self.$wrapper.find('.signin-form input:first').focus();
2543                });
2544            }
2545
2546        }
2547
2548    });
2549
2550}).apply(this, [window.theme, jQuery]);
2551
2552// Nav
2553(function(theme, $) {
2554
2555    theme = theme || {};
2556
2557    var initialized = false;
2558
2559    $.extend(theme, {
2560
2561        Nav: {
2562
2563            defaults: {
2564                wrapper: $('#mainNav'),
2565                scrollDelay: 600,
2566                scrollAnimation: 'easeOutQuad'
2567            },
2568
2569            initialize: function($wrapper, opts) {
2570                if (initialized) {
2571                    return this;
2572                }
2573
2574                initialized = true;
2575                this.$wrapper = ($wrapper || this.defaults.wrapper);
2576
2577                this
2578                    .setOptions(opts)
2579                    .build()
2580                    .events();
2581
2582                return this;
2583            },
2584
2585            setOptions: function(opts) {
2586                this.options = $.extend(true, {}, this.defaults, opts, this.$wrapper.data('plugin-options'));
2587
2588                return this;
2589            },
2590
2591            build: function() {
2592                var self = this,
2593                    $html = $('html'),
2594                    $header = $('#header'),
2595                    thumbInfoPreview;
2596
2597                // Add Arrows
2598                $header.find('.dropdown-toggle, .dropdown-submenu > a').append($('<i />').addClass('fa fa-caret-down'));
2599
2600                // Preview Thumbs
2601                self.$wrapper.find('a[data-thumb-preview]').each(function() {
2602                    thumbInfoPreview = $('<span />').addClass('thumb-info thumb-info-preview')
2603                        .append($('<span />').addClass('thumb-info-wrapper')
2604                            .append($('<span />').addClass('thumb-info-image').css('background-image', 'url(' + $(this).data('thumb-preview') + ')')
2605                            )
2606                        );
2607
2608                    $(this).append(thumbInfoPreview);
2609                });
2610
2611                // Side Header Right (Reverse Dropdown)
2612                if($html.hasClass('side-header-right')) {
2613                    $header.find('.dropdown').addClass('dropdown-reverse');
2614                }
2615
2616                return this;
2617            },
2618
2619            events: function() {
2620                var self = this,
2621                    $header = $('#header'),
2622                    $window = $(window);
2623
2624                $header.find('a[href="#"]').on('click', function(e) {
2625                    e.preventDefault();
2626                });
2627
2628                // Mobile Arrows
2629                $header.find('.dropdown-toggle[href="#"], .dropdown-submenu a[href="#"], .dropdown-toggle[href!="#"] .fa-caret-down, .dropdown-submenu a[href!="#"] .fa-caret-down').on('click', function(e) {
2630                    e.preventDefault();
2631                    if ($window.width() < 992) {
2632                        $(this).closest('li').toggleClass('opened');
2633                    }
2634                });
2635
2636                // Touch Devices with normal resolutions
2637                if('ontouchstart' in document.documentElement) {
2638                    $header.find('.dropdown-toggle:not([href="#"]), .dropdown-submenu > a:not([href="#"])')
2639                        .on('touchstart click', function(e) {
2640                            if($window.width() > 991) {
2641
2642                                e.stopPropagation();
2643                                e.preventDefault();
2644
2645                                if(e.handled !== true) {
2646
2647                                    var li = $(this).closest('li');
2648
2649                                    if(li.hasClass('tapped')) {
2650                                        location.href = $(this).attr('href');
2651                                    }
2652
2653                                    li.addClass('tapped');
2654
2655                                    e.handled = true;
2656                                } else {
2657                                    return false;
2658                                }
2659
2660                                return false;
2661
2662                            }
2663                        })
2664                        .on('blur', function(e) {
2665                            $(this).closest('li').removeClass('tapped');
2666                        });
2667
2668                }
2669
2670                // Collapse Nav
2671                $header.find('[data-collapse-nav]').on('click', function(e) {
2672                    $(this).parents('.collapse').removeClass('in');
2673                });
2674
2675                // Anchors Position
2676                $('[data-hash]').each(function() {
2677
2678                    var target = $(this).attr('href'),
2679                        offset = ($(this).is("[data-hash-offset]") ? $(this).data('hash-offset') : 0);
2680
2681                    if($(target).get(0)) {
2682                        $(this).on('click', function(e) {
2683                            e.preventDefault();
2684
2685                            // Close Collapse if Opened
2686                            $(this).parents('.collapse.in').removeClass('in');
2687
2688                            self.scrollToTarget(target, offset);
2689
2690                            return;
2691                        });
2692                    }
2693
2694                });
2695
2696                return this;
2697            },
2698
2699            scrollToTarget: function(target, offset) {
2700                var self = this;
2701
2702                $('body').addClass('scrolling');
2703
2704                $('html, body').animate({
2705                    scrollTop: $(target).offset().top - offset
2706                }, self.options.scrollDelay, self.options.scrollAnimation, function() {
2707                    $('body').removeClass('scrolling');
2708                });
2709
2710                return this;
2711
2712            }
2713
2714        }
2715
2716    });
2717
2718}).apply(this, [window.theme, jQuery]);
2719
2720// Newsletter
2721(function(theme, $) {
2722
2723    theme = theme || {};
2724
2725    var initialized = false;
2726
2727    $.extend(theme, {
2728
2729        Newsletter: {
2730
2731            defaults: {
2732                wrapper: $('#newsletterForm')
2733            },
2734
2735            initialize: function($wrapper, opts) {
2736                if (initialized) {
2737                    return this;
2738                }
2739
2740                initialized = true;
2741                this.$wrapper = ($wrapper || this.defaults.wrapper);
2742
2743                this
2744                    .setOptions(opts)
2745                    .build();
2746
2747                return this;
2748            },
2749
2750            setOptions: function(opts) {
2751                this.options = $.extend(true, {}, this.defaults, opts, this.$wrapper.data('plugin-options'));
2752
2753                return this;
2754            },
2755
2756            build: function() {
2757                if (!($.isFunction($.fn.validate))) {
2758                    return this;
2759                }
2760
2761                var self = this,
2762                    $email = self.$wrapper.find('#newsletterEmail'),
2763                    $success = $('#newsletterSuccess'),
2764                    $error = $('#newsletterError');
2765
2766                self.$wrapper.validate({
2767                    submitHandler: function(form) {
2768
2769                        $.ajax({
2770                            type: 'POST',
2771                            url: self.$wrapper.attr('action'),
2772                            data: {
2773                                'email': $email.val()
2774                            },
2775                            dataType: 'json',
2776                            success: function(data) {
2777                                if (data.response == 'success') {
2778
2779                                    $success.removeClass('hidden');
2780                                    $error.addClass('hidden');
2781
2782                                    $email
2783                                        .val('')
2784                                        .blur()
2785                                        .closest('.control-group')
2786                                        .removeClass('success')
2787                                        .removeClass('error');
2788
2789                                } else {
2790
2791                                    $error.html(data.message);
2792                                    $error.removeClass('hidden');
2793                                    $success.addClass('hidden');
2794
2795                                    $email
2796                                        .blur()
2797                                        .closest('.control-group')
2798                                        .removeClass('success')
2799                                        .addClass('error');
2800
2801                                }
2802                            }
2803                        });
2804
2805                    },
2806                    rules: {
2807                        newsletterEmail: {
2808                            required: true,
2809                            email: true
2810                        }
2811                    },
2812                    errorPlacement: function(error, element) {
2813
2814                    }
2815                });
2816
2817                return this;
2818            }
2819
2820        }
2821
2822    });
2823
2824}).apply(this, [window.theme, jQuery]);
2825
2826// Search
2827(function(theme, $) {
2828
2829    theme = theme || {};
2830
2831    var initialized = false;
2832
2833    $.extend(theme, {
2834
2835        Search: {
2836
2837            defaults: {
2838                wrapper: $('#searchForm')
2839            },
2840
2841            initialize: function($wrapper, opts) {
2842                if (initialized) {
2843                    return this;
2844                }
2845
2846                initialized = true;
2847                this.$wrapper = ($wrapper || this.defaults.wrapper);
2848
2849                this
2850                    .setOptions(opts)
2851                    .build();
2852
2853                return this;
2854            },
2855
2856            setOptions: function(opts) {
2857                this.options = $.extend(true, {}, this.defaults, opts, this.$wrapper.data('plugin-options'));
2858
2859                return this;
2860            },
2861
2862            build: function() {
2863                if (!($.isFunction($.fn.validate))) {
2864                    return this;
2865                }
2866
2867                this.$wrapper.validate({
2868                    errorPlacement: function(error, element) {}
2869                });
2870
2871                return this;
2872            }
2873
2874        }
2875
2876    });
2877
2878}).apply(this, [window.theme, jQuery]);
2879
2880// Sticky Header
2881(function(theme, $) {
2882
2883    theme = theme || {};
2884
2885    var initialized = false;
2886
2887    $.extend(theme, {
2888
2889        StickyHeader: {
2890
2891            defaults: {
2892                wrapper: $('#header'),
2893                headerBody: $('#header .header-body'),
2894                stickyEnabled: true,
2895                stickyEnableOnBoxed: true,
2896                stickyEnableOnMobile: true,
2897                stickyStartAt: 0,
2898                stickyStartAtElement: false,
2899                stickySetTop: 0,
2900                stickyChangeLogo: false,
2901                stickyChangeLogoWrapper: true
2902            },
2903
2904            initialize: function($wrapper, opts) {
2905                if (initialized) {
2906                    return this;
2907                }
2908
2909                initialized = true;
2910                this.$wrapper = ($wrapper || this.defaults.wrapper);
2911
2912                this
2913                    .setOptions(opts)
2914                    .build()
2915                    .events();
2916
2917                return this;
2918            },
2919
2920            setOptions: function(opts) {
2921                this.options = $.extend(true, {}, this.defaults, opts, this.$wrapper.data('plugin-options'));
2922
2923                return this;
2924            },
2925
2926            build: function() {
2927                if (!this.options.stickyEnableOnBoxed && $('html').hasClass('boxed') || !this.options.stickyEnabled) {
2928                    return this;
2929                }
2930
2931                var self = this,
2932                    $html = $('html'),
2933                    $window = $(window),
2934                    sideHeader = $html.hasClass('side-header');
2935
2936                // HTML Classes
2937                $html.addClass('sticky-header-enabled');
2938
2939                if (parseInt(self.options.stickySetTop) < 0) {
2940                    $html.addClass('sticky-header-negative');
2941                }
2942
2943                // Set Start At
2944                if(self.options.stickyStartAtElement) {
2945
2946                    var $stickyStartAtElement = $(self.options.stickyStartAtElement);
2947
2948                    $(window).on('scroll resize', function() {
2949                        self.options.stickyStartAt = $stickyStartAtElement.offset().top;
2950                    });
2951
2952                    $(window).trigger('resize');
2953                }
2954
2955                // Boxed
2956                if($html.hasClass('boxed') && (parseInt(self.options.stickyStartAt) == 0) && $window.width() > 991) {
2957                    self.options.stickyStartAt = 30;
2958                }
2959
2960                // Set Wrapper Min-Height
2961                self.options.wrapper.css('min-height', self.options.wrapper.height());
2962
2963                // Check Sticky Header
2964                self.checkStickyHeader = function() {
2965                    if ($window.scrollTop() >= parseInt(self.options.stickyStartAt)) {
2966                        self.activateStickyHeader();
2967                    } else {
2968                        self.deactivateStickyHeader();
2969                    }
2970                };
2971
2972                // Activate Sticky Header
2973                self.activateStickyHeader = function() {
2974
2975                    if ($window.width() < 992) {
2976                        if (!self.options.stickyEnableOnMobile) {
2977                            self.deactivateStickyHeader();
2978                            return;
2979                        }
2980                    } else {
2981                        if (sideHeader) {
2982                            self.deactivateStickyHeader();
2983                            return;
2984                        }
2985                    }
2986
2987                    $html.addClass('sticky-header-active');
2988
2989                    self.options.headerBody.css('top', self.options.stickySetTop);
2990
2991                    if (self.options.stickyChangeLogo) {
2992                        self.changeLogo(true);
2993                    }
2994
2995                    $.event.trigger({
2996                        type: 'stickyHeader.activate'
2997                    });
2998                };
2999
3000                // Deactivate Sticky Header
3001                self.deactivateStickyHeader = function() {
3002
3003                    $html.removeClass('sticky-header-active');
3004
3005                    self.options.headerBody.css('top', 0);
3006
3007                    if (self.options.stickyChangeLogo) {
3008                        self.changeLogo(false);
3009                    }
3010
3011                    $.event.trigger({
3012                        type: 'stickyHeader.deactivate'
3013                    });
3014                };
3015
3016                // Always Sticky
3017                if (parseInt(self.options.stickyStartAt) <= 0) {
3018                    self.activateStickyHeader();
3019                }
3020
3021                // Set Logo
3022                if (self.options.stickyChangeLogo) {
3023
3024                    var $logoWrapper = self.options.wrapper.find('.header-logo'),
3025                        $logo = $logoWrapper.find('img'),
3026                        logoWidth = $logo.attr('width'),
3027                        logoHeight = $logo.attr('height'),
3028                        logoSmallTop = parseInt($logo.attr('data-sticky-top') ? $logo.attr('data-sticky-top') : 0),
3029                        logoSmallWidth = parseInt($logo.attr('data-sticky-width') ? $logo.attr('data-sticky-width') : 'auto'),
3030                        logoSmallHeight = parseInt($logo.attr('data-sticky-height') ? $logo.attr('data-sticky-height') : 'auto');
3031
3032                    if (self.options.stickyChangeLogoWrapper) {
3033                        $logoWrapper.css({
3034                            'width': $logo.outerWidth(true),
3035                            'height': $logo.outerHeight(true)
3036                        });
3037                    }
3038
3039                    self.changeLogo = function(activate) {
3040                        if(activate) {
3041                            $logo.css({
3042                                'top': logoSmallTop,
3043                                'width': logoSmallWidth,
3044                                'height': logoSmallHeight
3045                            });
3046                        } else {
3047                            $logo.css({
3048                                'top': 0,
3049                                'width': logoWidth,
3050                                'height': logoHeight
3051                            });
3052                        }
3053                    }
3054
3055                }
3056
3057                return this;
3058            },
3059
3060            events: function() {
3061                var self = this;
3062
3063                if (!this.options.stickyEnableOnBoxed && $('body').hasClass('boxed') || !this.options.stickyEnabled) {
3064                    return this;
3065                }
3066
3067                if (!self.options.alwaysStickyEnabled) {
3068                    $(window).on('scroll resize', function() {
3069                        self.checkStickyHeader();
3070                    });
3071                } else {
3072                    self.activateStickyHeader();
3073                }
3074
3075                return this;
3076            }
3077
3078        }
3079
3080    });
3081
3082}).apply(this, [window.theme, jQuery]);

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.