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