PageSourceSearch

https://steinmillerins.com/js/theme.js

js steinmillerins.com collected 2026-09-26 08:15:46 UTC 151,904 bytes, 6,420 lines download raw bytes

1/*
2Name: 			Theme Base
3Written by: 	Okler Themes - (http://www.okler.net)
4Theme Version:	8.2.0
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: -80,
51		delay: 100,
52		duration: '750ms',
53		minWindowWidth: 767,
54		forceAnimation: false
55	};
56
57	PluginAnimate.prototype = {
58		initialize: function($el, opts) {
59			if ($el.data(instanceName)) {
60				return this;
61			}
62
63			this.$el = $el;
64
65			this
66				.setData()
67				.setOptions(opts)
68				.build();
69
70			return this;
71		},
72
73		setData: function() {
74			this.$el.data(instanceName, this);
75
76			return this;
77		},
78
79		setOptions: function(opts) {
80			this.options = $.extend(true, {}, PluginAnimate.defaults, opts, {
81				wrapper: this.$el
82			});
83
84			return this;
85		},
86
87		build: function() {
88			var self = this;
89
90			if($('body').hasClass('loading-overlay-showing')) {
91				$(window).on('loading.overlay.ready', function(){
92					self.animate();
93				});
94			} else {
95				self.animate();
96			}
97
98			return this;
99		},
100
101		animate: function() {
102			var self = this,
103				$el = this.options.wrapper,
104				delay = 0,
105				duration = this.options.duration,
106				elTopDistance = $el.offset().top,
107				windowTopDistance = $(window).scrollTop();
108
109			$el.addClass('appear-animation animated');
110
111			if (!$('html').hasClass('no-csstransitions') && $(window).width() > self.options.minWindowWidth && elTopDistance >= windowTopDistance || self.options.forceAnimation == true) {
112
113				$el.appear(function() {
114
115					$el.one('animation:show', function(ev) {
116						delay = ($el.attr('data-appear-animation-delay') ? $el.attr('data-appear-animation-delay') : self.options.delay);
117						duration = ($el.attr('data-appear-animation-duration') ? $el.attr('data-appear-animation-duration') : self.options.duration);
118
119						if (duration != '750ms') {
120							$el.css('animation-duration', duration);
121						}
122
123						$el.css('animation-delay', delay + 'ms');
124
125						$el.addClass($el.attr('data-appear-animation') + ' appear-animation-visible');
126					});
127
128					$el.trigger('animation:show');
129
130				}, {
131					accX: self.options.accX,
132					accY: self.options.accY
133				});
134
135			} else {
136
137				$el.addClass('appear-animation-visible');
138
139			}
140
141			return this;
142		}
143	};
144
145	// expose to scope
146	$.extend(theme, {
147		PluginAnimate: PluginAnimate
148	});
149
150	// jquery plugin
151	$.fn.themePluginAnimate = function(opts) {
152		return this.map(function() {
153			var $this = $(this);
154
155			if ($this.data(instanceName)) {
156				return $this.data(instanceName);
157			} else {
158				return new PluginAnimate($this, opts);
159			}
160
161		});
162	};
163
164}).apply(this, [window.theme, jQuery]);
165
166// Animated Letters
167(function(theme, $) {
168
169	theme = theme || {};
170
171	var instanceName = '__animatedLetters';
172
173	var PluginAnimatedLetters = function($el, opts) {
174		return this.initialize($el, opts);
175	};
176
177	PluginAnimatedLetters.defaults = {
178		animationName: 'fadeIn',
179		animationSpeed: 50,
180		startDelay: 500,
181		minWindowWidth: 768,
182		letterClass: ''
183	};
184
185	PluginAnimatedLetters.prototype = {
186		initialize: function($el, opts) {
187			if ($el.data(instanceName)) {
188				return this;
189			}
190
191			var self = this;
192
193			this.$el = $el;
194			this.initialText = $el.text();
195
196			// If it's inside a carousel, wait for the initializaion of the carousel
197			if( self.$el.closest('.owl-carousel').get(0) ) {
198				self.$el.closest('.owl-carousel').on('initialized.owl.carousel', function(){
199					self
200						.setData()
201						.setOptions(opts)
202						.build()
203						.events();					
204				});
205
206				return this;
207			}
208
209			this
210				.setData()
211				.setOptions(opts)
212				.build()
213				.events();
214
215			return this;
216		},
217
218		setData: function() {
219			this.$el.data(instanceName, this);
220
221			return this;
222		},
223
224		setOptions: function(opts) {
225			this.options = $.extend(true, {}, PluginAnimatedLetters.defaults, opts, {
226				wrapper: this.$el
227			});
228
229			return this;
230		},
231
232		build: function() {
233			var self    = this,
234				letters = self.$el.text().split('');
235
236			if( $(window).width() < self.options.minWindowWidth ) {
237				return this;
238			}
239
240			// Add class to show
241			self.$el.addClass('initialized');			
242
243			// Set Min Height to avoid flicking issues
244			self.setMinHeight();
245
246			self.$el.text('');
247
248			setTimeout(function(){
249				for( var i = 0; i < letters.length; i++ ) {
250					var letter = letters[i];
251					
252					self.$el.append( '<span class="letter '+ ( self.options.letterClass ? self.options.letterClass + ' ' : '' ) + self.options.animationName +' animated" style="animation-delay: '+ ( i * self.options.animationSpeed ) +'ms;">' + letter + '</span>' );
253
254				}
255			}, self.options.startDelay);
256
257			return this;
258		},
259
260		setMinHeight: function() {
261			var self = this;
262
263			// if it's inside carousel
264			if( self.$el.closest('.owl-carousel').get(0) ) {
265				self.$el.closest('.owl-carousel').addClass('d-block');
266				self.$el.css( 'min-height', self.$el.height() );
267				self.$el.closest('.owl-carousel').removeClass('d-block');
268			} else {
269				self.$el.css( 'min-height', self.$el.height() );
270			}
271
272			return this;
273		},
274
275		destroy: function() {
276			var self = this;
277
278			self.$el
279				.html( self.initialText )
280				.css( 'min-height', '' );
281
282			return this;
283		},
284
285		events: function() {
286			var self = this;
287
288			// Destroy
289			self.$el.on('animated.letters.destroy', function(){
290				self.destroy();
291			});
292
293			// Initialize
294			self.$el.on('animated.letters.initialize', function(){
295				self.build();
296			});
297
298			return this;
299		}
300	};
301
302	// expose to scope
303	$.extend(theme, {
304		PluginAnimatedLetters: PluginAnimatedLetters
305	});
306
307	// jquery plugin
308	$.fn.themePluginAnimatedLetters = function(opts) {
309		return this.map(function() {
310			var $this = $(this);
311
312			if ($this.data(instanceName)) {
313				return $this.data(instanceName);
314			} else {
315				return new PluginAnimatedLetters($this, opts);
316			}
317
318		});
319	}
320
321}).apply(this, [window.theme, jQuery]);
322
323// Before / After
324(function(theme, $) {
325
326	theme = theme || {};
327
328	var instanceName = '__beforeafter';
329
330	var PluginBeforeAfter = function($el, opts) {
331		return this.initialize($el, opts);
332	};
333
334	PluginBeforeAfter.defaults = {
335		
336	};
337
338	PluginBeforeAfter.prototype = {
339		initialize: function($el, opts) {
340			this.$el = $el;
341
342			this
343				.setData()
344				.setOptions(opts)
345				.build();
346
347			return this;
348		},
349
350		setData: function() {
351			this.$el.data(instanceName, this);
352
353			return this;
354		},
355
356		setOptions: function(opts) {
357			this.options = $.extend(true, {}, PluginBeforeAfter.defaults, opts, {
358				wrapper: this.$el
359			});
360
361			return this;
362		},
363
364		build: function() {
365
366			if (!($.isFunction($.fn.twentytwenty))) {
367				return this;
368			}
369
370			var self = this;
371
372			self.options.wrapper
373				.twentytwenty(self.options);
374
375			return this;
376
377		}
378	};
379
380	// expose to scope
381	$.extend(theme, {
382		PluginBeforeAfter: PluginBeforeAfter
383	});
384
385	// jquery plugin
386	$.fn.themePluginBeforeAfter = function(opts) {
387		return this.map(function() {
388			var $this = $(this);
389
390			if ($this.data(instanceName)) {
391				return $this.data(instanceName);
392			} else {
393				return new PluginBeforeAfter($this, opts);
394			}
395
396		});
397	}
398
399}).apply(this, [window.theme, jQuery]);
400
401// Carousel
402(function(theme, $) {
403
404	theme = theme || {};
405
406	var instanceName = '__carousel';
407
408	var PluginCarousel = function($el, opts) {
409		return this.initialize($el, opts);
410	};
411
412	PluginCarousel.defaults = {
413		loop: true,
414		responsive: {
415			0: {
416				items: 1
417			},
418			479: {
419				items: 1
420			},
421			768: {
422				items: 2
423			},
424			979: {
425				items: 3
426			},
427			1199: {
428				items: 4
429			}
430		},
431		navText: [],
432		refresh: false
433	};
434
435	PluginCarousel.prototype = {
436		initialize: function($el, opts) {
437			if ($el.data(instanceName)) {
438				return this;
439			}
440
441			this.$el = $el;
442
443			// If has data-icon inside, initialize only after icons get rendered
444			// Prevent flicking issues
445			if( $el.find('[data-icon]').get(0) ) {
446				var self = this;
447
448				$(window).on('icon.rendered', function(){
449					if ($el.data(instanceName)) {
450						return this;
451					}
452
453					setTimeout(function(){
454						self
455							.setData()
456							.setOptions(opts)
457							.build();
458					}, 1000);
459				});
460
461				return this;
462			}
463
464			this
465				.setData()
466				.setOptions(opts)
467				.build();
468
469			return this;
470		},
471
472		setData: function() {
473			this.$el.data(instanceName, this);
474
475			return this;
476		},
477
478		setOptions: function(opts) {
479			this.options = $.extend(true, {}, PluginCarousel.defaults, opts, {
480				wrapper: this.$el
481			});
482
483			return this;
484		},
485
486		build: function() {
487			if (!($.isFunction($.fn.owlCarousel))) {
488				return this;
489			}
490
491			var self = this,
492				$el = this.options.wrapper;
493
494			// Add Theme Class
495			$el.addClass('owl-theme');
496
497			// Add Loading
498			$el.addClass('owl-loading');
499
500			// Force RTL according to HTML dir attribute
501			if ($('html').attr('dir') == 'rtl') {
502				this.options = $.extend(true, {}, this.options, {
503					rtl: true
504				});
505			}
506
507			if (this.options.items == 1) {
508				this.options.responsive = {}
509			}
510
511			if (this.options.items > 4) {
512				this.options = $.extend(true, {}, this.options, {
513					responsive: {
514						1199: {
515							items: this.options.items
516						}
517					}
518				});
519			}
520
521			// Auto Height Fixes
522			if (this.options.autoHeight) {
523				var itemsHeight = [];
524
525				$el.find('.owl-item').each(function(){
526					if( $(this).hasClass('active') ) {
527						itemsHeight.push( $(this).height() );
528					}
529				});
530
531				$(window).afterResize(function() {
532					$el.find('.owl-stage-outer').height( Math.max.apply(null, itemsHeight) );
533				});
534
535				$(window).on('load', function() {
536					$el.find('.owl-stage-outer').height( Math.max.apply(null, itemsHeight) );
537				});
538			}
539
540			// Initialize OwlCarousel
541			$el.owlCarousel(this.options).addClass('owl-carousel-init animated fadeIn');
542
543			// Remove "animated fadeIn" class to prevent conflicts
544			setTimeout(function(){
545				$el.removeClass('animated fadeIn');
546			}, 1000);
547
548			// Owl Carousel Wrapper
549			if( $el.closest('.owl-carousel-wrapper').get(0) ) {
550				setTimeout(function(){
551					$el.closest('.owl-carousel-wrapper').css({
552						height: ''
553					});
554				}, 500);
555			}
556
557			// Nav Offset
558			self.navigationOffsets();
559
560			// Nav Outside
561			if( $el.hasClass('nav-outside') ) {
562				$(window).on('owl.carousel.nav.outside', function(){
563					if( $(window).width() < 992 ) {
564						self.options.stagePadding = 40;
565						$el.addClass('stage-margin');
566					} else {
567						self.options.stagePadding = 0;
568						$el.removeClass('stage-margin');
569					}
570
571					$el.owlCarousel('destroy').owlCarousel( self.options );
572
573					// Nav Offset
574					self.navigationOffsets();
575				});
576
577				// Window Resize
578				$(window).on('load', function(){
579					$(window).afterResize(function(){
580						$(window).trigger('owl.carousel.nav.outside');
581					});
582				});
583
584				// First Load
585				$(window).trigger('owl.carousel.nav.outside');
586			}
587
588			// Nav style 5 (SVG Arrows)
589			if( $el.hasClass('nav-svg-arrows-1') ) {
590				var svg_arrow = '' +
591					'<svg version="1.1" viewBox="0 0 15.698 8.706" width="17" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' +
592						'<polygon stroke="#212121" stroke-width="0.1" fill="#212121" points="11.354,0 10.646,0.706 13.786,3.853 0,3.853 0,4.853 13.786,4.853 10.646,8 11.354,8.706 15.698,4.353 "/>' +
593					'</svg>';
594
595				$el.find('.owl-next, .owl-prev').append( svg_arrow );
596			}
597
598			// Sync
599			if( $el.attr('data-sync') ) {
600				$el.on('change.owl.carousel', function(event) {
601					if (event.namespace && event.property.name === 'position') {
602					    var target = event.relatedTarget.relative(event.property.value, true);
603					    $( $el.data('sync') ).owlCarousel('to', target, 300, true);				        
604				  	}
605				});
606			}
607
608			// Carousel Center Active Item
609			if( $el.hasClass('carousel-center-active-item') ) {
610				var itemsActive    = $el.find('.owl-item.active'),
611					indexCenter    = Math.floor( ($el.find('.owl-item.active').length - 1) / 2 ),
612					itemCenter     = itemsActive.eq(indexCenter);
613
614				itemCenter.addClass('current');
615
616				$el.on('change.owl.carousel', function(event) {
617				  	$el.find('.owl-item').removeClass('current');
618					
619					setTimeout(function(){
620					  	var itemsActive    = $el.find('.owl-item.active'),
621					  		indexCenter    = Math.floor( ($el.find('.owl-item.active').length - 1) / 2 ),
622					  		itemCenter     = itemsActive.eq(indexCenter);
623
624					  	itemCenter.addClass('current');
625					}, 100);
626				});
627
628				// Refresh
629				$el.trigger('refresh.owl.carousel');
630
631			}
632
633			// AnimateIn / AnimateOut Fix
634			if( self.options.animateIn || self.options.animateOut ) {
635				$el.on('change.owl.carousel', function(event) {
636
637					// Hide elements inside carousel
638				    $el.find('[data-appear-animation], [data-plugin-animated-letters]').addClass('d-none');
639
640				    // Animated Letters
641				    $el.find('[data-plugin-animated-letters]').trigger('animated.letters.destroy');
642
643				    // Remove "d-none" class before show the element. This is useful when using background images inside a carousel. Like ken burns effect
644				    $el.find('.owl-item:not(.active) [data-carousel-onchange-show]').removeClass('d-none');
645
646				});
647
648				$el.on('changed.owl.carousel', function(event) {
649					setTimeout(function(){
650
651					    // Appear Animation
652					    if( $el.find('.owl-item.cloned [data-appear-animation]').get(0) ) {
653					    	$el.find('.owl-item.cloned [data-appear-animation]').each(function() {
654								var $this = $(this),
655									opts;
656
657								var pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
658								if (pluginOptions)
659									opts = pluginOptions;
660
661								$this.themePluginAnimate(opts);
662							});
663					    }
664
665						// Show elements inside carousel
666					    $el.find('.owl-item.active [data-appear-animation], [data-plugin-animated-letters]').removeClass('d-none');
667
668					    // Animated Letters
669					    $el.find('.owl-item.active [data-plugin-animated-letters]').trigger('animated.letters.initialize');
670
671					    // Background Video
672					    $el.find('.owl-item.cloned.active [data-plugin-video-background]').trigger('video.background.initialize');
673
674					}, 1000);
675				    
676				});
677			}
678
679			// Render Background Videos inside carousel. Just a trigger on window is sufficient to render
680			if( $el.find('[data-plugin-video-background]').get(0) ) {
681				$(window).resize();
682			}
683
684			// Remove Loading
685			$el.removeClass('owl-loading');
686
687			// Remove Height
688			$el.css('height', 'auto');
689
690			// Carousel Navigate By ID and item index
691			self.carouselNavigate();
692
693			// Refresh Carousel
694			if( self.options.refresh ) {
695				$el.owlCarousel('refresh');
696			}
697
698			return this;
699		},
700
701		navigationOffsets: function() {
702			var self 			 = this,
703				$el  			 = this.options.wrapper,
704				navHasTransform  = $el.find('.owl-nav').css('transform') == 'none' ? false : true,
705				dotsHasTransform = $el.find('.owl-dots').css('transform') == 'none' ? false : true;
706
707			// ************* NAV *****************
708			// Nav Offset - Horizontal
709			if( self.options.navHorizontalOffset && !self.options.navVerticalOffset ) {
710				if( !navHasTransform ) {
711					$el.find('.owl-nav').css({
712						transform: 'translate3d('+ self.options.navHorizontalOffset +', 0, 0)'
713					});
714				} else {
715					$el.find('.owl-nav').css({
716						left: self.options.navHorizontalOffset
717					});
718				}
719			}
720
721			// Nav Offset - Vertical
722			if( self.options.navVerticalOffset && !self.options.navHorizontalOffset ) {
723				if( !navHasTransform ) {
724					$el.find('.owl-nav').css({
725						transform: 'translate3d(0, '+ self.options.navVerticalOffset +', 0)'
726					});
727				} else {
728					$el.find('.owl-nav').css({
729						top: 'calc( 50% - '+ self.options.navVerticalOffset +' )'
730					});
731				}
732			}
733
734			// Nav Offset - Horizontal & Vertical
735			if( self.options.navVerticalOffset && self.options.navHorizontalOffset ) {
736				if( !navHasTransform ) {
737					$el.find('.owl-nav').css({
738						transform: 'translate3d('+ self.options.navHorizontalOffset +', '+ self.options.navVerticalOffset +', 0)'
739					});
740				} else {
741					$el.find('.owl-nav').css({
742						top: 'calc( 50% - '+ self.options.navVerticalOffset +' )',
743						left: self.options.navHorizontalOffset
744					});
745				}
746			}
747
748			// ********** DOTS *********************
749			// Dots Offset - Horizontal
750			if( self.options.dotsHorizontalOffset && !self.options.dotsVerticalOffset ) {
751				$el.find('.owl-dots').css({
752					transform: 'translate3d('+ self.options.dotsHorizontalOffset +', 0, 0)'
753				});
754			}
755
756			// Dots Offset - Vertical
757			if( self.options.dotsVerticalOffset && !self.options.dotsHorizontalOffset ) {
758				if( !dotsHasTransform ) {
759					$el.find('.owl-dots').css({
760						transform: 'translate3d(0, '+ self.options.dotsVerticalOffset +', 0)'
761					});
762				} else {
763					$el.find('.owl-dots').css({
764						top: 'calc( 50% - '+ self.options.dotsVerticalOffset +' )'
765					});
766				}
767			}
768
769			// Dots Offset - Horizontal & Vertical
770			if( self.options.dotsVerticalOffset && self.options.dotsHorizontalOffset ) {
771				$el.find('.owl-dots').css({
772					transform: 'translate3d('+ self.options.dotsHorizontalOffset +', '+ self.options.dotsVerticalOffset +', 0)'
773				});
774			}
775
776			return this;
777		},
778
779		carouselNavigate: function() {
780			var self      = this,
781				$el       = this.options.wrapper,
782				$carousel = $el.data('owl.carousel');
783
784			if( $('[data-carousel-navigate]').get(0) ) {
785				$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').each(function(){
786					var $this = $(this),
787						hasCarousel = $( $this.data('carousel-navigate-id') ).get(0),
788						toIndex = $this.data('carousel-navigate-to');
789
790					if( hasCarousel ) {
791
792						$this.on('click', function(){
793							$carousel.to( parseInt(toIndex) - 1 );
794						});
795
796					}
797				});
798
799				$el.on('change.owl.carousel', function(){
800					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').removeClass('active');
801				});
802
803				$el.on('changed.owl.carousel', function(e){
804					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"][data-carousel-navigate-to="'+ ( e.item.index + 1 ) +'"]').addClass('active');
805				});
806			}
807
808			return this;
809		}
810	};
811
812	// expose to scope
813	$.extend(theme, {
814		PluginCarousel: PluginCarousel
815	});
816
817	// jquery plugin
818	$.fn.themePluginCarousel = function(opts) {
819		return this.map(function() {
820			var $this = $(this);
821
822			if ($this.data(instanceName)) {
823				return $this.data(instanceName);
824			} else {
825				return new PluginCarousel($this, opts);
826			}
827
828		});
829	}
830
831}).apply(this, [window.theme, jQuery]);
832
833// Chart Circular
834(function(theme, $) {
835
836	theme = theme || {};
837
838	var instanceName = '__chartCircular';
839
840	var PluginChartCircular = function($el, opts) {
841		return this.initialize($el, opts);
842	};
843
844	PluginChartCircular.defaults = {
845		accX: 0,
846		accY: -150,
847		delay: 1,
848		barColor: '#0088CC',
849		trackColor: '#f2f2f2',
850		scaleColor: false,
851		scaleLength: 5,
852		lineCap: 'round',
853		lineWidth: 13,
854		size: 175,
855		rotate: 0,
856		animate: ({
857			duration: 2500,
858			enabled: true
859		})
860	};
861
862	PluginChartCircular.prototype = {
863		initialize: function($el, opts) {
864			if ($el.data(instanceName)) {
865				return this;
866			}
867
868			this.$el = $el;
869
870			this
871				.setData()
872				.setOptions(opts)
873				.build();
874
875			return this;
876		},
877
878		setData: function() {
879			this.$el.data(instanceName, this);
880
881			return this;
882		},
883
884		setOptions: function(opts) {
885			this.options = $.extend(true, {}, PluginChartCircular.defaults, opts, {
886				wrapper: this.$el
887			});
888
889			return this;
890		},
891
892		build: function() {
893			if (!($.isFunction($.fn.appear)) || !($.isFunction($.fn.easyPieChart))) {
894				return this;
895			}
896
897			var self = this,
898				$el = this.options.wrapper,
899				value = ($el.attr('data-percent') ? $el.attr('data-percent') : 0),
900				percentEl = $el.find('.percent');
901
902			$.extend(true, self.options, {
903				onStep: function(from, to, currentValue) {
904					percentEl.html(parseInt(currentValue));
905				}
906			});
907
908			$el.attr('data-percent', 0);
909
910			$el.appear(function() {
911
912				$el.easyPieChart(self.options);
913
914				setTimeout(function() {
915
916					$el.data('easyPieChart').update(value);
917					$el.attr('data-percent', value);
918
919				}, self.options.delay);
920
921			}, {
922				accX: self.options.accX,
923				accY: self.options.accY
924			});
925
926			return this;
927		}
928	};
929
930	// expose to scope
931	$.extend(theme, {
932		PluginChartCircular: PluginChartCircular
933	});
934
935	// jquery plugin
936	$.fn.themePluginChartCircular = function(opts) {
937		return this.map(function() {
938			var $this = $(this);
939
940			if ($this.data(instanceName)) {
941				return $this.data(instanceName);
942			} else {
943				return new PluginChartCircular($this, opts);
944			}
945
946		});
947	}
948
949}).apply(this, [window.theme, jQuery]);
950
951// Countdown
952(function(theme, $) {
953
954	theme = theme || {};
955
956	var instanceName = '__countdown';
957
958	var PluginCountdown = function($el, opts) {
959		return this.initialize($el, opts);
960	};
961
962	PluginCountdown.defaults = {
963		date: '2030/06/10 12:00:00',
964		textDay: 'DAY',
965		textHour: 'HRS',
966		textMin: 'MIN',
967		textSec: 'SEC',
968		uppercase: true,
969		numberClass: '',
970		wrapperClass: '',
971		insertHTMLbefore: '',
972		insertHTMLafter: ''
973	};
974
975	PluginCountdown.prototype = {
976		initialize: function($el, opts) {
977			if ($el.data(instanceName)) {
978				return this;
979			}
980
981			this.$el = $el;
982
983			this
984				.setData()
985				.setOptions(opts)
986				.build();
987
988			return this;
989		},
990
991		setData: function() {
992			this.$el.data(instanceName, this);
993
994			return this;
995		},
996
997		setOptions: function(opts) {
998			this.options = $.extend(true, {}, PluginCountdown.defaults, opts, {
999				wrapper: this.$el
1000			});
1001
1002			return this;
1003		},
1004
1005		build: function() {
1006			if (!($.isFunction($.fn.countTo))) {
1007				return this;
1008			}
1009
1010			var self = this,
1011				$el = this.options.wrapper,
1012				numberClass = ( self.options.numberClass ) ? ' ' + self.options.numberClass : '',
1013				wrapperClass = ( self.options.wrapperClass ) ? ' ' + self.options.wrapperClass : '';
1014
1015			if( self.options.uppercase ) {
1016				$el.countdown(self.options.date).on('update.countdown', function(event) {
1017					var $this = $(this).html(event.strftime(self.options.insertHTMLbefore
1018						+ '<span class="days'+ wrapperClass +'"><span class="'+ numberClass +'">%D</span> '+ self.options.textDay +'<div class="d-inline text-uppercase">%!d</div></span> '
1019						+ '<span class="hours'+ wrapperClass +'"><span class="'+ numberClass +'">%H</span> '+ self.options.textHour +'</span> '
1020						+ '<span class="minutes'+ wrapperClass +'"><span class="'+ numberClass +'">%M</span> '+ self.options.textMin +'</span> '
1021						+ '<span class="seconds'+ wrapperClass +'"><span class="'+ numberClass +'">%S</span> '+ self.options.textSec +'</span> '
1022						+ self.options.insertHTMLafter
1023					));
1024				});
1025			} else {
1026				$el.countdown(self.options.date).on('update.countdown', function(event) {
1027					var $this = $(this).html(event.strftime(self.options.insertHTMLbefore
1028						+ '<span class="days'+ wrapperClass +'"><span class="'+ numberClass +'">%D</span> '+ self.options.textDay +'%!d</span> '
1029						+ '<span class="hours'+ wrapperClass +'"><span class="'+ numberClass +'">%H</span> '+ self.options.textHour +'</span> '
1030						+ '<span class="minutes'+ wrapperClass +'"><span class="'+ numberClass +'">%M</span> '+ self.options.textMin +'</span> '
1031						+ '<span class="seconds'+ wrapperClass +'"><span class="'+ numberClass +'">%S</span> '+ self.options.textSec +'</span> '
1032						+ self.options.insertHTMLafter
1033					));
1034				});
1035			}
1036
1037			return this;
1038		}
1039	};
1040
1041	// expose to scope
1042	$.extend(theme, {
1043		PluginCountdown: PluginCountdown
1044	});
1045
1046	// jquery plugin
1047	$.fn.themePluginCountdown = function(opts) {
1048		return this.map(function() {
1049			var $this = $(this);
1050
1051			if ($this.data(instanceName)) {
1052				return $this.data(instanceName);
1053			} else {
1054				return new PluginCountdown($this, opts);
1055			}
1056
1057		});
1058	}
1059
1060}).apply(this, [window.theme, jQuery]);
1061
1062// Counter
1063(function(theme, $) {
1064
1065	theme = theme || {};
1066
1067	var instanceName = '__counter';
1068
1069	var PluginCounter = function($el, opts) {
1070		return this.initialize($el, opts);
1071	};
1072
1073	PluginCounter.defaults = {
1074		accX: 0,
1075		accY: 0,
1076		appendWrapper: false,
1077		prependWrapper: false,
1078		speed: 3000,
1079		refreshInterval: 100,
1080		decimals: 0,
1081		onUpdate: null,
1082		onComplete: null
1083	};
1084
1085	PluginCounter.prototype = {
1086		initialize: function($el, opts) {
1087			if ($el.data(instanceName)) {
1088				return this;
1089			}
1090
1091			this.$el = $el;
1092
1093			this
1094				.setData()
1095				.setOptions(opts)
1096				.build();
1097
1098			return this;
1099		},
1100
1101		setData: function() {
1102			this.$el.data(instanceName, this);
1103
1104			return this;
1105		},
1106
1107		setOptions: function(opts) {
1108			this.options = $.extend(true, {}, PluginCounter.defaults, opts, {
1109				wrapper: this.$el
1110			});
1111
1112			return this;
1113		},
1114
1115		build: function() {
1116			if (!($.isFunction($.fn.countTo))) {
1117				return this;
1118			}
1119
1120			var self = this,
1121				$el = this.options.wrapper;
1122
1123			$.extend(self.options, {
1124				onComplete: function() {
1125					
1126					if ($el.data('append')) {
1127						if( self.options.appendWrapper ) {
1128							var appendWrapper = $( self.options.appendWrapper );
1129
1130							appendWrapper.append( $el.data('append') );
1131
1132							$el.html( $el.html() + appendWrapper[0].outerHTML );
1133						} else {
1134							$el.html($el.html() + $el.data('append'));
1135						}
1136					}
1137
1138					if ($el.data('prepend')) {
1139						if( self.options.prependWrapper ) {
1140							var prependWrapper = $( self.options.prependWrapper );
1141
1142							prependWrapper.append( $el.data('prepend') );
1143
1144							$el.html( $el.html() + prependWrapper[0].outerHTML );
1145						} else {
1146							$el.html($el.data('prepend') + $el.html());
1147						}
1148					}
1149				}
1150			});
1151
1152			$el.appear(function() {
1153
1154				$el.countTo(self.options);
1155
1156			}, {
1157				accX: self.options.accX,
1158				accY: self.options.accY
1159			});
1160
1161			return this;
1162		}
1163	};
1164
1165	// expose to scope
1166	$.extend(theme, {
1167		PluginCounter: PluginCounter
1168	});
1169
1170	// jquery plugin
1171	$.fn.themePluginCounter = function(opts) {
1172		return this.map(function() {
1173			var $this = $(this);
1174
1175			if ($this.data(instanceName)) {
1176				return $this.data(instanceName);
1177			} else {
1178				return new PluginCounter($this, opts);
1179			}
1180
1181		});
1182	}
1183
1184}).apply(this, [window.theme, jQuery]);
1185
1186// Float Element
1187(function(theme, $) {
1188
1189	'use strict';
1190
1191	theme = theme || {};
1192
1193	var instanceName = '__floatElement';
1194
1195	var PluginFloatElement = function($el, opts) {
1196		return this.initialize($el, opts);
1197	};
1198
1199	PluginFloatElement.defaults = {
1200		startPos: 'top',
1201		speed: 3,
1202		horizontal: false,
1203		isInsideSVG: false,
1204		transition: false,
1205		transitionDelay: 0,
1206		transitionDuration: 500
1207	};
1208
1209	PluginFloatElement.prototype = {
1210		initialize: function($el, opts) {
1211			if ($el.data(instanceName)) {
1212				return this;
1213			}
1214
1215			this.$el = $el;
1216
1217			this
1218				.setData()
1219				.setOptions(opts)
1220				.build();
1221
1222			return this;
1223		},
1224
1225		setData: function() {
1226			this.$el.data(instanceName, this);
1227
1228			return this;
1229		},
1230
1231		setOptions: function(opts) {
1232			this.options = $.extend(true, {}, PluginFloatElement.defaults, opts, {
1233				wrapper: this.$el
1234			});
1235
1236			return this;
1237		},
1238
1239		build: function() {
1240			var self = this,
1241				$el = this.options.wrapper,
1242				$window = $(window),
1243				minus;
1244
1245			if( self.options.style ) {
1246				$el.attr('style', self.options.style);
1247			}
1248
1249			if( $window.width() > 767 ) {
1250
1251				// Set Start Position
1252				if( self.options.startPos == 'none' ) {
1253					minus = '';
1254				} else if( self.options.startPos == 'top' ) {
1255					$el.css({
1256						top: 0
1257					});
1258					minus = '';
1259				} else {
1260					$el.css({
1261						bottom: 0
1262					});
1263					minus = '-';
1264				}
1265
1266				// Set Transition
1267				if( self.options.transition ) {
1268					$el.css({
1269						transition: 'ease-out transform '+ self.options.transitionDuration +'ms ' + self.options.transitionDelay + 'ms'
1270					});
1271				}
1272
1273				// First Load
1274				self.movement(minus);	
1275
1276				// Scroll
1277				$window.on('scroll', function(){
1278					self.movement(minus);				   
1279				});
1280
1281			}
1282
1283			return this;
1284		},
1285
1286		movement: function(minus) {
1287			var self = this,
1288				$el = this.options.wrapper,
1289				$window = $(window),
1290				scrollTop = $window.scrollTop(),
1291		    	elementOffset = $el.offset().top,
1292		     	currentElementOffset = (elementOffset - scrollTop),
1293		     	factor = ( self.options.isInsideSVG ) ? 2 : 100;
1294
1295		   	var scrollPercent = factor * currentElementOffset / ($window.height());
1296
1297		   	if( $el.visible( true ) ) {
1298
1299		   		if( !self.options.horizontal ) {
1300
1301		   			$el.css({
1302			   			transform: 'translate3d(0, '+ minus + scrollPercent / self.options.speed +'%, 0)'
1303			   		});
1304
1305		   		} else {
1306
1307		   			$el.css({
1308			   			transform: 'translate3d('+ minus + scrollPercent / self.options.speed +'%, '+ minus + scrollPercent / self.options.speed +'%, 0)'
1309			   		});
1310
1311		   		}
1312		   		
1313		   	}
1314
1315		}
1316	};
1317
1318	// expose to scope
1319	$.extend(theme, {
1320		PluginFloatElement: PluginFloatElement
1321	});
1322
1323	// jquery plugin
1324	$.fn.themePluginFloatElement = function(opts) {
1325		return this.map(function() {
1326			var $this = $(this);
1327
1328			if ($this.data(instanceName)) {
1329				return $this.data(instanceName);
1330			} else {
1331				return new PluginFloatElement($this, opts);
1332			}
1333
1334		});
1335	}
1336
1337}).apply(this, [window.theme, jQuery]);
1338
1339// Icon
1340(function(theme, $) {
1341
1342	'use strict';
1343
1344	theme = theme || {};
1345
1346	var instanceName = '__icon';
1347
1348	var PluginIcon = function($el, opts) {
1349		return this.initialize($el, opts);
1350	};
1351
1352	PluginIcon.defaults = {
1353		color: '#2388ED',
1354		animated: false,
1355		delay: 300,
1356		onlySVG: false
1357	};
1358
1359	PluginIcon.prototype = {
1360		initialize: function($el, opts) {
1361			if ($el.data(instanceName)) {
1362				return this;
1363			}
1364
1365			this.$el = $el;
1366
1367			this
1368				.setData()
1369				.setOptions(opts)
1370				.build();
1371
1372			return this;
1373		},
1374
1375		setData: function() {
1376			this.$el.data(instanceName, this);
1377
1378			return this;
1379		},
1380
1381		setOptions: function(opts) {
1382			this.options = $.extend(true, {}, PluginIcon.defaults, opts, {
1383				wrapper: this.$el
1384			});
1385
1386			return this;
1387		},
1388
1389		build: function() {
1390			var self  	 = this,
1391				$el   	 = this.options.wrapper,
1392				color 	 = self.options.color,
1393				elTopDistance = $el.offset().top,
1394				windowTopDistance = $(window).scrollTop(),
1395				duration = ( self.options.animated && !self.options.strokeBased ) ? 200 : 100;
1396
1397			// Check origin
1398			if( window.location.origin === 'file://' ) {
1399				$el.css('opacity', 1);
1400				return;
1401			}
1402
1403			// Duration
1404			if( self.options.duration ) {
1405				duration = self.options.duration;
1406			}
1407
1408			// SVG Content
1409			var SVGContent = $.get({
1410				url: $el.attr('src'), 
1411				success: function(data, status, xhr){
1412					var iconWrapper = $('<div class="animated-icon animated fadeIn">'+ xhr.responseText +'</div>'),
1413						uniqid = 'icon_' + Math.floor(Math.random() * 26) + Date.now();
1414
1415					iconWrapper.find('svg').attr('id', uniqid);
1416
1417					if( $el.attr('width') ) {
1418						iconWrapper.find('svg')
1419							.attr('width', $el.attr('width'))
1420							.attr('height', $el.attr('width'));						
1421					}
1422
1423					$el.replaceWith(iconWrapper);
1424
1425					if( self.options.extraClass ) {
1426						iconWrapper.addClass( self.options.extraClass );
1427					}
1428
1429					if( self.options.onlySVG ) {
1430						$(window).trigger('icon.rendered');
1431						return this;
1432					}
1433
1434					$el = iconWrapper;
1435
1436					var icon = new Vivus(uniqid, {start: 'manual', type: 'sync', selfDestroy: true, duration: duration, onReady: function(obj){
1437						var styleElement = document.createElementNS("http://www.w3.org/2000/svg", "style"),
1438							animateStyle = '';
1439
1440						// SVG Fill Based
1441						if( self.options.animated && !self.options.strokeBased || !self.options.animated && color && !self.options.strokeBased ) {
1442							animateStyle = 'stroke-width: 0.1px; fill-opacity: 0; transition: ease fill-opacity 300ms;';
1443							
1444							// Set Style on SVG inside object
1445							styleElement.textContent = '#' + uniqid + ' path, #' + uniqid + ' line, #' + uniqid + ' rect, #' + uniqid + ' circle, #' + uniqid + ' polyline { fill: '+ color +'; stroke: '+ color +'; '+ animateStyle + (self.options.svgStyle ? self.options.svgStyle : "") + ' } .finished path { fill-opacity: 1; }';
1446							obj.el.appendChild(styleElement);
1447						}
1448
1449						// SVG Stroke Based
1450						if( self.options.animated && self.options.strokeBased || !self.options.animated && color && self.options.strokeBased ) {
1451
1452							// Set Style on SVG inside object
1453							styleElement.textContent = '#' + uniqid + ' path, #' + uniqid + ' line, #' + uniqid + ' rect, #' + uniqid + ' circle, #' + uniqid + ' polyline { stroke: '+ color +'; ' + (self.options.svgStyle ? self.options.svgStyle : "") + '}';
1454							obj.el.appendChild(styleElement);
1455						}
1456
1457						$.event.trigger('theme.plugin.icon.svg.ready');
1458					}});
1459
1460					// Isn't animated
1461					if( !self.options.animated ) {
1462						setTimeout(function(){
1463							icon.finish();
1464						}, 10);
1465						$el.css({ opacity: 1 });
1466					}
1467
1468					// Animated
1469					if( self.options.animated && $(window).width() > 767 ) {
1470						// First Load
1471						if( $el.visible( true ) ) {
1472							self.startIconAnimation( icon, $el );
1473						} else if( elTopDistance < windowTopDistance ) {
1474							self.startIconAnimation( icon, $el );
1475						}
1476
1477						// On Scroll
1478						$(window).on('scroll', function(){
1479							if( $el.visible( true ) ) {
1480								self.startIconAnimation( icon, $el );
1481							}
1482						});
1483
1484					} else {
1485						
1486						$el.css({ opacity: 1 });
1487						icon.finish();
1488						
1489						$(window).on('theme.plugin.icon.svg.ready', function(){
1490							setTimeout(function(){
1491								icon.el.setAttribute('class', 'finished');
1492								icon.finish();
1493							}, 300);
1494						});
1495						
1496					}
1497
1498					$(window).trigger('icon.rendered');
1499				}
1500			});
1501
1502			return this;
1503		},
1504		startIconAnimation: function(icon, $el) {
1505			var self = this;
1506
1507			// Animate for better performance
1508			$({to:0}).animate({to:1}, ((self.options.strokeBased) ? self.options.delay : self.options.delay + 300 ), function() {
1509				$el.css({ opacity: 1 });
1510			});
1511
1512			$({to:0}).animate({to:1}, self.options.delay, function() {
1513				icon.play(1);
1514
1515				setTimeout(function(){
1516					icon.el.setAttribute('class', 'finished');
1517				}, icon.duration * 5 );
1518			});
1519		}
1520	};
1521
1522	// expose to scope
1523	$.extend(theme, {
1524		PluginIcon: PluginIcon
1525	});
1526
1527	// jquery plugin
1528	$.fn.themePluginIcon = function(opts) {
1529		return this.map(function() {
1530			var $this = $(this);
1531
1532			if ($this.data(instanceName)) {
1533				return $this.data(instanceName);
1534			} else {
1535				return new PluginIcon($this, opts);
1536			}
1537
1538		});
1539	};
1540
1541}).apply(this, [window.theme, jQuery]);
1542
1543// Lazy Load
1544(function(theme, $) {
1545
1546	theme = theme || {};
1547
1548	var instanceName = '__lazyload';
1549
1550	var PluginLazyLoad = function($el, opts) {
1551		return this.initialize($el, opts);
1552	};
1553
1554	PluginLazyLoad.defaults = {
1555		effect: 'show',
1556		appearEffect: '',
1557		imgFluid: true,
1558		appear: function(elements_left, settings) {
1559			
1560		},
1561		load: function(elements_left, settings) {
1562			$(this).addClass($.trim('lazy-load-loaded ' + settings.appearEffect)).css({
1563				'animation-duration': '1s'
1564			});
1565		}
1566	};
1567
1568	PluginLazyLoad.prototype = {
1569		initialize: function($el, opts) {
1570			if ($el.data(instanceName)) {
1571				return this;
1572			}
1573
1574			this.$el = $el;
1575
1576			this
1577				.setData()
1578				.setOptions(opts)
1579				.build()
1580				.events();
1581
1582			return this;
1583		},
1584
1585		setData: function() {
1586			this.$el.data(instanceName, this);
1587
1588			return this;
1589		},
1590
1591		setOptions: function(opts) {
1592			this.options = $.extend(true, {}, PluginLazyLoad.defaults, opts, {
1593				wrapper: this.$el
1594			});
1595
1596			return this;
1597		},
1598
1599		build: function() {
1600			if (!($.isFunction($.fn.lazyload))) {
1601				return this;
1602			}
1603
1604			var self = this;
1605
1606			// Add height on images based on <img> height attribute. This prevent some issues like isotope position, etc...
1607			if( self.options.wrapper.attr('height') ) {
1608				self.options.wrapper.height( self.options.wrapper.attr('height') );
1609			}
1610
1611			self.options.wrapper.lazyload(this.options);
1612
1613			return this;
1614		},
1615
1616		events: function() {
1617			var self = this;
1618
1619			if( self.options.imgFluid && self.options.wrapper.is('img') ) {
1620				self.options.wrapper.on('appear', function(){
1621					setTimeout(function(){
1622						self.options.wrapper.addClass('img-fluid');
1623
1624						setTimeout(function(){
1625							self.options.wrapper.css('height', '');
1626
1627							if( self.options.wrapper.closest('.isotope-item') ) {
1628								self.options.wrapper.closest('.isotope-item').closest('.sort-destination').isotope('layout');
1629							}
1630						}, 700);
1631
1632					}, 500);
1633				});
1634			}
1635
1636			return this;
1637		}
1638	};
1639
1640	// expose to scope
1641	$.extend(theme, {
1642		PluginLazyLoad: PluginLazyLoad
1643	});
1644
1645	// jquery plugin
1646	$.fn.themePluginLazyLoad = function(opts) {
1647		return this.map(function() {
1648			var $this = $(this);
1649
1650			if ($this.data(instanceName)) {
1651				return $this.data(instanceName);
1652			} else {
1653				return new PluginLazyLoad($this, opts);
1654			}
1655
1656		});
1657	}
1658
1659}).apply(this, [window.theme, jQuery]);
1660
1661// Lightbox
1662(function(theme, $) {
1663
1664	theme = theme || {};
1665
1666	var instanceName = '__lightbox';
1667
1668	var PluginLightbox = function($el, opts) {
1669		return this.initialize($el, opts);
1670	};
1671
1672	PluginLightbox.defaults = {
1673		tClose: 'Close (Esc)', // Alt text on close button
1674		tLoading: 'Loading...', // Text that is displayed during loading. Can contain %curr% and %total% keys
1675		gallery: {
1676			tPrev: 'Previous (Left arrow key)', // Alt text on left arrow
1677			tNext: 'Next (Right arrow key)', // Alt text on right arrow
1678			tCounter: '%curr% of %total%' // Markup for "1 of 7" counter
1679		},
1680		image: {
1681			tError: '<a href="%url%">The image</a> could not be loaded.' // Error message when image could not be loaded
1682		},
1683		ajax: {
1684			tError: '<a href="%url%">The content</a> could not be loaded.' // Error message when ajax request failed
1685		},
1686		callbacks: {
1687			open: function() {
1688				$('html').addClass('lightbox-opened');
1689			},
1690			close: function() {
1691				$('html').removeClass('lightbox-opened');
1692			}
1693		}
1694	};
1695
1696	PluginLightbox.prototype = {
1697		initialize: function($el, opts) {
1698			if ($el.data(instanceName)) {
1699				return this;
1700			}
1701
1702			this.$el = $el;
1703
1704			this
1705				.setData()
1706				.setOptions(opts)
1707				.build();
1708
1709			return this;
1710		},
1711
1712		setData: function() {
1713			this.$el.data(instanceName, this);
1714
1715			return this;
1716		},
1717
1718		setOptions: function(opts) {
1719			this.options = $.extend(true, {}, PluginLightbox.defaults, opts, {
1720				wrapper: this.$el
1721			});
1722
1723			return this;
1724		},
1725
1726		build: function() {
1727			if (!($.isFunction($.fn.magnificPopup))) {
1728				return this;
1729			}
1730
1731			this.options.wrapper.magnificPopup(this.options);
1732
1733			return this;
1734		}
1735	};
1736
1737	// expose to scope
1738	$.extend(theme, {
1739		PluginLightbox: PluginLightbox
1740	});
1741
1742	// jquery plugin
1743	$.fn.themePluginLightbox = function(opts) {
1744		return this.map(function() {
1745			var $this = $(this);
1746
1747			if ($this.data(instanceName)) {
1748				return $this.data(instanceName);
1749			} else {
1750				return new PluginLightbox($this, opts);
1751			}
1752
1753		});
1754	}
1755
1756}).apply(this, [window.theme, jQuery]);
1757
1758// Loading Overlay
1759(function(theme, $) {
1760
1761	'use strict';
1762
1763	theme = theme || {};
1764
1765	var loadingOverlayTemplate = [
1766		'<div class="loading-overlay">',
1767			'<div class="bounce-loader"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>',
1768		'</div>'
1769	].join('');
1770
1771	var LoadingOverlay = function( $wrapper, options ) {
1772		return this.initialize( $wrapper, options );
1773	};
1774
1775	LoadingOverlay.prototype = {
1776
1777		options: {
1778			css: {},
1779			hideDelay: 500
1780		},
1781
1782		initialize: function( $wrapper, options ) {
1783			this.$wrapper = $wrapper;
1784
1785			this
1786				.setVars()
1787				.setOptions( options )
1788				.build()
1789				.events();
1790
1791			this.$wrapper.data( 'loadingOverlay', this );
1792		},
1793
1794		setVars: function() {
1795			this.$overlay = this.$wrapper.find('.loading-overlay');
1796
1797			return this;
1798		},
1799
1800		setOptions: function( options ) {
1801			if ( !this.$overlay.get(0) ) {
1802				this.matchProperties();
1803			}
1804			this.options     = $.extend( true, {}, this.options, options, theme.fn.getOptions(this.$wrapper.data('plugin-options')) );
1805
1806			this.loaderClass = this.getLoaderClass( this.options.css.backgroundColor );
1807
1808			return this;
1809		},
1810
1811		build: function() {
1812			if ( !this.$overlay.closest(document.documentElement).get(0) ) {
1813				if ( !this.$cachedOverlay ) {
1814					this.$overlay = $( loadingOverlayTemplate ).clone();
1815
1816					if ( this.options.css ) {
1817						this.$overlay.css( this.options.css );
1818						this.$overlay.find( '.loader' ).addClass( this.loaderClass );
1819					}
1820				} else {
1821					this.$overlay = this.$cachedOverlay.clone();
1822				}
1823
1824				this.$wrapper.append( this.$overlay );
1825			}
1826
1827			if ( !this.$cachedOverlay ) {
1828				this.$cachedOverlay = this.$overlay.clone();
1829			}
1830
1831			return this;
1832		},
1833
1834		events: function() {
1835			var _self = this;
1836
1837			if ( this.options.startShowing ) {
1838				_self.show();
1839			}
1840
1841			if ( this.$wrapper.is('body') || this.options.hideOnWindowLoad ) {
1842				$( window ).on( 'load error', function() {
1843					_self.hide();
1844				});
1845			}
1846
1847			if ( this.options.listenOn ) {
1848				$( this.options.listenOn )
1849					.on( 'loading-overlay:show beforeSend.ic', function( e ) {
1850						e.stopPropagation();
1851						_self.show();
1852					})
1853					.on( 'loading-overlay:hide complete.ic', function( e ) {
1854						e.stopPropagation();
1855						_self.hide();
1856					});
1857			}
1858
1859			this.$wrapper
1860				.on( 'loading-overlay:show beforeSend.ic', function( e ) {
1861					if ( e.target === _self.$wrapper.get(0) ) {
1862						e.stopPropagation();
1863						_self.show();
1864						return true;
1865					}
1866					return false;
1867				})
1868				.on( 'loading-overlay:hide complete.ic', function( e ) {
1869					if ( e.target === _self.$wrapper.get(0) ) {
1870						e.stopPropagation();
1871						_self.hide();
1872						return true;
1873					}
1874					return false;
1875				});
1876
1877			return this;
1878		},
1879
1880		show: function() {
1881			this.build();
1882
1883			this.position = this.$wrapper.css( 'position' ).toLowerCase();
1884			if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
1885				this.$wrapper.css({
1886					position: 'relative'
1887				});
1888			}
1889			this.$wrapper.addClass( 'loading-overlay-showing' );
1890		},
1891
1892		hide: function() {
1893			var _self = this;
1894
1895			setTimeout(function() {
1896				_self.$wrapper.removeClass( 'loading-overlay-showing' );
1897				
1898				if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
1899					_self.$wrapper.css({ position: '' });
1900				}
1901
1902				$(window).trigger('loading.overlay.ready');
1903			}, _self.options.hideDelay);
1904		},
1905
1906		matchProperties: function() {
1907			var i,
1908				l,
1909				properties;
1910
1911			properties = [
1912				'backgroundColor',
1913				'borderRadius'
1914			];
1915
1916			l = properties.length;
1917
1918			for( i = 0; i < l; i++ ) {
1919				var obj = {};
1920				obj[ properties[ i ] ] = this.$wrapper.css( properties[ i ] );
1921
1922				$.extend( this.options.css, obj );
1923			}
1924		},
1925
1926		getLoaderClass: function( backgroundColor ) {
1927			if ( !backgroundColor || backgroundColor === 'transparent' || backgroundColor === 'inherit' ) {
1928				return 'black';
1929			}
1930
1931			var hexColor,
1932				r,
1933				g,
1934				b,
1935				yiq;
1936
1937			var colorToHex = function( color ){
1938				var hex,
1939					rgb;
1940
1941				if( color.indexOf('#') >- 1 ){
1942					hex = color.replace('#', '');
1943				} else {
1944					rgb = color.match(/\d+/g);
1945					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);
1946				}
1947
1948				if ( hex.length === 3 ) {
1949					hex = hex + hex;
1950				}
1951
1952				return hex;
1953			};
1954
1955			hexColor = colorToHex( backgroundColor );
1956
1957			r = parseInt( hexColor.substr( 0, 2), 16 );
1958			g = parseInt( hexColor.substr( 2, 2), 16 );
1959			b = parseInt( hexColor.substr( 4, 2), 16 );
1960			yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
1961
1962			return ( yiq >= 128 ) ? 'black' : 'white';
1963		}
1964
1965	};
1966
1967	// expose to scope
1968	$.extend(theme, {
1969		LoadingOverlay: LoadingOverlay
1970	});
1971
1972	// expose as a jquery plugin
1973	$.fn.loadingOverlay = function( opts ) {
1974		return this.each(function() {
1975			var $this = $( this );
1976
1977			var loadingOverlay = $this.data( 'loadingOverlay' );
1978			if ( loadingOverlay ) {
1979				return loadingOverlay;
1980			} else {
1981				var options = opts || $this.data( 'loading-overlay-options' ) || {};
1982				return new LoadingOverlay( $this, options );
1983			}
1984		});
1985	}
1986
1987	// auto init
1988	$('[data-loading-overlay]').loadingOverlay();
1989
1990}).apply(this, [window.theme, jQuery]);
1991
1992// Masonry
1993(function(theme, $) {
1994
1995	theme = theme || {};
1996
1997	var instanceName = '__masonry';
1998
1999	var PluginMasonry = function($el, opts) {
2000		return this.initialize($el, opts);
2001	};
2002
2003	PluginMasonry.defaults = {
2004
2005	};
2006
2007	PluginMasonry.prototype = {
2008		initialize: function($el, opts) {
2009			if ($el.data(instanceName)) {
2010				return this;
2011			}
2012
2013			this.$el = $el;
2014
2015			this
2016				.setData()
2017				.setOptions(opts)
2018				.build();
2019
2020			return this;
2021		},
2022
2023		setData: function() {
2024			this.$el.data(instanceName, this);
2025
2026			return this;
2027		},
2028
2029		setOptions: function(opts) {
2030			this.options = $.extend(true, {}, PluginMasonry.defaults, opts, {
2031				wrapper: this.$el
2032			});
2033
2034			return this;
2035		},
2036
2037		build: function() {
2038			if (!($.isFunction($.fn.isotope))) {
2039				return this;
2040			}
2041
2042			var self = this,
2043				$window = $(window);
2044
2045			self.$loader = false;
2046
2047			if (self.options.wrapper.parents('.masonry-loader').get(0)) {
2048				self.$loader = self.options.wrapper.parents('.masonry-loader');
2049				self.createLoader();
2050			}
2051
2052			self.options.wrapper.one('layoutComplete', function(event, laidOutItems) {
2053				self.removeLoader();
2054			});
2055
2056			self.options.wrapper.waitForImages(function() {
2057				self.options.wrapper.isotope(self.options);	
2058			});
2059
2060			// IE10/11 fix
2061			if( $('html').hasClass('ie10') || $('html').hasClass('ie11') ) {
2062				var padding = parseInt( self.options.wrapper.children().css('padding-left') ) + parseInt( self.options.wrapper.children().css('padding-right') );
2063			}
2064
2065			$(window).on('resize', function() {
2066				setTimeout(function() {
2067					self.options.wrapper.isotope('layout');
2068				}, 300);
2069			});
2070
2071			setTimeout(function() {
2072				self.removeLoader();
2073			}, 3000);
2074
2075			return this;
2076		},
2077
2078		createLoader: function() {
2079			var self = this;
2080
2081			var loaderTemplate = [
2082				'<div class="bounce-loader">',
2083					'<div class="bounce1"></div>',
2084					'<div class="bounce2"></div>',
2085					'<div class="bounce3"></div>',
2086				'</div>'
2087			].join('');
2088
2089			self.$loader.append(loaderTemplate);
2090
2091			return this;
2092		},
2093
2094		removeLoader: function() {
2095
2096			var self = this;
2097
2098			if (self.$loader) {
2099
2100				self.$loader.removeClass('masonry-loader-showing');
2101
2102				setTimeout(function() {
2103					self.$loader.addClass('masonry-loader-loaded');
2104				}, 300);
2105
2106			}
2107
2108		}
2109	};
2110
2111	// expose to scope
2112	$.extend(theme, {
2113		PluginMasonry: PluginMasonry
2114	});
2115
2116	// jquery plugin
2117	$.fn.themePluginMasonry = function(opts) {
2118		return this.map(function() {
2119			var $this = $(this);
2120
2121			if ($this.data(instanceName)) {
2122				return $this.data(instanceName);
2123			} else {
2124				return new PluginMasonry($this, opts);
2125			}
2126
2127		});
2128	}
2129
2130}).apply(this, [window.theme, jQuery]);
2131
2132// Match Height
2133(function(theme, $) {
2134
2135	theme = theme || {};
2136
2137	var instanceName = '__matchHeight';
2138
2139	var PluginMatchHeight = function($el, opts) {
2140		return this.initialize($el, opts);
2141	};
2142
2143	PluginMatchHeight.defaults = {
2144		byRow: true,
2145		property: 'height',
2146		target: null,
2147		remove: false
2148	};
2149
2150	PluginMatchHeight.prototype = {
2151		initialize: function($el, opts) {
2152			if ($el.data(instanceName)) {
2153				return this;
2154			}
2155
2156			this.$el = $el;
2157
2158			this
2159				.setData()
2160				.setOptions(opts)
2161				.build();
2162
2163			return this;
2164		},
2165
2166		setData: function() {
2167			this.$el.data(instanceName, this);
2168
2169			return this;
2170		},
2171
2172		setOptions: function(opts) {
2173			this.options = $.extend(true, {}, PluginMatchHeight.defaults, opts, {
2174				wrapper: this.$el
2175			});
2176
2177			return this;
2178		},
2179
2180		build: function() {
2181			if (!($.isFunction($.fn.matchHeight))) {
2182				return this;
2183			}
2184
2185			var self = this;
2186
2187			self.options.wrapper.matchHeight(self.options);
2188
2189			return this;
2190		}
2191
2192	};
2193
2194	// expose to scope
2195	$.extend(theme, {
2196		PluginMatchHeight: PluginMatchHeight
2197	});
2198
2199	// jquery plugin
2200	$.fn.themePluginMatchHeight = 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 PluginMatchHeight($this, opts);
2208			}
2209
2210		});
2211	}
2212
2213}).apply(this, [window.theme, jQuery]);
2214
2215// Parallax
2216(function(theme, $) {
2217
2218	theme = theme || {};
2219
2220	var instanceName = '__parallax';
2221
2222	var PluginParallax = function($el, opts) {
2223		return this.initialize($el, opts);
2224	};
2225
2226	PluginParallax.defaults = {
2227		speed: 1.5,
2228		horizontalPosition: '50%',
2229		offset: 0,
2230		parallaxDirection: 'top',
2231		parallaxHeight: '180%',
2232		scrollableParallax: false,
2233		scrollableParallaxMinWidth: 991,
2234		startOffset: 7,
2235		transitionDuration: '200ms',
2236		cssProperty: 'width',
2237		cssValueStart: 40,
2238		cssValueEnd: 100,
2239		cssValueUnit: 'vw'
2240	};
2241
2242	PluginParallax.prototype = {
2243		initialize: function($el, opts) {
2244			if ($el.data(instanceName)) {
2245				return this;
2246			}
2247
2248			this.$el = $el;
2249
2250			this
2251				.setData()
2252				.setOptions(opts)
2253				.build();
2254
2255			return this;
2256		},
2257
2258		setData: function() {
2259			this.$el.data(instanceName, this);
2260
2261			return this;
2262		},
2263
2264		setOptions: function(opts) {
2265			this.options = $.extend(true, {}, PluginParallax.defaults, opts, {
2266				wrapper: this.$el
2267			});
2268
2269			return this;
2270		},
2271
2272		build: function() {
2273			var self = this,
2274				$window = $(window),
2275				offset,
2276				yPos,
2277				bgpos,
2278				background,
2279				rotateY;
2280
2281			// Scrollable
2282			if( self.options.scrollableParallax && $(window).width() > self.options.scrollableParallaxMinWidth ) {
2283				var $scrollableWrapper = self.options.wrapper.find('.scrollable-parallax-wrapper');
2284
2285				if( $scrollableWrapper.get(0) ) {
2286
2287					var progress 	 = ( $(window).scrollTop() > ( self.options.wrapper.offset().top + $(window).outerHeight() ) ) ? self.options.cssValueEnd : self.options.cssValueStart,
2288						cssValueUnit = self.options.cssValueUnit ? self.options.cssValueUnit : '';
2289
2290					$scrollableWrapper.css({
2291						'background-image' : 'url(' + self.options.wrapper.data('image-src') + ')',
2292						'background-size' : 'cover',
2293						'background-position' : 'center',
2294						'background-attachment' : 'fixed',
2295						'transition' : 'ease '+ self.options.cssProperty +' '+ self.options.transitionDuration,
2296						'width' : progress + '%'
2297					});
2298
2299					$(window).on('scroll', function(e){
2300						if( self.options.wrapper.visible( true ) ) {
2301							var $window = $(window),
2302								scrollTop = $window.scrollTop(),
2303						    	elementOffset = self.options.wrapper.offset().top,
2304						     	currentElementOffset = (elementOffset - scrollTop);
2305
2306						   	var scrollPercent = Math.abs( +( currentElementOffset - $window.height() ) / (self.options.startOffset ? self.options.startOffset : 7) );
2307						 	
2308						 	// Increment progress value according scroll position
2309						 	if( scrollPercent <= self.options.cssValueEnd && progress <= self.options.cssValueEnd ) {
2310						 		progress = self.options.cssValueStart + scrollPercent;
2311						 	}
2312
2313						 	// Adjust CSS end value
2314						 	if( progress > self.options.cssValueEnd ) {
2315						 		progress = self.options.cssValueEnd;
2316						 	}
2317
2318						 	// Adjust CSS start value
2319						 	if( progress < self.options.cssValueStart ) {
2320						 		progress = self.options.cssValueStart;
2321						 	}
2322
2323						 	var styles = {}
2324						 	styles[self.options.cssProperty] = progress + cssValueUnit;
2325
2326							$scrollableWrapper.css(styles);
2327						}
2328					});
2329
2330				}
2331
2332				return;
2333			}
2334
2335			// Create Parallax Element
2336			if( self.options.fadeIn ) {
2337				background = $('<div class="parallax-background fadeIn animated"></div>');
2338			} else {
2339				background = $('<div class="parallax-background"></div>');
2340			}
2341
2342			// Set Style for Parallax Element
2343			background.css({
2344				'background-image' : 'url(' + self.options.wrapper.data('image-src') + ')',
2345				'background-size' : 'cover',
2346				'position' : 'absolute',
2347				'top' : 0,
2348				'left' : 0,
2349				'width' : '100%',
2350				'height' : self.options.parallaxHeight
2351			});
2352
2353			// Add Parallax Element on DOM
2354			self.options.wrapper.prepend(background);
2355
2356			// Set Overlfow Hidden and Position Relative to Parallax Wrapper
2357			self.options.wrapper.css({
2358				'position' : 'relative',
2359				'overflow' : 'hidden'
2360			});
2361
2362			// Parallax Effect on Scroll & Resize
2363			var parallaxEffectOnScrolResize = function() {
2364				$window.on('scroll resize', function() {
2365					offset  = self.options.wrapper.offset();
2366					yPos    = -($window.scrollTop() - (offset.top - 100)) / ((self.options.speed + 2 ));
2367					plxPos  = (yPos < 0) ? Math.abs(yPos) : -Math.abs(yPos);
2368					rotateY = ( $('html[dir="rtl"]').get(0) ) ? ' rotateY(180deg)' : ''; // RTL
2369
2370					if( self.options.parallaxDirection == 'bottom' ) {
2371						self.options.offset = 250;
2372					}
2373
2374					var y = ( (plxPos - 50) + (self.options.offset) );
2375					if( self.options.parallaxDirection == 'bottom' ) {
2376						y = ( y < 0 ) ? Math.abs( y ) : -Math.abs( y );
2377					}
2378
2379					background.css({
2380						'transform' : 'translate3d(0, '+ y +'px, 0)' + rotateY,
2381						'background-position-x' : self.options.horizontalPosition
2382					});
2383				});
2384
2385				$window.trigger('scroll');
2386			}
2387
2388			if (!$.browser.mobile) {
2389				parallaxEffectOnScrolResize();
2390			} else {
2391				if( self.options.enableOnMobile == true ) {
2392					parallaxEffectOnScrolResize();
2393				} else {
2394					self.options.wrapper.addClass('parallax-disabled');
2395				}
2396			}
2397
2398			return this;
2399		}
2400	};
2401
2402	// expose to scope
2403	$.extend(theme, {
2404		PluginParallax: PluginParallax
2405	});
2406
2407	// jquery plugin
2408	$.fn.themePluginParallax = 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 PluginParallax($this, opts);
2416			}
2417
2418		});
2419	}
2420
2421}).apply(this, [window.theme, jQuery]);
2422
2423// Progress Bar
2424(function(theme, $) {
2425
2426	theme = theme || {};
2427
2428	var instanceName = '__progressBar';
2429
2430	var PluginProgressBar = function($el, opts) {
2431		return this.initialize($el, opts);
2432	};
2433
2434	PluginProgressBar.defaults = {
2435		accX: 0,
2436		accY: -50,
2437		delay: 1
2438	};
2439
2440	PluginProgressBar.prototype = {
2441		initialize: function($el, opts) {
2442			if ($el.data(instanceName)) {
2443				return this;
2444			}
2445
2446			this.$el = $el;
2447
2448			this
2449				.setData()
2450				.setOptions(opts)
2451				.build();
2452
2453			return this;
2454		},
2455
2456		setData: function() {
2457			this.$el.data(instanceName, this);
2458
2459			return this;
2460		},
2461
2462		setOptions: function(opts) {
2463			this.options = $.extend(true, {}, PluginProgressBar.defaults, opts, {
2464				wrapper: this.$el
2465			});
2466
2467			return this;
2468		},
2469
2470		build: function() {
2471			if (!($.isFunction($.fn.appear))) {
2472				return this;
2473			}
2474
2475			var self = this,
2476				$el = this.options.wrapper,
2477				delay = 1;
2478
2479			$el.appear(function() {
2480
2481				delay = ($el.attr('data-appear-animation-delay') ? $el.attr('data-appear-animation-delay') : self.options.delay);
2482
2483				$el.addClass($el.attr('data-appear-animation'));
2484
2485				setTimeout(function() {
2486
2487					$el.animate({
2488						width: $el.attr('data-appear-progress-animation')
2489					}, 1500, 'easeOutQuad', function() {
2490						$el.find('.progress-bar-tooltip').animate({
2491							opacity: 1
2492						}, 500, 'easeOutQuad');
2493					});
2494
2495				}, delay);
2496
2497			}, {
2498				accX: self.options.accX,
2499				accY: self.options.accY
2500			});
2501
2502			return this;
2503		}
2504	};
2505
2506	// expose to scope
2507	$.extend(theme, {
2508		PluginProgressBar: PluginProgressBar
2509	});
2510
2511	// jquery plugin
2512	$.fn.themePluginProgressBar = function(opts) {
2513		return this.map(function() {
2514			var $this = $(this);
2515
2516			if ($this.data(instanceName)) {
2517				return $this.data(instanceName);
2518			} else {
2519				return new PluginProgressBar($this, opts);
2520			}
2521
2522		});
2523	}
2524
2525}).apply(this, [window.theme, jQuery]);
2526
2527// Read More
2528(function(theme, $) {
2529
2530	theme = theme || {};
2531
2532	var instanceName = '__readmore';
2533
2534	var PluginReadMore = function($el, opts) {
2535		return this.initialize($el, opts);
2536	};
2537
2538	PluginReadMore.defaults = {
2539		buttonOpenLabel: 'Read More <i class="fas fa-chevron-down text-2 ml-1"></i>',
2540		buttonCloseLabel: 'Read Less <i class="fas fa-chevron-up text-2 ml-1"></i>',
2541		enableToggle: true,
2542		maxHeight: 110,
2543		overlayColor: '#FFF',
2544		overlayHeight: 100,
2545		startOpened: false,
2546		align: 'left'
2547	};
2548
2549	PluginReadMore.prototype = {
2550		initialize: function($el, opts) {
2551			var self = this;
2552
2553			this.$el = $el;
2554
2555			this
2556				.setData()
2557				.setOptions(opts)
2558				.build()
2559				.events();
2560
2561			if( self.options.startOpened ) {
2562				self.options.wrapper.find('.readmore-button-wrapper > a').trigger('click');
2563			}
2564
2565			return this;
2566		},
2567
2568		setData: function() {
2569			this.$el.data(instanceName, this);
2570
2571			return this;
2572		},
2573
2574		setOptions: function(opts) {
2575			this.options = $.extend(true, {}, PluginReadMore.defaults, opts, {
2576				wrapper: this.$el
2577			});
2578
2579			return this;
2580		},
2581
2582		build: function() {
2583			var self = this;
2584
2585			self.options.wrapper.addClass('position-relative');
2586
2587			// Overlay
2588			self.options.wrapper.append( '<div class="readmore-overlay"></div>' );
2589
2590			self.options.wrapper.find('.readmore-overlay').css({
2591				background: 'linear-gradient(180deg, rgba(2, 0, 36, 0) 0%, '+ self.options.overlayColor +' 100%)',
2592				position: 'absolute',
2593				bottom: 0,
2594				left: 0,
2595				width: '100%',
2596				height: self.options.overlayHeight,
2597				'z-index': 1
2598			});
2599
2600			// Read More Button
2601			self.options.wrapper.find('.readmore-button-wrapper').removeClass('d-none').css({
2602				position: 'absolute',
2603				bottom: 0,
2604				left: 0,
2605				width: '100%',
2606				'z-index': 2
2607			});	
2608
2609			// Button Label
2610			self.options.wrapper.find('.readmore-button-wrapper > a').html( self.options.buttonOpenLabel );
2611
2612			self.options.wrapper.css({
2613				'height': self.options.maxHeight,
2614				'overflow-y': 'hidden'
2615			});
2616
2617			// Alignment
2618			switch ( self.options.align ) {
2619				case 'center':
2620					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-center');
2621					break;
2622
2623				case 'right':
2624					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-right');
2625					break;
2626
2627				case 'left':
2628				default:
2629					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-left');
2630					break;
2631			}
2632
2633			return this;
2634
2635		},
2636
2637		events: function() {
2638			var self = this;
2639
2640			// Read More
2641			self.readMore = function() {
2642				self.options.wrapper.find('.readmore-button-wrapper > a:not(.readless)').on('click', function(e){
2643					e.preventDefault();
2644
2645					var $this = $(this);
2646
2647					setTimeout(function(){
2648						self.options.wrapper.animate({
2649							'height': self.options.wrapper[0].scrollHeight
2650						}, function(){
2651							if( !self.options.enableToggle ) {
2652								$this.fadeOut();
2653							}
2654
2655							$this.html( self.options.buttonCloseLabel ).addClass('readless').off('click');
2656
2657							self.readLess();
2658
2659							self.options.wrapper.find('.readmore-overlay').fadeOut();
2660							self.options.wrapper.css({
2661								'max-height': 'none',
2662								'overflow': 'visible'
2663							});
2664
2665							self.options.wrapper.find('.readmore-button-wrapper').animate({
2666								bottom: -20
2667							});
2668						});
2669					}, 200);
2670				});
2671			}
2672
2673			// Read Less
2674			self.readLess = function() {
2675				self.options.wrapper.find('.readmore-button-wrapper > a.readless').on('click', function(e){
2676					e.preventDefault();
2677
2678					var $this = $(this);
2679
2680					// Button
2681					self.options.wrapper.find('.readmore-button-wrapper').animate({
2682						bottom: 0
2683					});
2684
2685					// Overlay
2686					self.options.wrapper.find('.readmore-overlay').fadeIn();
2687
2688					setTimeout(function(){
2689						self.options.wrapper.height(self.options.wrapper[0].scrollHeight).animate({
2690							'height': self.options.maxHeight
2691						}, function(){
2692							$this.html( self.options.buttonOpenLabel ).removeClass('readless').off('click');
2693
2694							self.readMore();
2695
2696							self.options.wrapper.css({
2697								'overflow': 'hidden'
2698							});
2699						});
2700					}, 200);
2701				});
2702			}
2703
2704			// First Load
2705			self.readMore();
2706
2707			return this;
2708		}
2709	};
2710
2711	// expose to scope
2712	$.extend(theme, {
2713		PluginReadMore: PluginReadMore
2714	});
2715
2716	// jquery plugin
2717	$.fn.themePluginReadMore = function(opts) {
2718		return this.map(function() {
2719			var $this = $(this);
2720
2721			if ($this.data(instanceName)) {
2722				return $this.data(instanceName);
2723			} else {
2724				return new PluginReadMore($this, opts);
2725			}
2726
2727		});
2728	}
2729
2730}).apply(this, [window.theme, jQuery]);
2731
2732// Revolution Slider
2733(function(theme, $) {
2734
2735	theme = theme || {};
2736
2737	var instanceName = '__revolution';
2738
2739	var PluginRevolutionSlider = function($el, opts) {
2740		return this.initialize($el, opts);
2741	};
2742
2743	PluginRevolutionSlider.defaults = {
2744		sliderType: 'standard',
2745		sliderLayout: 'fullwidth',
2746		delay: 9000,
2747		gridwidth: 1170,
2748		gridheight: 500,
2749		spinner: 'spinner3',
2750		disableProgressBar: 'on',
2751		parallax: {
2752			type: 'off',
2753			bgparallax: 'off'
2754		},
2755		navigation: {
2756			keyboardNavigation: 'off',
2757			keyboard_direction: 'horizontal',
2758			mouseScrollNavigation: 'off',
2759			onHoverStop: 'off',
2760			touch: {
2761				touchenabled: 'on',
2762				swipe_threshold: 75,
2763				swipe_min_touches: 1,
2764				swipe_direction: 'horizontal',
2765				drag_block_vertical: false
2766			},
2767			arrows: {
2768				enable: true,
2769				hide_onmobile: false,
2770				hide_under: 0,
2771				hide_onleave: true,
2772				hide_delay: 200,
2773				hide_delay_mobile: 1200,
2774				left: {
2775					h_align: 'left',
2776					v_align: 'center',
2777					h_offset: 30,
2778					v_offset: 0
2779				},
2780				right: {
2781					h_align: 'right',
2782					v_align: 'center',
2783					h_offset: 30,
2784					v_offset: 0
2785				}
2786			}
2787		},
2788
2789		/* ADDONS */
2790	    addOnTypewriter: {
2791			enable: false
2792		},
2793		addOnWhiteboard: {
2794			enable: false,
2795
2796		},
2797	    whiteboard: {
2798	        movehand: {
2799	            src: '../vendor/rs-plugin/revolution-addons/whiteboard/assets/images/hand_point_right.png',
2800	            width: 400,
2801	            height: 1000,
2802	            handtype: 'right',
2803	            transform: {
2804	                transformX: 50,
2805	                transformY: 50
2806	            },
2807	            jittering: {
2808	                distance: '80',
2809	                distance_horizontal: '100',
2810	                repeat: '5',
2811	                offset: '10',
2812	                offset_horizontal: '0'
2813	            },
2814	            rotation: {
2815	                angle: '10',
2816	                repeat: '3'
2817	            }
2818	        },
2819	        writehand: {
2820	            src: '../vendor/rs-plugin/revolution-addons/whiteboard/assets/images/write_right_angle.png',
2821	            width: 572,
2822	            height: 691,
2823	            handtype: 'right',
2824	            transform: {
2825	                transformX: 50,
2826	                transformY: 50
2827	            },
2828	            jittering: {
2829	                distance: '80',
2830	                distance_horizontal: '100',
2831	                repeat: '5',
2832	                offset: '10',
2833	                offset_horizontal: '0'
2834	            },
2835	            rotation:{
2836	                angle: '10',
2837	                repeat: '3'
2838	            }
2839	        }
2840	    },
2841	    addOnParticles: {
2842	    	enable: false
2843	    },
2844	    particles: {
2845			startSlide: "first", 
2846			endSlide: "last", 
2847			zIndex: "1",
2848			particles: {
2849				number: {value: 80}, color: {value: "#ffffff"},
2850				shape: {
2851					type: "circle", stroke: {width: 0, color: "#ffffff", opacity: 1},
2852					image: {src: ""}
2853				},
2854				opacity: {value: 0.5, random: true, min: 0.25, anim: {enable: false, speed: 3, opacity_min: 0, sync: false}},
2855				size: {value: 2, random: false, min: 30, anim: {enable: false, speed: 40, size_min: 1, sync: false}},
2856				line_linked: {enable: true, distance: 150, color: "#ffffff", opacity: 0.4, width: 1},
2857				move: {enable: true, speed: 6, direction: "none", random: true, min_speed: 6, straight: false, out_mode: "out"}
2858			},
2859			interactivity: {
2860				events: {onhover: {enable: false, mode: "repulse"}, onclick: {enable: false, mode: "repulse"}},
2861				modes: {grab: {distance: 400, line_linked: {opacity: 0.5}}, bubble: {distance: 400, size: 40, opacity: 0.4}, repulse: {distance: 200}}
2862			}
2863		},
2864		addOnCountdown: {
2865			enable: false,
2866			targetdate: new Date().getTime() + 864000000, // http://www.freeformatter.com/epoch-timestamp-to-date-converter.html
2867			slidechanges: [{days: 0, hours: 0, minutes: 0, seconds: 0, slide: 2}]
2868		},
2869		addOnSlicey: {
2870			enable: false
2871		},
2872		addOnFilmstrip: {
2873			enable: false
2874		},
2875		addOnBeforeAfter : {
2876			enable: false,
2877			options: {
2878				cursor: "move",
2879			    carousel: false,
2880			    arrowStyles: {
2881			        leftIcon: "fa-icon-caret-left",
2882			        rightIcon: "fa-icon-caret-right",
2883			        topIcon: "fa-icon-caret-up",
2884			        bottomIcon: "fa-icon-caret-down",
2885			        size: "35",
2886			        color: "#ffffff",
2887			        spacing: "10",
2888			        bgColor: "transparent",
2889			        padding: "0",
2890			        borderRadius: "0"
2891			    },
2892			    dividerStyles: {
2893			        width: "1",
2894			        color: "rgba(255, 255, 255, 0.5)"
2895			    }
2896			}
2897		},
2898		addOnPanorama: {
2899			enable: false
2900		},
2901		addOnRevealer: {
2902			enable: false,
2903		},
2904		revealer: {
2905			direction: "open_horizontal",
2906			color: "#ffffff",
2907			duration: "1500",
2908			delay: "0",
2909			easing: "Power2.easeInOut",
2910			overlay_enabled: true,
2911			overlay_color: "#000000",
2912			overlay_duration: "1500",
2913			overlay_delay: "0",
2914			overlay_easing: "Power2.easeInOut",
2915			spinner: "1",
2916			spinnerColor: "#006dd2",
2917			spinnerHtml: "<div class='rsaddon-revealer-spinner rsaddon-revealer-spinner-1'><div class='rsaddon-revealer-1'><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><\/div><\/div \/>"
2918		},
2919		addOnDuotone: {
2920			enable: false
2921		},
2922		addOnBubblemorph: {
2923			enable: false
2924		},
2925		addOnDistortion: {
2926			enable: false
2927		}
2928		
2929	};
2930
2931	PluginRevolutionSlider.prototype = {
2932		initialize: function($el, opts) {
2933			if ($el.data(instanceName)) {
2934				return this;
2935			}
2936
2937			this.$el = $el;
2938
2939			this
2940				.setData()
2941				.setOptions(opts)
2942				.build()
2943				.events();
2944
2945			return this;
2946		},
2947
2948		setData: function() {
2949			this.$el.data(instanceName, this);
2950
2951			return this;
2952		},
2953
2954		setOptions: function(opts) {
2955			this.options = $.extend(true, {}, PluginRevolutionSlider.defaults, opts, {
2956				wrapper: this.$el
2957			});
2958
2959			return this;
2960		},
2961
2962		build: function() {
2963			if (!($.isFunction($.fn.revolution))) {
2964				return this;
2965			}
2966
2967			// Single Slider Class
2968			if(this.options.wrapper.find('> ul > li').length == 1) {
2969				this.options.wrapper.addClass('slider-single-slide');
2970
2971				// Remove Bullets
2972				// this.options.navigation.bullets.enable = false;
2973				$.extend(this.options.navigation, {
2974					bullets: {
2975						enable: false
2976					}
2977				});
2978
2979			}
2980
2981			// Full Screen Class
2982			if(this.options.sliderLayout == 'fullscreen') {
2983				this.options.wrapper.closest('.slider-container').addClass('fullscreen-slider');
2984			}
2985			
2986			// Initialize Revolution Slider
2987			this.options.wrapper.revolution(this.options);
2988
2989			// Addon Init - Typewriter
2990			if(this.options.addOnTypewriter.enable) {
2991				RsTypewriterAddOn($, this.options.wrapper);
2992			}
2993
2994			// Addon Init - Whiteboard
2995			if(this.options.addOnWhiteboard.enable) {
2996				this.options.wrapper.rsWhiteBoard();
2997			}
2998
2999			// Addon Init - Particles
3000			if(this.options.addOnParticles.enable) {
3001				RsParticlesAddOn(this.options.wrapper);
3002			}
3003
3004			// Addon Init - Countdown
3005			if(this.options.addOnCountdown.enable) {
3006				tp_countdown(this.options.wrapper, this.options.addOnCountdown.targetdate, this.options.addOnCountdown.slidechanges);
3007			}
3008
3009			// Addon Init - Slicey
3010			if(this.options.addOnSlicey.enable) {
3011				this.options.wrapper.revSliderSlicey();
3012			}
3013
3014			// Addon Init - Filmstrip
3015			if(this.options.addOnFilmstrip.enable) {
3016				RsFilmstripAddOn($, this.options.wrapper, '../vendor/rs-plugin/revolution-addons/filmstrip/', false);
3017			}
3018
3019			// Addon Init - Before After
3020			if(this.options.addOnBeforeAfter.enable) {
3021				RevSliderBeforeAfter($, this.options.wrapper, this.options.addOnBeforeAfter.options);
3022			}
3023
3024			// Addon Init - Panorama
3025			if(this.options.addOnPanorama.enable) {
3026				RsAddonPanorama($, this.options.wrapper);
3027			}
3028
3029			// Addon Init - Revealer
3030			if(this.options.addOnRevealer.enable) {
3031				RsRevealerAddOn($, this.options.wrapper, this.options.revealer.spinnerHtml);
3032			}
3033
3034			// Addon Init - Duotone
3035			if(this.options.addOnDuotone.enable) {
3036				RsAddonDuotone($, this.options.wrapper, true, "cubic-bezier(0.645, 0.045, 0.355, 1.000)", "1000");
3037			}
3038
3039			// Addon Init - Bubblemorph
3040			if(this.options.addOnBubblemorph.enable) {
3041				BubbleMorphAddOn($, this.options.wrapper, false);
3042			}
3043
3044			// Addon Init - Distortion
3045			if(this.options.addOnDistortion.enable) {
3046				RsLiquideffectAddOn($, this.options.wrapper);
3047			}
3048
3049			return this;
3050		},
3051
3052		events: function() {
3053
3054			return this;
3055		}
3056	};
3057
3058	// expose to scope
3059	$.extend(theme, {
3060		PluginRevolutionSlider: PluginRevolutionSlider
3061	});
3062
3063	// jquery plugin
3064	$.fn.themePluginRevolutionSlider = function(opts) {
3065		return this.map(function() {
3066			var $this = $(this);
3067
3068			if ($this.data(instanceName)) {
3069				return $this.data(instanceName);
3070			} else {
3071				return new PluginRevolutionSlider($this, opts);
3072			}
3073
3074		});
3075	}
3076
3077}).apply(this, [window.theme, jQuery]);
3078
3079// Scroll to Top
3080(function(theme, $) {
3081
3082	theme = theme || {};
3083
3084	$.extend(theme, {
3085
3086		PluginScrollToTop: {
3087
3088			defaults: {
3089				wrapper: $('body'),
3090				offset: 150,
3091				buttonClass: 'scroll-to-top',
3092				iconClass: 'fas fa-chevron-up',
3093				delay: 1000,
3094				visibleMobile: false,
3095				label: false,
3096				easing: 'easeOutBack'
3097			},
3098
3099			initialize: function(opts) {
3100				initialized = true;
3101
3102				// Don't initialize if the page has Section Scroll
3103				if( $('body[data-plugin-section-scroll]').get(0) ) {
3104					return;
3105				}
3106
3107				this
3108					.setOptions(opts)
3109					.build()
3110					.events();
3111
3112				return this;
3113			},
3114
3115			setOptions: function(opts) {
3116				this.options = $.extend(true, {}, this.defaults, opts);
3117
3118				return this;
3119			},
3120
3121			build: function() {
3122				var self = this,
3123					$el;
3124
3125				// Base HTML Markup
3126				$el = $('<a />')
3127					.addClass(self.options.buttonClass)
3128					.attr({
3129						'href': '#',
3130					})
3131					.append(
3132						$('<i />')
3133						.addClass(self.options.iconClass)
3134				);
3135
3136				// Visible Mobile
3137				if (!self.options.visibleMobile) {
3138					$el.addClass('hidden-mobile');
3139				}
3140
3141				// Label
3142				if (self.options.label) {
3143					$el.append(
3144						$('<span />').html(self.options.label)
3145					);
3146				}
3147
3148				this.options.wrapper.append($el);
3149
3150				this.$el = $el;
3151
3152				return this;
3153			},
3154
3155			events: function() {
3156				var self = this,
3157					_isScrolling = false;
3158
3159				// Click Element Action
3160				self.$el.on('click', function(e) {
3161					e.preventDefault();
3162					$('body, html').animate({
3163						scrollTop: 0
3164					}, self.options.delay, self.options.easing);
3165					return false;
3166				});
3167
3168				// Show/Hide Button on Window Scroll event.
3169				$(window).scroll(function() {
3170
3171					if (!_isScrolling) {
3172
3173						_isScrolling = true;
3174
3175						if ($(window).scrollTop() > self.options.offset) {
3176
3177							self.$el.stop(true, true).addClass('visible');
3178							_isScrolling = false;
3179
3180						} else {
3181
3182							self.$el.stop(true, true).removeClass('visible');
3183							_isScrolling = false;
3184
3185						}
3186
3187					}
3188
3189				});
3190
3191				return this;
3192			}
3193
3194		}
3195
3196	});
3197
3198}).apply(this, [window.theme, jQuery]);
3199
3200// Scrollable
3201(function(theme, $) {
3202
3203	theme = theme || {};
3204
3205	var instanceName = '__scrollable';
3206
3207	var PluginScrollable = function($el, opts) {
3208		return this.initialize($el, opts);
3209	};
3210
3211	PluginScrollable.updateModals = function() {
3212		PluginScrollable.updateBootstrapModal();
3213	};
3214
3215	PluginScrollable.updateBootstrapModal = function() {
3216		var updateBoostrapModal;
3217
3218		updateBoostrapModal = typeof $.fn.modal !== 'undefined';
3219		updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor !== 'undefined';
3220		updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor.prototype !== 'undefined';
3221		updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor.prototype.enforceFocus !== 'undefined';
3222
3223		if ( !updateBoostrapModal ) {
3224			return false;
3225		}
3226
3227		var originalFocus = $.fn.modal.Constructor.prototype.enforceFocus;
3228		$.fn.modal.Constructor.prototype.enforceFocus = function() {
3229			originalFocus.apply( this );
3230
3231			var $scrollable = this.$element.find('.scrollable');
3232			if ( $scrollable ) {
3233				if ( $.isFunction($.fn['themePluginScrollable'])  ) {
3234					$scrollable.themePluginScrollable();
3235				}
3236
3237				if ( $.isFunction($.fn['nanoScroller']) ) {
3238					$scrollable.nanoScroller();
3239				}
3240			}
3241		};
3242	};
3243
3244	PluginScrollable.defaults = {
3245		contentClass: 'scrollable-content',
3246		paneClass: 'scrollable-pane',
3247		sliderClass: 'scrollable-slider',
3248		alwaysVisible: true,
3249		preventPageScrolling: true
3250	};
3251
3252	PluginScrollable.prototype = {
3253		initialize: function($el, opts) {
3254			if ( $el.data( instanceName ) ) {
3255				return this;
3256			}
3257
3258			this.$el = $el;
3259
3260			this
3261				.setData()
3262				.setOptions(opts)
3263				.build();
3264
3265			return this;
3266		},
3267
3268		setData: function() {
3269			this.$el.data(instanceName, this);
3270
3271			return this;
3272		},
3273
3274		setOptions: function(opts) {
3275			this.options = $.extend(true, {}, PluginScrollable.defaults, opts, {
3276				wrapper: this.$el
3277			});
3278
3279			return this;
3280		},
3281
3282		build: function() {
3283			this.options.wrapper.nanoScroller(this.options);
3284
3285			return this;
3286		}
3287	};
3288
3289	// expose to scope
3290	$.extend(theme, {
3291		PluginScrollable: PluginScrollable
3292	});
3293
3294	// jquery plugin
3295	$.fn.themePluginScrollable = function(opts) {
3296		return this.each(function() {
3297			var $this = $(this);
3298
3299			if ($this.data(instanceName)) {
3300				return $this.data(instanceName);
3301			} else {
3302				return new PluginScrollable($this, opts);
3303			}
3304
3305		});
3306	};
3307
3308	$(function() {
3309		PluginScrollable.updateModals();
3310	});
3311
3312}).apply(this, [window.theme, jQuery]);
3313
3314// Section Scroll
3315(function(theme, $) {
3316
3317	theme = theme || {};
3318
3319	var instanceName = '__sectionScroll';
3320
3321	var PluginSectionScroll = function($el, opts) {
3322		return this.initialize($el, opts);
3323	};
3324
3325	PluginSectionScroll.defaults = {
3326		targetClass: '.section',
3327		dotsNav: true,
3328		changeHeaderLogo: true,
3329		headerLogoDark: 'img/logo-default-slim.png',
3330		headerLogoLight: 'img/logo-default-slim-dark.png'
3331	};
3332
3333	PluginSectionScroll.prototype = {
3334		initialize: function($el, opts) {
3335			if ($el.data(instanceName)) {
3336				return this;
3337			}
3338
3339			this.$el = $el;
3340
3341			this
3342				.setData()
3343				.setOptions(opts)
3344				.build()
3345				.events();
3346
3347			return this;
3348		},
3349
3350		setData: function() {
3351			this.$el.data(instanceName, this);
3352
3353			return this;
3354		},
3355
3356		setOptions: function(opts) {
3357			this.options = $.extend(true, {}, PluginSectionScroll.defaults, opts, {
3358				wrapper: this.$el
3359			});
3360
3361			return this;
3362		},
3363
3364		build: function() {
3365			var self = this,
3366				$el = this.options.wrapper;
3367
3368			// Check type of header and change the target for header (by change header color purpose)
3369			if( $('html').hasClass('side-header-overlay-full-screen') ) {
3370				self.$header = $('.sticky-wrapper');
3371			} else {
3372				self.$header = $('#header');
3373			}
3374
3375			// Turn the section full height or not depeding on the content size
3376			self.updateSectionsHeight();
3377
3378			// Wrap all sections in a section wrapper
3379			$( this.options.targetClass ).wrap('<div class="section-wrapper"></div>');
3380
3381			// Set the section wrapper height
3382	  		$('.section-wrapper').each(function(){
3383	  			$(this).height( $(this).find('.section-scroll').outerHeight() );
3384	  		});
3385
3386	  		// Add active class to the first section on page load
3387	  		$('.section-wrapper').first().addClass('active');
3388			
3389	        var	flag = false,
3390	            scrollableFlag = false,
3391	        	touchDirection = '',
3392	        	touchstartY = 0,
3393	        	touchendY = 0;
3394
3395	        $(window).on('touchstart', function(event) {
3396			    touchstartY = event.changedTouches[0].screenY;
3397			});
3398
3399	        var wheelEvent = 'onwheel' in document ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll';
3400	        if( $(window).width() < 992 && $('html').hasClass('touch') ) {
3401	        	wheelEvent = 'onwheel' in document ? 'wheel touchend' : document.onmousewheel !== undefined ? 'mousewheel touchend' : 'DOMMouseScroll touchend';
3402	        }
3403
3404        	if( $(window).width() < 992 ) {
3405	    		$('html').removeClass('overflow-hidden');
3406			    $(window).on('scroll', function(){
3407
3408		    		var index = 0;
3409		    		$('.section-scroll').each(function(){
3410		    			if( $(this).offset().top <= $(window).scrollTop() + 50 ) {
3411		    				var $currentSection2 = $('.section-wrapper').eq( index ).find('.section-scroll');
3412
3413			            	$('.section-scroll-dots-navigation > ul > li').removeClass('active');
3414							$('.section-scroll-dots-navigation > ul > li').eq( index ).addClass('active');
3415
3416							$(window).trigger({
3417								type: 'section.scroll.mobile.change.header.color',
3418								currentSection: $currentSection2
3419							});
3420		    			}
3421
3422		    			index++;
3423		    		});
3424		    		
3425			    });
3426
3427			    $(window).on('section.scroll.mobile.change.header.color', function(e){
3428			    	if( typeof e.currentSection == 'undefined' ) {
3429			    		return;
3430			    	}
3431
3432			    	var $currentSection = e.currentSection,
3433			    		headerColor     = $currentSection.data('section-scroll-header-color');
3434								    	
3435			    	$('#header .header-nav').removeClass('header-nav-light-text header-nav-dark-text').addClass('header-nav-' + headerColor + '-text');
3436			    	$('#header .header-nav-features').removeClass('header-nav-features-dark header-nav-features-light').addClass('header-nav-features-' + headerColor);
3437			    	$('#header .header-social-icons').removeClass('social-icons-icon-dark social-icons-icon-light').addClass('social-icons-icon-' + headerColor);
3438
3439			    	// Change Logo
3440			    	if( self.options.changeHeaderLogo && headerColor != undefined ) {
3441				    	if( headerColor == 'light' ) {
3442				    		$('#header .header-logo img').attr('src', self.options.headerLogoLight);
3443				    	} else if( headerColor == 'dark' ) {
3444				    		$('#header .header-logo img').attr('src', self.options.headerLogoDark);
3445				    	}
3446			    	}
3447
3448			    	self.$header.css({
3449			    		opacity: 1
3450			    	});
3451
3452			    });
3453        	}
3454
3455	        $(window).on(wheelEvent, function(e){
3456	        	if( $(window).width() < 992 ) {
3457	        		return;
3458	        	}
3459
3460	        	if( $(window).width() < 992 && $('html').hasClass('touch') ) {
3461		        	if( $(e.target).closest('.section-scroll-dots-navigation').get(0) || $(e.target).closest('.header-body').get(0) || $(e.target).closest('.owl-carousel').get(0) ) {
3462		        		return;
3463		        	}
3464		        }
3465
3466		        // Side Header Overlay Full Screen
3467		        if( $('html.side-header-overlay-full-screen.side-header-hide').get(0) ) {
3468		        	return;
3469		        }
3470
3471	        	var wheelDirection = e.originalEvent.wheelDelta == undefined ? e.originalEvent.deltaY > 0 : e.originalEvent.wheelDelta < 0;
3472	        	if( $(window).width() < 992 && $('html').hasClass('touch') ) {
3473		        	touchendY = event.changedTouches[0].screenY;
3474	        		
3475				    if( touchendY <= touchstartY ) {
3476				    	touchDirection = 'up';
3477				    }
3478
3479				    if( touchendY >= touchstartY ) {
3480				    	touchDirection = 'down';
3481				    }
3482
3483				    if( touchendY == touchstartY ) {
3484				    	return;
3485				    }
3486	        	}
3487
3488	        	var $currentSection = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll'),
3489            		$nextSection = self.getNextSection(wheelDirection, touchDirection),
3490            		nextSectionOffsetTop;
3491
3492            	// If is the last section, then change the offsetTop value
3493            	if( self.getCurrentIndex() == $('.section-wrapper').length - 1 ) {
3494            		nextSectionOffsetTop = $(document).height();
3495            	} else {
3496            		nextSectionOffsetTop = $nextSection.offset().top;
3497            	}
3498
3499			    if( $(window).width() < 992 && $('html').hasClass('touch') ) {
3500				    setTimeout(function(){
3501					    if( $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').hasClass('section-scroll-scrollable') ) {
3502					    	$('html').removeClass('overflow-hidden');
3503					    } else {
3504					    	$('html').addClass('overflow-hidden');
3505					    }
3506				    }, 1200);
3507				}
3508
3509	        	// For non full height sections
3510	        	if( $currentSection.hasClass('section-scroll-scrollable') ) {
3511	        		if( !flag && !scrollableFlag ) {
3512
3513		        		// Scroll Direction
3514		        		if(wheelDirection || touchDirection == 'up') {
3515		        			if( ( $(window).scrollTop() + $(window).height() ) >= nextSectionOffsetTop ) {
3516		        				flag = true;
3517								setTimeout(function(){
3518									$(window).trigger('section.scroll.change.header.color');
3519
3520					            	setTimeout(function(){
3521										flag = false;
3522									}, 500);
3523								}, 1000);
3524
3525		        				if( self.getCurrentIndex() == ( $('.section-wrapper').length - 1 )  ) {
3526						    		return false;
3527						    	}
3528
3529		        				// Move to the next section
3530		        				self.moveTo( $currentSection.offset().top + $currentSection.outerHeight() );
3531
3532		        				// Change Section Active Class
3533					   			self.changeSectionActiveState( $nextSection );
3534
3535					   			self.$header.css({
3536							    	opacity: 0,
3537							    	transition: 'ease opacity 500ms'
3538							    });
3539					        }
3540
3541			        		if( !$('html').hasClass('touch') ) {
3542				        		for( var i = 1; i < 100; i++ ) {
3543					        		$('body, html').scrollTop( $(window).scrollTop() + 1 );
3544
3545					        		if( ( $(window).scrollTop() + $(window).height() ) >= nextSectionOffsetTop ) {
3546					        			scrollableFlag = true;
3547										setTimeout(function(){
3548											$(window).trigger('section.scroll.change.header.color');
3549							            	scrollableFlag = false;
3550										}, 500);
3551					        			break;
3552					        		}
3553				        		}
3554				        	}
3555					    } else {
3556					    	if( $(window).scrollTop() <= $currentSection.offset().top ) {
3557					    		flag = true;
3558								setTimeout(function(){
3559									$(window).trigger('section.scroll.change.header.color');
3560
3561					            	setTimeout(function(){
3562										flag = false;
3563									}, 500);
3564								}, 1000);
3565
3566					    		if( self.getCurrentIndex() == 0  ) {
3567						    		return false;
3568						    	}
3569
3570					   			// Move to the next section
3571		        				self.moveTo( $currentSection.offset().top - $(window).height() );
3572
3573		        				// Change Section Active Class
3574					   			self.changeSectionActiveState( $nextSection );
3575
3576					   			self.$header.css({
3577							    	opacity: 0,
3578							    	transition: 'ease opacity 500ms'
3579							    });
3580					        }
3581
3582					    	if( !$('html').hasClass('touch') ) {
3583				        		for( var i = 1; i < 100; i++ ) {
3584					        		$('body, html').scrollTop( $(window).scrollTop() - 1 );
3585
3586					        		if( $(window).scrollTop() <= $currentSection.offset().top ) {
3587					        			scrollableFlag = true;
3588										setTimeout(function(){
3589											$(window).trigger('section.scroll.change.header.color');
3590							            	scrollableFlag = false;
3591										}, 500);
3592					        			break;
3593					        		}
3594				        		}
3595				        	}
3596					    }
3597
3598			   			// Change Dots Active Class
3599				        self.changeDotsActiveState();
3600
3601		        		return;
3602
3603		        	}
3604	        	}
3605
3606	        	// For full height sections
3607	        	if( !flag && !scrollableFlag ) {
3608				    if(wheelDirection || touchDirection == 'up') {
3609				    	if( self.getCurrentIndex() == ( $('.section-wrapper').length - 1 )  ) {
3610				    		return false;
3611				    	}
3612
3613				   		// Change Section Active Class
3614			   			self.changeSectionActiveState( $nextSection );
3615
3616				   		setTimeout(function(){
3617				   			// Move to the next section
3618	        				self.moveTo( $nextSection.offset().top );
3619
3620				   		}, 150);
3621				    } else {
3622				    	if( self.getCurrentIndex() == 0  ) {
3623				    		return false;
3624				    	}
3625
3626				   		// Change Section Active Class
3627			   			self.changeSectionActiveState( $nextSection );
3628
3629				   		if( $nextSection.height() > $(window).height() ) {
3630				   			// Move to the next section
3631	        				self.moveTo( $currentSection.offset().top - $(window).height() );
3632				   		} else {
3633					        setTimeout(function(){
3634					   			// Move to the next section
3635		        				self.moveTo( $nextSection.offset().top );
3636
3637					   		}, 150);
3638				   		}
3639				    }
3640
3641				    // Change Dots Active Class
3642			        self.changeDotsActiveState();
3643
3644				    self.$header.css({
3645				    	opacity: 0,
3646				    	transition: 'ease opacity 500ms'
3647				    });
3648
3649				    // Style next section
3650	            	$nextSection.css({
3651	            		position: 'relative',
3652	            		opacity: 1,
3653	            		'z-index': 1,
3654	            		transform: 'translate3d(0,0,0) scale(1)'
3655	            	});
3656
3657	            	// Style previous section
3658	            	$currentSection.css({
3659	            		position: 'fixed',
3660	            		width: '100%',
3661	            		top: 0,
3662	            		left: 0,
3663	            		opacity: 0,
3664	            		'z-index': 0,
3665	            		transform: 'translate3d(0,0,-10px) scale(0.7)',
3666	            		transition: 'ease transform 600ms, ease opacity 600ms',
3667	            	});
3668
3669					setTimeout(function(){
3670						$currentSection.css({
3671		            		position: 'relative',
3672		            		opacity: 1,
3673		            		transform: 'translate3d(0,0,-10px) scale(1)'
3674		            	});
3675
3676						$(window).trigger('section.scroll.change.header.color');
3677
3678		            	setTimeout(function(){
3679							flag = false;
3680						}, 500);
3681					}, 1000);
3682
3683					flag = true;
3684
3685				}
3686
3687				return;
3688	        });
3689
3690	        // Dots Navigation
3691	        if( this.options.dotsNav ) {
3692	        	self.dotsNavigation();
3693	        }
3694
3695	        // First Load
3696	        setTimeout(function(){
3697		        if( $(window.location.hash).get(0) ) {
3698		        	self.moveTo( $(window.location.hash).parent().offset().top );
3699
3700		        	self.changeSectionActiveState( $(window.location.hash) );
3701
3702		        	// Change Dots Active Class
3703			        self.changeDotsActiveState();
3704
3705		        	self.updateHash( true );
3706		        } else {
3707		        	var hash  = window.location.hash,
3708		        		index = hash.replace('#','');
3709
3710		        	if( !hash ) {
3711		        		index = 1;
3712		        	}
3713
3714		        	self.moveTo( $('.section-wrapper').eq( index - 1 ).offset().top );
3715
3716		        	self.changeSectionActiveState( $('.section-wrapper').eq( index - 1 ).find('.section-scroll') );
3717
3718		        	// Change Dots Active Class
3719			        self.changeDotsActiveState();
3720
3721		        	self.updateHash( true );
3722		        }
3723
3724				$(window).trigger('section.scroll.ready');
3725				$(window).trigger('section.scroll.change.header.color');
3726			}, 500);
3727
3728			return this;
3729		},
3730
3731		updateSectionsHeight: function() {
3732			var self = this;
3733
3734			$('.section-scroll').css({ height: '' });
3735
3736			$('.section-scroll').each(function(){
3737				if( $(this).outerHeight() < ( $(window).height() + 3 ) ) {
3738					$(this).css({ height: '100vh' });		
3739				} else {
3740					$(this).addClass('section-scroll-scrollable');
3741				}
3742			});
3743
3744			// Set the section wrapper height
3745	  		$('.section-wrapper').each(function(){
3746	  			$(this).height( $(this).find('.section-scroll').outerHeight() );
3747	  		});
3748
3749			return this;
3750		},
3751
3752		updateHash: function( first_load ){
3753			var self = this;
3754
3755			if( !window.location.hash ) {
3756				window.location.hash = 1;
3757			} else {
3758				if(!first_load) {
3759					var $section = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll'),
3760						section_id = $section.attr('id') ? $section.attr('id') : $section.parent().index() + 1;
3761
3762					window.location.hash = section_id;
3763				}
3764			}
3765
3766			return this;
3767		},
3768
3769		getCurrentIndex: function() {
3770			var self = this,
3771				currentIndex = 0;
3772
3773			currentIndex = $('.section-wrapper.active').index();
3774
3775			return currentIndex;
3776		},
3777
3778		moveTo: function( $scrollTopValue, first_load ) {
3779			var self = this;
3780
3781			$('body, html').animate({
3782   				scrollTop: $scrollTopValue
3783   			}, 1000, 'easeOutQuint');
3784
3785   			setTimeout(function(){
3786	   			self.updateHash();
3787   			}, 500);
3788
3789			return this;
3790		},
3791
3792		getNextSection: function(wheelDirection, touchDirection) {
3793			var self = this,
3794				$nextSection = '';
3795
3796			// Scroll Direction
3797        	if(wheelDirection || touchDirection == 'up') {
3798				$nextSection = $('.section-wrapper').eq( self.getCurrentIndex() + 1 ).find('.section-scroll');
3799        	} else {
3800        		$nextSection = $('.section-wrapper').eq( self.getCurrentIndex() - 1 ).find('.section-scroll');
3801        	}
3802
3803			return $nextSection;
3804		},
3805
3806		changeSectionActiveState: function( $nextSection ) {
3807			var self = this;
3808
3809			$('.section-wrapper').removeClass('active');
3810	   		$nextSection.parent().addClass('active');
3811
3812			return this;
3813		},
3814
3815		changeDotsActiveState: function() {
3816			var self = this;
3817
3818			$('.section-scroll-dots-navigation > ul > li').removeClass('active');
3819			$('.section-scroll-dots-navigation > ul > li').eq( self.getCurrentIndex() ).addClass('active');
3820
3821			return this;
3822		},
3823
3824		dotsNavigation: function() {
3825			var self = this;
3826
3827			var dotsNav = $('<div class="section-scroll-dots-navigation"><ul class="list list-unstyled"></ul></div>'),
3828        		currentSectionIndex = self.getCurrentIndex();
3829
3830        	if( self.options.dotsClass ) {
3831        		dotsNav.addClass( self.options.dotsClass );
3832        	}
3833
3834        	for( var i = 0; i < $('.section-scroll').length; i++ ) {
3835        		var title = $('.section-wrapper').eq( i ).find('.section-scroll').data('section-scroll-title');
3836
3837        		dotsNav.find('> ul').append( '<li'+ ( ( currentSectionIndex == i ) ? ' class="active"' : '' ) +'><a href="#'+ i +'" data-nav-id="'+ i +'"><span>'+ title +'</span></a></li>' );
3838        	}
3839
3840        	$('.body').append( dotsNav );
3841
3842        	dotsNav.find('a[data-nav-id]').on('click touchstart', function(e){
3843        		e.preventDefault();
3844        		var $this = $(this);
3845
3846        		$('.section-scroll').css({
3847        			opacity: 0,
3848        			transition: 'ease opacity 300ms'
3849        		});
3850
3851        		self.$header.css({
3852			    	opacity: 0,
3853			    	transition: 'ease opacity 500ms'
3854			    });
3855
3856        		setTimeout(function(){
3857	        		self.moveTo( $('.section-wrapper').eq( $this.data('nav-id') ).offset().top )
3858
3859		   			$('.section-wrapper').removeClass('active');
3860			   		$('.section-wrapper').eq( $this.data('nav-id') ).addClass('active');
3861
3862	        		$('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').css({
3863	        			opacity: 1
3864	        		});
3865
3866	        		setTimeout(function(){
3867		        		$('.section-scroll').css({ opacity: 1 });
3868
3869		        		$(window).trigger('section.scroll.change.header.color');
3870	        		}, 500);
3871
3872	        		if( $(window).width() > 991 ) {
3873		        		self.changeDotsActiveState();
3874	        		}
3875        		}, 500);
3876        	});
3877
3878			return this;
3879		},
3880
3881		events: function() {
3882			var self = this;
3883
3884			$(window).on('section.scroll.ready', function(){
3885				$(window).scrollTop(0);
3886			});
3887
3888			$(window).on('section.scroll.change.header.color', function(){
3889		    	var headerColor = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').data('section-scroll-header-color');
3890		    	
3891		    	$('#header .header-nav').removeClass('header-nav-light-text header-nav-dark-text').addClass('header-nav-' + headerColor + '-text');
3892		    	$('#header .header-nav-features').removeClass('header-nav-features-dark header-nav-features-light').addClass('header-nav-features-' + headerColor);
3893		    	$('#header .header-social-icons').removeClass('social-icons-icon-dark social-icons-icon-light').addClass('social-icons-icon-' + headerColor);
3894
3895		    	// Change Logo
3896		    	if( self.options.changeHeaderLogo && headerColor != undefined ) {
3897			    	if( headerColor == 'light' ) {
3898			    		$('#header .header-logo img').attr('src', self.options.headerLogoLight);
3899			    	} else if( headerColor == 'dark' ) {
3900			    		$('#header .header-logo img').attr('src', self.options.headerLogoDark);
3901			    	}
3902		    	}
3903
3904		    	self.$header.css({
3905		    		opacity: 1
3906		    	});
3907		    });
3908
3909			$(document).ready(function(){
3910			    $(window).afterResize(function(){
3911			    	self.updateSectionsHeight();
3912
3913			    	if( $(window).width() < 992 ) {
3914			    		$('html').removeClass('overflow-hidden');
3915			    	}
3916			    });
3917			});
3918
3919		    return this;
3920		}
3921	};
3922
3923	// expose to scope
3924	$.extend(theme, {
3925		PluginSectionScroll: PluginSectionScroll
3926	});
3927
3928	// jquery plugin
3929	$.fn.themePluginSectionScroll = function(opts) {
3930		return this.map(function() {
3931			var $this = $(this);
3932
3933			if ($this.data(instanceName)) {
3934				return $this.data(instanceName);
3935			} else {
3936				return new PluginSectionScroll($this, opts);
3937			}
3938
3939		});
3940	};
3941
3942}).apply(this, [window.theme, jQuery]);
3943
3944// Sort
3945(function(theme, $) {
3946
3947	theme = theme || {};
3948
3949	var instanceName = '__sort';
3950
3951	var PluginSort = function($el, opts) {
3952		return this.initialize($el, opts);
3953	};
3954
3955	PluginSort.defaults = {
3956		useHash: true,
3957		itemSelector: '.isotope-item',
3958		layoutMode: 'masonry',
3959		filter: '*',
3960		hiddenStyle: {
3961			opacity: 0
3962		},
3963		visibleStyle: {
3964			opacity: 1
3965		},
3966		stagger: 30,
3967		isOriginLeft: ($('html').attr('dir') == 'rtl' ? false : true)
3968	};
3969
3970	PluginSort.prototype = {
3971		initialize: function($el, opts) {
3972			if ($el.data(instanceName)) {
3973				return this;
3974			}
3975
3976			this.$el = $el;
3977
3978			this
3979				.setData()
3980				.setOptions(opts)
3981				.build();
3982
3983			return this;
3984		},
3985
3986		setData: function() {
3987			this.$el.data(instanceName, this);
3988
3989			return this;
3990		},
3991
3992		setOptions: function(opts) {
3993			this.options = $.extend(true, {}, PluginSort.defaults, opts, {
3994				wrapper: this.$el
3995			});
3996
3997			return this;
3998		},
3999
4000		build: function() {
4001			if (!($.isFunction($.fn.isotope))) {
4002				return this;
4003			}
4004
4005			var self = this,
4006				$source = this.options.wrapper,
4007				$destination = $('.sort-destination[data-sort-id="' + $source.attr('data-sort-id') + '"]'),
4008				$window = $(window);
4009
4010			if ($destination.get(0)) {
4011
4012				self.$source = $source;
4013				self.$destination = $destination;
4014				self.$loader = false;
4015
4016				self.setParagraphHeight($destination);
4017
4018				if (self.$destination.parents('.sort-destination-loader').get(0)) {
4019					self.$loader = self.$destination.parents('.sort-destination-loader');
4020					self.createLoader();
4021				}
4022
4023				$destination.attr('data-filter', '*');
4024
4025				$destination.one('layoutComplete', function(event, laidOutItems) {
4026					self.removeLoader();
4027				});
4028
4029				// IE10/11 fix
4030				if( $('html').hasClass('ie10') || $('html').hasClass('ie11') ) {
4031					var padding = parseInt( self.options.wrapper.children().css('padding-left') ) + parseInt( self.options.wrapper.children().css('padding-right') );
4032				}
4033
4034				$destination.waitForImages(function() {
4035					$destination.isotope(self.options);
4036					self.events();
4037				});
4038
4039
4040				setTimeout(function() {
4041					self.removeLoader();
4042				}, 3000);
4043
4044			}
4045
4046			return this;
4047		},
4048
4049		events: function() {
4050			var self = this,
4051				filter = null,
4052				$window = $(window);
4053
4054			self.$source.find('a').click(function(e) {
4055				e.preventDefault();
4056
4057				filter = $(this).parent().data('option-value');
4058
4059				self.setFilter(filter);
4060
4061				if (e.originalEvent) {
4062					self.$source.trigger('filtered');
4063				}
4064
4065				return this;
4066			});
4067
4068			self.$destination.trigger('filtered');
4069			self.$source.trigger('filtered');
4070
4071			if (self.options.useHash) {
4072				self.hashEvents();
4073			}
4074
4075			$window.on('resize', function() {
4076				setTimeout(function() {
4077					self.$destination.isotope('layout');
4078				}, 300);
4079			});
4080
4081			setTimeout(function() {
4082				$window.trigger('resize');
4083			}, 300);
4084
4085			return this;
4086		},
4087
4088		setFilter: function(filter) {
4089			var self = this,
4090				page = false,
4091				currentFilter = filter;
4092
4093			self.$source.find('.active').removeClass('active');
4094			self.$source.find('li[data-option-value="' + filter + '"], li[data-option-value="' + filter + '"] > a').addClass('active');
4095
4096			self.options.filter = currentFilter;
4097
4098			if (self.$destination.attr('data-current-page')) {
4099				currentFilter = currentFilter + '[data-page-rel=' + self.$destination.attr('data-current-page') + ']';
4100			}
4101
4102			self.$destination.attr('data-filter', filter).isotope({
4103				filter: currentFilter
4104			}).one('arrangeComplete', function( event, filteredItems ) {
4105				
4106				if (self.options.useHash) {
4107					if (window.location.hash != '' || self.options.filter.replace('.', '') != '*') {
4108						window.location.hash = self.options.filter.replace('.', '');
4109					}
4110				}
4111				
4112				$(window).trigger('scroll');
4113
4114			}).trigger('filtered');
4115
4116			return this;
4117		},
4118
4119		hashEvents: function() {
4120			var self = this,
4121				hash = null,
4122				hashFilter = null,
4123				initHashFilter = '.' + location.hash.replace('#', '');
4124
4125			if (initHashFilter != '.' && initHashFilter != '.*') {
4126				self.setFilter(initHashFilter);
4127			}
4128
4129			$(window).on('hashchange', function(e) {
4130
4131				hashFilter = '.' + location.hash.replace('#', '');
4132				hash = (hashFilter == '.' || hashFilter == '.*' ? '*' : hashFilter);
4133
4134				self.setFilter(hash);
4135
4136			});
4137
4138			return this;
4139		},
4140
4141		setParagraphHeight: function() {
4142			var self = this,
4143				minParagraphHeight = 0,
4144				paragraphs = $('span.thumb-info-caption p', self.$destination);
4145
4146			paragraphs.each(function() {
4147				if ($(this).height() > minParagraphHeight) {
4148					minParagraphHeight = ($(this).height() + 10);
4149				}
4150			});
4151
4152			paragraphs.height(minParagraphHeight);
4153
4154			return this;
4155		},
4156
4157		createLoader: function() {
4158			var self = this;
4159
4160			var loaderTemplate = [
4161				'<div class="bounce-loader">',
4162					'<div class="bounce1"></div>',
4163					'<div class="bounce2"></div>',
4164					'<div class="bounce3"></div>',
4165				'</div>'
4166			].join('');
4167
4168			self.$loader.append(loaderTemplate);
4169
4170			return this;
4171		},
4172
4173		removeLoader: function() {
4174
4175			var self = this;
4176
4177			if (self.$loader) {
4178
4179				self.$loader.removeClass('sort-destination-loader-showing');
4180
4181				setTimeout(function() {
4182					self.$loader.addClass('sort-destination-loader-loaded');
4183				}, 300);
4184
4185			}
4186
4187		}
4188
4189	};
4190
4191	// expose to scope
4192	$.extend(theme, {
4193		PluginSort: PluginSort
4194	});
4195
4196	// jquery plugin
4197	$.fn.themePluginSort = function(opts) {
4198		return this.map(function() {
4199			var $this = $(this);
4200
4201			if ($this.data(instanceName)) {
4202				return $this.data(instanceName);
4203			} else {
4204				return new PluginSort($this, opts);
4205			}
4206
4207		});
4208	}
4209
4210}).apply(this, [window.theme, jQuery]);
4211
4212// Star Rating
4213(function(theme, $) {
4214
4215	theme = theme || {};
4216
4217	var instanceName = '__starrating';
4218
4219	var PluginStarRating = function($el, opts) {
4220		return this.initialize($el, opts);
4221	};
4222
4223	PluginStarRating.defaults = {
4224		theme: 'krajee-fas',
4225		color: 'primary',
4226		showClear: false,
4227		showCaption: false
4228	};
4229
4230	PluginStarRating.prototype = {
4231		initialize: function($el, opts) {
4232			this.$el = $el;
4233
4234			this
4235				.setData()
4236				.setOptions(opts)
4237				.build();
4238
4239			return this;
4240		},
4241
4242		setData: function() {
4243			this.$el.data(instanceName, this);
4244
4245			return this;
4246		},
4247
4248		setOptions: function(opts) {
4249			this.options = $.extend(true, {}, PluginStarRating.defaults, opts, {
4250				wrapper: this.$el
4251			});
4252
4253			return this;
4254		},
4255
4256		build: function() {
4257
4258			if (!($.isFunction($.fn.rating))) {
4259				return this;
4260			}
4261
4262			var self = this;
4263
4264			self.options.wrapper
4265				.rating(self.options);
4266
4267			self.options.wrapper.parents('.rating-container')
4268				.addClass('rating-' + self.options.color);
4269
4270			if( self.options.extraClass ) {
4271				self.options.wrapper.parents('.rating-container')
4272					.addClass(self.options.extraClass);
4273			}
4274
4275			return this;
4276
4277		}
4278	};
4279
4280	// expose to scope
4281	$.extend(theme, {
4282		PluginStarRating: PluginStarRating
4283	});
4284
4285	// jquery plugin
4286	$.fn.themePluginStarRating = function(opts) {
4287		return this.map(function() {
4288			var $this = $(this);
4289
4290			if ($this.data(instanceName)) {
4291				return $this.data(instanceName);
4292			} else {
4293				return new PluginStarRating($this, opts);
4294			}
4295
4296		});
4297	}
4298
4299}).apply(this, [window.theme, jQuery]);
4300
4301// Sticky
4302(function(theme, $) {
4303	
4304	theme = theme || {};
4305	
4306	var instanceName = '__sticky';
4307
4308	var PluginSticky = function($el, opts) {
4309		return this.initialize($el, opts);
4310	};
4311
4312	PluginSticky.defaults = {
4313		minWidth: 991,
4314		activeClass: 'sticky-active'
4315	};
4316
4317	PluginSticky.prototype = {
4318		initialize: function($el, opts) {
4319			if ( $el.data( instanceName ) ) {
4320				return this;
4321			}
4322
4323			this.$el = $el;
4324
4325			this
4326				.setData()
4327				.setOptions(opts)
4328				.build()
4329				.events();
4330
4331			return this;
4332		},
4333
4334		setData: function() {
4335			this.$el.data(instanceName, this);
4336
4337			return this;
4338		},
4339
4340		setOptions: function(opts) {
4341			this.options = $.extend(true, {}, PluginSticky.defaults, opts, {
4342				wrapper: this.$el
4343			});
4344
4345			return this;
4346		},
4347
4348		build: function() {
4349			if (!($.isFunction($.fn.pin))) {
4350				return this;
4351			}
4352
4353			var self = this,
4354				$window = $(window);
4355			
4356			self.options.wrapper.pin(self.options);
4357
4358			if( self.options.wrapper.hasClass('sticky-wrapper-transparent') ) {
4359				self.options.wrapper.parent().addClass('position-absolute w-100');
4360			}
4361
4362			$window.afterResize(function() {
4363				self.options.wrapper.removeAttr('style').removeData('pin');
4364				self.options.wrapper.pin(self.options);
4365				$window.trigger('scroll');
4366			});
4367
4368			// Change Logo Src
4369			if( self.options.wrapper.find('img').attr('data-change-src') ) {
4370				var $logo      = self.options.wrapper.find('img'),
4371					logoSrc    = $logo.attr('src'),
4372					logoNewSrc = $logo.attr('data-change-src');
4373
4374				self.changeLogoSrc = function(activate) {
4375					if(activate) {
4376						$logo.attr('src', logoNewSrc);
4377					} else {
4378						$logo.attr('src', logoSrc);
4379					}
4380				}
4381			}
4382			
4383			return this;
4384		},
4385
4386		events: function() {
4387			var self = this,
4388				$window = $(window),
4389				$logo = self.options.wrapper.find('img'),
4390				sticky_activate_flag = true,
4391				sticky_deactivate_flag = false,
4392				class_to_check = ( self.options.wrapper.hasClass('sticky-wrapper-effect-1') ) ? 'sticky-effect-active' : 'sticky-active';
4393
4394			$window.on('scroll sticky.effect.active', function(){
4395				if( self.options.wrapper.hasClass( class_to_check ) ) {		
4396					if( sticky_activate_flag ) {			
4397						if( $logo.attr('data-change-src') ) {
4398							self.changeLogoSrc(true);
4399						}
4400
4401						sticky_activate_flag = false;
4402						sticky_deactivate_flag = true;
4403					}
4404				} else {	
4405					if( sticky_deactivate_flag ) {				
4406						if( $logo.attr('data-change-src') ) {
4407							self.changeLogoSrc(false);
4408						}
4409
4410						sticky_deactivate_flag = false;
4411						sticky_activate_flag = true;
4412					}
4413				}
4414			});
4415
4416			var is_backing = false;
4417			if( self.options.stickyStartEffectAt ) {
4418
4419				// First Load
4420				if( self.options.stickyStartEffectAt < $window.scrollTop() ) {
4421					self.options.wrapper.addClass('sticky-effect-active');
4422
4423					$window.trigger('sticky.effect.active');
4424				}
4425
4426				$window.on('scroll', function(){
4427					if( self.options.stickyStartEffectAt < $window.scrollTop() ) {	
4428						self.options.wrapper.addClass('sticky-effect-active');
4429						is_backing = true;
4430
4431						$window.trigger('sticky.effect.active');
4432					} else {	
4433						if( is_backing ) {
4434							self.options.wrapper.find('.sticky-body').addClass('position-fixed');
4435							is_backing = false;
4436						}
4437
4438						if( $window.scrollTop() == 0 ) {
4439							self.options.wrapper.find('.sticky-body').removeClass('position-fixed');
4440						}
4441
4442						self.options.wrapper.removeClass('sticky-effect-active');
4443					}
4444				});
4445			}
4446
4447			// Refresh Sticky Plugin if click in a data-toggle="collapse"
4448			if( $('[data-toggle="collapse"]').get(0) ) {
4449
4450				$('[data-toggle="collapse"]').on('click', function(){
4451					setTimeout(function(){
4452						self.build();
4453						$(window).trigger('scroll');
4454					}, 1000);
4455				});
4456
4457			}
4458		}
4459	};
4460
4461	// expose to scope
4462	$.extend(theme, {
4463		PluginSticky: PluginSticky
4464	});
4465
4466	// jquery plugin
4467	$.fn.themePluginSticky = function(opts) {
4468		return this.map(function() {
4469			var $this = $(this);
4470
4471			if ($this.data(instanceName)) {
4472				return $this.data(instanceName);
4473			} else {
4474				return new PluginSticky($this, opts);
4475			}
4476			
4477		});
4478	}
4479
4480}).apply(this, [ window.theme, jQuery ]);
4481
4482// Toggle
4483(function(theme, $) {
4484
4485	theme = theme || {};
4486
4487	var instanceName = '__toggle';
4488
4489	var PluginToggle = function($el, opts) {
4490		return this.initialize($el, opts);
4491	};
4492
4493	PluginToggle.defaults = {
4494		duration: 350,
4495		isAccordion: false
4496	};
4497
4498	PluginToggle.prototype = {
4499		initialize: function($el, opts) {
4500			if ($el.data(instanceName)) {
4501				return this;
4502			}
4503
4504			this.$el = $el;
4505
4506			this
4507				.setData()
4508				.setOptions(opts)
4509				.build();
4510
4511			return this;
4512		},
4513
4514		setData: function() {
4515			this.$el.data(instanceName, this);
4516
4517			return this;
4518		},
4519
4520		setOptions: function(opts) {
4521			this.options = $.extend(true, {}, PluginToggle.defaults, opts, {
4522				wrapper: this.$el
4523			});
4524
4525			return this;
4526		},
4527
4528		build: function() {
4529			var self = this,
4530				$wrapper = this.options.wrapper,
4531				$items = $wrapper.find('> .toggle'),
4532				$el = null;
4533
4534			$items.each(function() {
4535				$el = $(this);
4536
4537				if ($el.hasClass('active')) {
4538					$el.find('> p').addClass('preview-active');
4539					$el.find('> .toggle-content').slideDown(self.options.duration);
4540				}
4541
4542				self.events($el);
4543			});
4544
4545			if (self.options.isAccordion) {
4546				self.options.duration = self.options.duration / 2;
4547			}
4548
4549			return this;
4550		},
4551
4552		events: function($el) {
4553			var self = this,
4554				previewParCurrentHeight = 0,
4555				previewParAnimateHeight = 0,
4556				toggleContent = null;
4557
4558			$el.find('> label, > .toggle-title').click(function(e) {
4559
4560				var $this = $(this),
4561					parentSection = $this.parent(),
4562					parentWrapper = $this.parents('.toggle'),
4563					previewPar = null,
4564					closeElement = null;
4565
4566				if (self.options.isAccordion && typeof(e.originalEvent) != 'undefined') {
4567					closeElement = parentWrapper.find('.toggle.active > label, .toggle.active > .toggle-title');
4568
4569					if (closeElement[0] == $this[0]) {
4570						return;
4571					}
4572				}
4573
4574				parentSection.toggleClass('active');
4575
4576				// Preview Paragraph
4577				if (parentSection.find('> p').get(0)) {
4578
4579					previewPar = parentSection.find('> p');
4580					previewParCurrentHeight = previewPar.css('height');
4581					previewPar.css('height', 'auto');
4582					previewParAnimateHeight = previewPar.css('height');
4583					previewPar.css('height', previewParCurrentHeight);
4584
4585				}
4586
4587				// Content
4588				toggleContent = parentSection.find('> .toggle-content');
4589
4590				if (parentSection.hasClass('active')) {
4591
4592					$(previewPar).animate({
4593						height: previewParAnimateHeight
4594					}, self.options.duration, function() {
4595						$(this).addClass('preview-active');
4596					});
4597
4598					toggleContent.slideDown(self.options.duration, function() {
4599						if (closeElement) {
4600							closeElement.trigger('click');
4601						}
4602					});
4603
4604				} else {
4605
4606					$(previewPar).animate({
4607						height: 0
4608					}, self.options.duration, function() {
4609						$(this).removeClass('preview-active');
4610					});
4611
4612					toggleContent.slideUp(self.options.duration);
4613
4614				}
4615
4616			});
4617		}
4618	};
4619
4620	// expose to scope
4621	$.extend(theme, {
4622		PluginToggle: PluginToggle
4623	});
4624
4625	// jquery plugin
4626	$.fn.themePluginToggle = function(opts) {
4627		return this.map(function() {
4628			var $this = $(this);
4629
4630			if ($this.data(instanceName)) {
4631				return $this.data(instanceName);
4632			} else {
4633				return new PluginToggle($this, opts);
4634			}
4635
4636		});
4637	}
4638
4639}).apply(this, [window.theme, jQuery]);
4640
4641// Tweets
4642(function(theme, $) {
4643
4644	theme = theme || {};
4645
4646	var instanceName = '__tweets';
4647
4648	var PluginTweets = function($el, opts) {
4649		return this.initialize($el, opts);
4650	};
4651
4652	PluginTweets.defaults = {
4653		username: null,
4654		count: 2,
4655		URL: 'php/twitter-feed.php',
4656		iconColor: false
4657	};
4658
4659	PluginTweets.prototype = {
4660		initialize: function($el, opts) {
4661			if ($el.data(instanceName)) {
4662				return this;
4663			}
4664
4665			this.$el = $el;
4666
4667			this
4668				.setData()
4669				.setOptions(opts)
4670				.build();
4671
4672			return this;
4673		},
4674
4675		setData: function() {
4676			this.$el.data(instanceName, this);
4677
4678			return this;
4679		},
4680
4681		setOptions: function(opts) {
4682			this.options = $.extend(true, {}, PluginTweets.defaults, opts, {
4683				wrapper: this.$el
4684			});
4685
4686			return this;
4687		},
4688
4689		build: function() {
4690			if (this.options.username == null || this.options.username == '') {
4691				return this;
4692			}
4693
4694			var self = this,
4695				$wrapper = this.options.wrapper;
4696
4697			$.ajax({
4698				type: 'GET',
4699				data: {
4700					twitter_screen_name: self.options.username,
4701					tweets_to_display: self.options.count,
4702					icon_color: self.options.iconColor
4703				},
4704				url: self.options.URL,
4705			}).done(function(html) {
4706				$wrapper.html(html).find('a').attr('target','_blank');
4707			});
4708
4709			return this;
4710		}
4711	};
4712
4713	// expose to scope
4714	$.extend(theme, {
4715		PluginTweets: PluginTweets
4716	});
4717
4718	// jquery plugin
4719	$.fn.themePluginTweets = function(opts) {
4720		return this.map(function() {
4721			var $this = $(this);
4722
4723			if ($this.data(instanceName)) {
4724				return $this.data(instanceName);
4725			} else {
4726				return new PluginTweets($this, opts);
4727			}
4728
4729		});
4730	}
4731
4732}).apply(this, [window.theme, jQuery]);
4733
4734// Validation
4735(function(theme, $) {
4736
4737	theme = theme || {};
4738
4739	$.extend(theme, {
4740
4741		PluginValidation: {
4742
4743			defaults: {
4744				formClass: 'needs-validation',
4745				validator: {
4746					highlight: function(element) {
4747						$(element)
4748							.addClass('is-invalid')
4749							.removeClass('is-valid')
4750							.parent()
4751							.removeClass('has-success')
4752							.addClass('has-danger');
4753					},
4754					success: function(label, element) {
4755						$(element)
4756							.removeClass('is-invalid')
4757							.addClass('is-valid')
4758							.parent()
4759							.removeClass('has-danger')
4760							.addClass('has-success')
4761							.find('label.error')
4762							.remove();
4763					},
4764					errorPlacement: function(error, element) {
4765						if (element.attr('type') == 'radio' || element.attr('type') == 'checkbox') {
4766							error.appendTo(element.parent().parent());
4767						} else {
4768							error.insertAfter(element);
4769						}
4770					}
4771				},
4772				validateCaptchaURL: 'php/contact-form-verify-captcha.php',
4773				refreshCaptchaURL: 'php/contact-form-refresh-captcha.php'
4774			},
4775
4776			initialize: function(opts) {
4777				initialized = true;
4778
4779				this
4780					.setOptions(opts)
4781					.build();
4782
4783				return this;
4784			},
4785
4786			setOptions: function(opts) {
4787				this.options = $.extend(true, {}, this.defaults, opts);
4788
4789				return this;
4790			},
4791
4792			build: function() {
4793				var self = this;
4794
4795				if (!($.isFunction($.validator))) {
4796					return this;
4797				}
4798
4799				self.addMethods();
4800				self.setMessageGroups();
4801
4802				$.validator.setDefaults(self.options.validator);
4803
4804				$('.' + self.options.formClass).validate();
4805
4806				return this;
4807			},
4808
4809			addMethods: function() {
4810				var self = this;
4811
4812				$.validator.addMethod('captcha', function(value, element, params) {
4813					var captchaValid = false;
4814
4815					$.ajax({
4816						url: self.options.validateCaptchaURL,
4817						type: 'POST',
4818						async: false,
4819						dataType: 'json',
4820						data: {
4821							captcha: $.trim(value)
4822						},
4823						success: function(data) {
4824							if (data.response == 'success') {
4825								captchaValid = true;
4826							}
4827						}
4828					});
4829
4830					if (captchaValid) {
4831						return true;
4832					}
4833
4834				}, '');
4835
4836				// Refresh Captcha
4837				$('#refreshCaptcha').on('click', function(e) {
4838					e.preventDefault();
4839					$.get(self.options.refreshCaptchaURL, function(url) {
4840						$('#captcha-image').attr('src', url);
4841					});					
4842				});
4843
4844			},
4845
4846			setMessageGroups: function() {
4847
4848				$('.checkbox-group[data-msg-required], .radio-group[data-msg-required]').each(function() {
4849					var message = $(this).data('msg-required');
4850					$(this).find('input').attr('data-msg-required', message);
4851				});
4852
4853			}
4854
4855		}
4856
4857	});
4858
4859}).apply(this, [window.theme, jQuery]);
4860
4861// Video Background
4862(function(theme, $) {
4863
4864	theme = theme || {};
4865
4866	var instanceName = '__videobackground';
4867
4868	var PluginVideoBackground = function($el, opts) {
4869		return this.initialize($el, opts);
4870	};
4871
4872	PluginVideoBackground.defaults = {
4873		overlay: false,
4874		volume: 1,
4875		playbackRate: 1,
4876		muted: true,
4877		loop: true,
4878		autoplay: true,
4879		position: '50% 50%',
4880		posterType: 'detect',
4881		className: 'vide-video-wrapper'
4882	};
4883
4884	PluginVideoBackground.prototype = {
4885		initialize: function($el, opts) {
4886			this.$el = $el;
4887
4888			this
4889				.setData()
4890				.setOptions(opts)
4891				.build()
4892				.events();
4893
4894			return this;
4895		},
4896
4897		setData: function() {
4898			this.$el.data(instanceName, this);
4899
4900			return this;
4901		},
4902
4903		setOptions: function(opts) {
4904			this.options = $.extend(true, {}, PluginVideoBackground.defaults, opts, {
4905				path: this.$el.data('video-path'),
4906				wrapper: this.$el
4907			});
4908
4909			return this;
4910		},
4911
4912		build: function() {
4913			var self = this;
4914
4915			if (!($.isFunction($.fn.vide)) || (!this.options.path)) {
4916				return this;
4917			}
4918
4919			if (this.options.overlay) {
4920
4921				var overlayClass = this.options.overlayClass;
4922
4923				this.options.wrapper.prepend(
4924					$('<div />').addClass(overlayClass)
4925				);
4926			}
4927
4928			this.options.wrapper
4929				.vide(this.options.path, this.options)
4930				.first()
4931				.css('z-index', 0);
4932
4933			// Change Poster
4934			self.changePoster();
4935
4936			// Initialize Vide inside a carousel
4937			if( self.options.wrapper.closest('.owl-carousel').get(0) ) {
4938				self.options.wrapper.closest('.owl-carousel').on('initialized.owl.carousel', function(){
4939					$('.owl-item.cloned')
4940						.find('[data-plugin-video-background] .vide-video-wrapper')
4941						.remove();
4942
4943					$('.owl-item.cloned')
4944						.find('[data-plugin-video-background]')
4945						.vide(self.options.path, self.options)
4946						.first()
4947						.css('z-index', 0);
4948
4949					self.changePoster( self.options.wrapper.closest('.owl-carousel') );
4950				});
4951			}
4952
4953			// Play Video Button
4954			var $playButton = self.options.wrapper.find('.video-background-play');
4955
4956			if( $playButton.get(0) ) {
4957				var $playWrapper = self.options.wrapper.find('.video-background-play-wrapper');
4958
4959				self.options.wrapper.find('.video-background-play').on('click', function(e){
4960					e.preventDefault();
4961
4962					if( $playWrapper.get(0) ) {
4963						$playWrapper.animate({
4964							opacity: 0
4965						}, 300, function(){
4966							$playWrapper.parent().height( $playWrapper.outerHeight() );
4967							$playWrapper.remove();
4968						});
4969					} else {
4970						$playButton.animate({
4971							opacity: 0
4972						}, 300, function(){
4973							$playButton.remove();
4974						});
4975					}
4976
4977					setTimeout(function(){
4978						self.options.wrapper.find('video')[0].play();
4979					}, 500)
4980				});
4981			}
4982
4983			return this;
4984		},
4985
4986		changePoster: function( $carousel ) {
4987			var self = this;
4988
4989			// If it's inside carousel
4990			if( $carousel && self.options.changePoster ) {
4991				$carousel.find('.owl-item [data-plugin-video-background] .vide-video-wrapper').css({
4992					'background-image': 'url(' + self.options.changePoster + ')'
4993				});
4994
4995				return this;
4996			}
4997
4998			if( self.options.changePoster ) {
4999				self.options.wrapper.find('.vide-video-wrapper').css({
5000					'background-image': 'url(' + self.options.changePoster + ')'
5001				});
5002			}
5003
5004			return this;
5005		},
5006
5007		events: function() {
5008			var self = this;
5009
5010			// Initialize
5011			self.options.wrapper.on('video.background.initialize', function(){
5012				self.build();
5013			});
5014
5015			return this;
5016		}
5017	};
5018
5019	// expose to scope
5020	$.extend(theme, {
5021		PluginVideoBackground: PluginVideoBackground
5022	});
5023
5024	// jquery plugin
5025	$.fn.themePluginVideoBackground = function(opts) {
5026		return this.map(function() {
5027			var $this = $(this);
5028
5029			if ($this.data(instanceName)) {
5030				return $this.data(instanceName);
5031			} else {
5032				return new PluginVideoBackground($this, opts);
5033			}
5034
5035		});
5036	}
5037
5038}).apply(this, [window.theme, jQuery]);
5039
5040// Account
5041(function(theme, $) {
5042
5043	theme = theme || {};
5044
5045	var initialized = false;
5046
5047	$.extend(theme, {
5048
5049		Account: {
5050
5051			defaults: {
5052				wrapper: $('#headerAccount')
5053			},
5054
5055			initialize: function($wrapper, opts) {
5056				if (initialized) {
5057					return this;
5058				}
5059
5060				initialized = true;
5061				this.$wrapper = ($wrapper || this.defaults.wrapper);
5062
5063				this
5064					.setOptions(opts)
5065					.events();
5066
5067				return this;
5068			},
5069
5070			setOptions: function(opts) {
5071				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
5072
5073				return this;
5074			},
5075
5076			events: function() {
5077				var self = this;
5078
5079				$(window).on('load', function(){
5080					$(document).ready(function(){
5081						setTimeout(function(){
5082
5083							self.$wrapper.find('input').on('focus', function() {
5084								self.$wrapper.addClass('open');
5085
5086								$(document).mouseup(function(e) {
5087									if (!self.$wrapper.is(e.target) && self.$wrapper.has(e.target).length === 0) {
5088										self.$wrapper.removeClass('open');
5089									}
5090								});
5091							});
5092
5093						}, 1500);
5094					});
5095				});
5096
5097				$('#headerSignUp').on('click', function(e) {
5098					e.preventDefault();
5099					self.$wrapper.addClass('signup').removeClass('signin').removeClass('recover');
5100					self.$wrapper.find('.signup-form input:first').focus();
5101				});
5102
5103				$('#headerSignIn').on('click', function(e) {
5104					e.preventDefault();
5105					self.$wrapper.addClass('signin').removeClass('signup').removeClass('recover');
5106					self.$wrapper.find('.signin-form input:first').focus();
5107				});
5108
5109				$('#headerRecover').on('click', function(e) {
5110					e.preventDefault();
5111					self.$wrapper.addClass('recover').removeClass('signup').removeClass('signin');
5112					self.$wrapper.find('.recover-form input:first').focus();
5113				});
5114
5115				$('#headerRecoverCancel').on('click', function(e) {
5116					e.preventDefault();
5117					self.$wrapper.addClass('signin').removeClass('signup').removeClass('recover');
5118					self.$wrapper.find('.signin-form input:first').focus();
5119				});
5120			}
5121
5122		}
5123
5124	});
5125
5126}).apply(this, [window.theme, jQuery]);
5127
5128// Nav
5129(function(theme, $) {
5130
5131	theme = theme || {};
5132
5133	var initialized = false;
5134
5135	$.extend(theme, {
5136
5137		Nav: {
5138
5139			defaults: {
5140				wrapper: $('#mainNav'),
5141				scrollDelay: 600,
5142				scrollAnimation: 'easeOutQuad'
5143			},
5144
5145			initialize: function($wrapper, opts) {
5146				if (initialized) {
5147					return this;
5148				}
5149
5150				initialized = true;
5151				this.$wrapper = ($wrapper || this.defaults.wrapper);
5152
5153				this
5154					.setOptions(opts)
5155					.build()
5156					.events();
5157
5158				return this;
5159			},
5160
5161			setOptions: function(opts) {
5162				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
5163
5164				return this;
5165			},
5166
5167			build: function() {
5168				var self = this,
5169					$html = $('html'),
5170					$header = $('#header'),
5171					$headerNavMain = $('#header .header-nav-main'),
5172					thumbInfoPreview;
5173
5174				// Preview Thumbs
5175				self.$wrapper.find('a[data-thumb-preview]').each(function() {
5176					thumbInfoPreview = $('<span />').addClass('thumb-info thumb-info-preview')
5177											.append($('<span />').addClass('thumb-info-wrapper')
5178												.append($('<span />').addClass('thumb-info-image').css('background-image', 'url(' + $(this).data('thumb-preview') + ')')
5179										   )
5180									   );
5181
5182					$(this).append(thumbInfoPreview);
5183				});
5184
5185				// Side Header / Side Header Hamburguer Sidebar (Reverse Dropdown)
5186				if($html.hasClass('side-header') || $html.hasClass('side-header-hamburguer-sidebar')) {
5187					
5188					// Side Header Right / Side Header Hamburguer Sidebar Right
5189					if($html.hasClass('side-header-right') || $html.hasClass('side-header-hamburguer-sidebar-right')) {
5190						if(!$html.hasClass('side-header-right-no-reverse')) {
5191							$header.find('.dropdown-submenu').addClass('dropdown-reverse');
5192						}
5193					}
5194
5195				} else {
5196					
5197					// Reverse
5198					self.checkReverse = function() {
5199						self.$wrapper.find('.dropdown, .dropdown-submenu').removeClass('dropdown-reverse');
5200
5201						self.$wrapper.find('.dropdown:not(.manual):not(.dropdown-mega), .dropdown-submenu:not(.manual)').each(function() {
5202							if(!$(this).find('.dropdown-menu').visible( false, true, 'horizontal' )  ) {
5203								$(this).addClass('dropdown-reverse');
5204							}
5205						});
5206					}
5207
5208					self.checkReverse();
5209
5210	 				$(window).on('resize', function() {
5211						self.checkReverse();
5212	 				});
5213
5214				}
5215
5216				// Clone Items
5217				if($headerNavMain.hasClass('header-nav-main-clone-items')) {
5218
5219			    	$headerNavMain.find('nav > ul > li > a').each(function(){
5220				    	var parent = $(this).parent(),
5221				    		clone  = $(this).clone(),
5222				    		clone2 = $(this).clone(),
5223				    		wrapper = $('<span class="wrapper-items-cloned"></span>');
5224
5225				    	// Config Classes
5226				    	$(this).addClass('item-original');
5227				    	clone2.addClass('item-two');
5228
5229				    	// Insert on DOM
5230				    	parent.prepend(wrapper);
5231				    	wrapper.append(clone).append(clone2);
5232				    });
5233
5234				}
5235
5236				// Floating
5237				if($('#header.header-floating-icons').get(0) && $(window).width() > 991) {
5238
5239					var menuFloatingAnim = {
5240						$menuFloating: $('#header.header-floating-icons .header-container > .header-row'),
5241
5242						build: function() {
5243							var self = this;
5244
5245							self.init();
5246						},
5247						init: function(){
5248							var self  = this,
5249								divisor = 0;
5250
5251							$(window).scroll(function() {
5252							    var scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height()),
5253							    	st = $(this).scrollTop();
5254
5255								divisor = $(document).height() / $(window).height();
5256
5257							    self.$menuFloating.find('.header-column > .header-row').css({
5258							    	transform : 'translateY( calc('+ scrollPercent +'vh - '+ st / divisor +'px) )' 
5259							    });
5260							});
5261						}
5262					}
5263
5264					menuFloatingAnim.build();
5265
5266				}
5267
5268				// Slide
5269				if($('.header-nav-links-vertical-slide').get(0)) {
5270					var slideNavigation = {
5271						$mainNav: $('#mainNav'),
5272						$mainNavItem: $('#mainNav li'),
5273
5274						build: function(){
5275							var self = this;
5276
5277							self.menuNav();
5278						},
5279						menuNav: function(){
5280							var self = this;
5281
5282							self.$mainNavItem.on('click', function(e){
5283								var currentMenuItem 	= $(this),
5284									currentMenu 		= $(this).parent(),
5285									nextMenu        	= $(this).find('ul').first(),
5286									prevMenu        	= $(this).closest('.next-menu'),
5287									isSubMenu       	= currentMenuItem.hasClass('dropdown') || currentMenuItem.hasClass('dropdown-submenu'),
5288									isBack          	= currentMenuItem.hasClass('back-button'),
5289									nextMenuHeightDiff  = ( ( nextMenu.find('> li').length * nextMenu.find('> li').outerHeight() ) - nextMenu.outerHeight() ),
5290									prevMenuHeightDiff  = ( ( prevMenu.find('> li').length * prevMenu.find('> li').outerHeight() ) - prevMenu.outerHeight() );
5291
5292								if( isSubMenu ) {
5293									currentMenu.addClass('next-menu');
5294									nextMenu.addClass('visible');
5295									currentMenu.css({
5296										overflow: 'visible',
5297										'overflow-y': 'visible'
5298									});
5299									
5300									if( nextMenuHeightDiff > 0 ) {
5301										nextMenu.css({
5302											overflow: 'hidden',
5303											'overflow-y': 'scroll'
5304										});
5305									}
5306
5307									for( i = 0; i < nextMenu.find('> li').length; i++ ) {
5308										if( nextMenu.outerHeight() < ($('.header-row-side-header').outerHeight() - 100) ) {
5309											nextMenu.css({
5310												height: nextMenu.outerHeight() + nextMenu.find('> li').outerHeight()
5311											});
5312										}
5313									}
5314
5315									nextMenu.css({
5316										'padding-top': nextMenuHeightDiff + 'px'
5317									});
5318								}
5319
5320								if( isBack ) {
5321									currentMenu.parent().parent().removeClass('next-menu');
5322									currentMenu.removeClass('visible');
5323
5324									if( prevMenuHeightDiff > 0 ) {
5325										prevMenu.css({
5326											overflow: 'hidden',
5327											'overflow-y': 'scroll'
5328										});
5329									}
5330								}
5331
5332								e.stopPropagation();
5333							});
5334						}
5335					}
5336
5337					$(window).trigger('resize');
5338					
5339					if( $(window).width() > 991 ) {
5340						slideNavigation.build();
5341					}
5342
5343					$(document).ready(function(){
5344						$(window).afterResize(function(){
5345							if( $(window).width() > 991 ) {
5346								slideNavigation.build();
5347							}
5348						});
5349					});
5350				}
5351
5352				// Header Nav Main Mobile Dark
5353				if($('.header-nav-main-mobile-dark').get(0)) {
5354					$('#header:not(.header-transparent-dark-bottom-border):not(.header-transparent-light-bottom-border)').addClass('header-no-border-bottom');
5355				}
5356
5357				// Keyboard Navigation / Accessibility
5358				if( $(window).width() > 991 ) {
5359					this.focusMenuWithChildren();
5360				}
5361				
5362				return this;
5363			},
5364
5365			focusMenuWithChildren: function() {
5366				// Get all the link elements within the primary menu.
5367				var links, i, len,
5368					menu = document.querySelector( 'html:not(.side-header):not(.side-header-hamburguer-sidebar):not(.side-header-overlay-full-screen) .header-nav-main > nav' );
5369
5370				if ( ! menu ) {
5371					return false;
5372				}
5373
5374				links = menu.getElementsByTagName( 'a' );
5375
5376				// Each time a menu link is focused or blurred, toggle focus.
5377				for ( i = 0, len = links.length; i < len; i++ ) {
5378					links[i].addEventListener( 'focus', toggleFocus, true );
5379					links[i].addEventListener( 'blur', toggleFocus, true );
5380				}
5381
5382				//Sets or removes the .focus class on an element.
5383				function toggleFocus() {
5384					var self = this;
5385
5386					// Move up through the ancestors of the current link until we hit .primary-menu.
5387					while ( -1 === self.className.indexOf( 'header-nav-main' ) ) {
5388						// On li elements toggle the class .focus.
5389						if ( 'li' === self.tagName.toLowerCase() ) {
5390							if ( -1 !== self.className.indexOf( 'open' ) ) {
5391								self.className = self.className.replace( ' open', '' );
5392							} else {
5393								self.className += ' open';
5394							}
5395						}
5396						self = self.parentElement;
5397					}
5398				}
5399			},
5400
5401			events: function() {
5402				var self    = this,
5403					$html   = $('html'),
5404					$header = $('#header'),
5405					$window = $(window),
5406					headerBodyHeight = $('.header-body').outerHeight();
5407
5408				$header.find('a[href="#"]').on('click', function(e) {
5409					e.preventDefault();
5410				});
5411
5412				// Mobile Arrows
5413				if( $html.hasClass('side-header-hamburguer-sidebar') ) {
5414					$header.find('.dropdown-toggle, .dropdown-submenu > a')
5415						.append('<i class="fas fa-chevron-down fa-chevron-right"></i>');
5416				} else {
5417					$header.find('.dropdown-toggle, .dropdown-submenu > a')
5418						.append('<i class="fas fa-chevron-down"></i>');
5419				}
5420				
5421				$header.find('.dropdown-toggle[href="#"], .dropdown-submenu a[href="#"], .dropdown-toggle[href!="#"] .fa-chevron-down, .dropdown-submenu a[href!="#"] .fa-chevron-down').on('click', function(e) {
5422					e.preventDefault();
5423					if ($window.width() < 992) {
5424						$(this).closest('li').toggleClass('open');
5425
5426						// Adjust Header Body Height
5427						var height = ( $header.hasClass('header-effect-shrink') && $html.hasClass('sticky-header-active') ) ? theme.StickyHeader.options.stickyHeaderContainerHeight : headerBodyHeight;
5428						$('.header-body').animate({
5429					 		height: ($('.header-nav-main nav').outerHeight(true) + height) + 10
5430					 	}, 0);
5431					}
5432				});
5433
5434				$header.find('li a.active').addClass('current-page-active');
5435
5436				// Add Open Class
5437				$header.find('.header-nav-click-to-open .dropdown-toggle[href="#"], .header-nav-click-to-open .dropdown-submenu a[href="#"], .header-nav-click-to-open .dropdown-toggle > i').on('click', function(e) {
5438					if( !$('html').hasClass('side-header-hamburguer-sidebar') && $window.width() > 991 ) {
5439						e.preventDefault();
5440						e.stopPropagation();
5441					}
5442
5443					if ($window.width() > 991) {
5444						e.preventDefault();
5445						e.stopPropagation();
5446
5447						$header.find('li a.active').removeClass('active');
5448
5449						if( $(this).prop('tagName') == 'I' ) {
5450							$(this).parent().addClass('active');
5451						} else {
5452							$(this).addClass('active');
5453						}
5454
5455						if (!$(this).closest('li').hasClass('open')) {
5456
5457							var $li = $(this).closest('li'),
5458								isSub = false;
5459
5460							if ( $(this).parent().hasClass('dropdown-submenu') ) {
5461								isSub = true;
5462							}
5463
5464							$(this).closest('.dropdown-menu').find('.dropdown-submenu.open').removeClass('open');
5465							$(this).parent('.dropdown').parent().find('.dropdown.open').removeClass('open');
5466
5467							if (!isSub) {
5468								$(this).parent().find('.dropdown-submenu.open').removeClass('open');
5469							}
5470
5471							$li.addClass('open');
5472
5473							$(document).off('click.nav-click-to-open').on('click.nav-click-to-open', function (e) {
5474								if (!$li.is(e.target) && $li.has(e.target).length === 0) {
5475									$li.removeClass('open');
5476									$li.parents('.open').removeClass('open');
5477									$header.find('li a.active').removeClass('active');
5478									$header.find('li a.current-page-active').addClass('active');
5479								}
5480							});
5481
5482						} else {
5483							$(this).closest('li').removeClass('open');
5484							$header.find('li a.active').removeClass('active');
5485							$header.find('li a.current-page-active').addClass('active');
5486						}
5487
5488						$window.trigger({
5489							type: 'resize',
5490							from: 'header-nav-click-to-open'
5491						});
5492					}
5493				});
5494
5495				// Collapse Nav
5496				$header.find('[data-collapse-nav]').on('click', function(e) {
5497					$(this).parents('.collapse').removeClass('show');
5498				});
5499
5500				// Top Features
5501				$header.find('.header-nav-features-toggle').on('click', function(e) {
5502					e.preventDefault();
5503
5504					var $toggleParent = $(this).parent();
5505
5506					if (!$(this).siblings('.header-nav-features-dropdown').hasClass('show')) {
5507
5508						var $dropdown = $(this).siblings('.header-nav-features-dropdown');
5509
5510						$('.header-nav-features-dropdown.show').removeClass('show');
5511
5512						$dropdown.addClass('show');
5513
5514						$(document).off('click.header-nav-features-toggle').on('click.header-nav-features-toggle', function (e) {
5515							if (!$toggleParent.is(e.target) && $toggleParent.has(e.target).length === 0) {
5516								$('.header-nav-features-dropdown.show').removeClass('show');
5517							}
5518						});
5519
5520						if ($(this).attr('data-focus')) {
5521							$('#' + $(this).attr('data-focus')).focus();
5522						}
5523
5524					} else {
5525						$(this).siblings('.header-nav-features-dropdown').removeClass('show');
5526					}
5527				});
5528
5529				// Hamburguer Menu
5530				var $hamburguerMenuBtn = $('.hamburguer-btn:not(.side-panel-toggle)'),
5531					$hamburguerSideHeader = $('#header.side-header, #header.side-header-overlay-full-screen');
5532				
5533				$hamburguerMenuBtn.on('click', function(){
5534					if($(this).attr('data-set-active') != 'false') {
5535						$(this).toggleClass('active');
5536					}
5537					$hamburguerSideHeader.toggleClass('side-header-hide');
5538					$html.toggleClass('side-header-hide');
5539
5540					$window.trigger('resize');
5541				});
5542
5543				$('.hamburguer-close:not(.side-panel-toggle)').on('click', function(){
5544					$('.hamburguer-btn:not(.hamburguer-btn-side-header-mobile-show)').trigger('click');
5545				});				
5546				
5547				// Set Header Body Height when open mobile menu
5548				$('.header-nav-main nav').on('show.bs.collapse', function () {
5549				 	$(this).removeClass('closed');
5550
5551				 	// Add Mobile Menu Opened Class
5552				 	$('html').addClass('mobile-menu-opened');
5553
5554			 		$('.header-body').animate({
5555				 		height: ($('.header-body').outerHeight() + $('.header-nav-main nav').outerHeight(true)) + 10
5556				 	});
5557
5558				 	// Header Below Slider / Header Bottom Slider - Scroll to menu position
5559				 	if( $('#header').is('.header-bottom-slider, .header-below-slider') && !$('html').hasClass('sticky-header-active') ) {
5560				 		self.scrollToTarget( $('#header'), 0 );
5561				 	}
5562				});
5563
5564				// Set Header Body Height when collapse mobile menu
5565				$('.header-nav-main nav').on('hide.bs.collapse', function () {
5566				 	$(this).addClass('closed');
5567
5568				 	// Remove Mobile Menu Opened Class
5569				 	$('html').removeClass('mobile-menu-opened');
5570
5571			 		$('.header-body').animate({
5572				 		height: ($('.header-body').outerHeight() - $('.header-nav-main nav').outerHeight(true))
5573				 	}, function(){
5574				 		$(this).height('auto');
5575				 	});
5576				});
5577
5578				// Header Effect Shrink - Adjust header body height on mobile
5579				$window.on('stickyHeader.activate', function(){
5580					if( $window.width() < 992 && $header.hasClass('header-effect-shrink') ) {
5581						if( $('.header-btn-collapse-nav').attr('aria-expanded') == 'true' ) {
5582							$('.header-body').animate({
5583						 		height: ( $('.header-nav-main nav').outerHeight(true) + theme.StickyHeader.options.stickyHeaderContainerHeight ) + ( ($('.header-nav-bar').get(0)) ? $('.header-nav-bar').outerHeight() : 0 ) 
5584						 	});
5585						}
5586					}
5587				});
5588
5589				$window.on('stickyHeader.deactivate', function(){
5590					if( $window.width() < 992 && $header.hasClass('header-effect-shrink') ) {
5591						if( $('.header-btn-collapse-nav').attr('aria-expanded') == 'true' ) {
5592							$('.header-body').animate({
5593						 		height: headerBodyHeight + $('.header-nav-main nav').outerHeight(true) + 10
5594						 	});
5595						}
5596					}
5597				});
5598
5599				// Remove Open Class on Resize		
5600				$window.on('resize.removeOpen', function(e) {
5601					if( e.from == 'header-nav-click-to-open' ) {
5602						return;
5603					}
5604					
5605					setTimeout(function() {
5606						if( $window.width() > 991 ) {
5607							$header.find('.dropdown.open').removeClass('open');
5608						}
5609					}, 100);
5610				});
5611
5612				// Side Header - Change value of initial header body height
5613				$(document).ready(function(){
5614					if( $window.width() > 991 ) {
5615						var flag = false;
5616						
5617						$window.on('resize', function(e) {
5618							if( e.from == 'header-nav-click-to-open' ) {
5619								return;
5620							}
5621
5622							$header.find('.dropdown.open').removeClass('open');
5623
5624							if( $window.width() < 992 && flag == false ) {
5625								headerBodyHeight = $('.header-body').outerHeight();
5626								flag = true;
5627
5628								setTimeout(function(){
5629									flag = false;
5630								}, 500);
5631							}
5632						});
5633					}
5634				});
5635
5636				// Side Header - Set header height on mobile
5637				if( $html.hasClass('side-header') ) {
5638					if( $window.width() < 992 ) {
5639						$header.css({
5640							height: $('.header-body .header-container').outerHeight() + (parseInt( $('.header-body').css('border-top-width') ) + parseInt( $('.header-body').css('border-bottom-width') ))
5641						});
5642					}
5643
5644					$(document).ready(function(){
5645						$window.afterResize(function(){
5646							if( $window.width() < 992 ) {
5647								$header.css({
5648									height: $('.header-body .header-container').outerHeight() + (parseInt( $('.header-body').css('border-top-width') ) + parseInt( $('.header-body').css('border-bottom-width') ))
5649								});
5650							} else {
5651								$header.css({
5652									height: ''
5653								});
5654							}
5655						});
5656					});
5657				}
5658
5659				// Anchors Position
5660				$('[data-hash]').each(function() {
5661
5662					var target = $(this).attr('href'),
5663						offset = ($(this).is("[data-hash-offset]") ? $(this).data('hash-offset') : 0);
5664
5665					if( target.indexOf('#') != -1 && $(target).get(0)) {
5666						$(this).on('click', function(e) {
5667							e.preventDefault();
5668
5669							if( !$(e.target).is('i') ) {
5670
5671								// Close Collapse if open
5672								$(this).parents('.collapse.show').collapse('hide');
5673
5674								// Close Side Header
5675								$hamburguerSideHeader.addClass('side-header-hide');
5676								$html.addClass('side-header-hide');
5677								
5678								$window.trigger('resize');
5679
5680								self.scrollToTarget(target, offset);
5681
5682								// Data Hash Trigger Click
5683								if( $(this).data('hash-trigger-click') ) {
5684
5685									var $clickTarget = $( $(this).data('hash-trigger-click') ),
5686										clickDelay = $(this).data('hash-trigger-click-delay') ? $(this).data('hash-trigger-click-delay') : 0;
5687
5688									if( $clickTarget.get(0) ) {
5689										setTimeout(function(){
5690											$clickTarget.trigger('click');
5691										}, clickDelay);
5692									}
5693
5694								}
5695								
5696							}
5697
5698							return;
5699						});
5700					}
5701
5702				});
5703
5704				// Floating
5705				if($('#header.header-floating-icons').get(0)) {
5706
5707					$('#header.header-floating-icons [data-hash]').off().each(function() {
5708
5709						var target = $(this).attr('href'),
5710							offset = ($(this).is("[data-hash-offset]") ? $(this).data('hash-offset') : 0);
5711
5712						if($(target).get(0)) {
5713							$(this).on('click', function(e) {
5714								e.preventDefault();
5715
5716									$('html, body').animate({
5717										scrollTop: $(target).offset().top - offset
5718									}, 600, 'easeOutQuad', function() {
5719
5720									});
5721
5722								return;
5723							});
5724						}
5725
5726					});
5727
5728				}
5729
5730				// Side Panel Toggle
5731				if( $('.side-panel-toggle').get(0) ) {
5732					var init_html_class = $('html').attr('class');
5733
5734					$('.side-panel-toggle').on('click', function(e){
5735						var extra_class = $(this).data('extra-class'),
5736							delay       = ( extra_class ) ? 100 : 0;
5737
5738						e.preventDefault();
5739
5740						if( $(this).hasClass('active') ) {
5741							$('html').removeClass('side-panel-open');
5742							$('.hamburguer-btn.side-panel-toggle:not(.side-panel-close)').removeClass('active');
5743							return false;
5744						}
5745
5746						if( extra_class ) {
5747							$('.side-panel-wrapper').css('transition','none');
5748							$('html')
5749								.removeClass()
5750								.addClass( init_html_class )
5751								.addClass( extra_class );
5752						}
5753
5754						setTimeout(function(){
5755							$('.side-panel-wrapper').css('transition','');
5756							$('html').toggleClass('side-panel-open');
5757						}, delay);
5758					});
5759
5760					$(document).on('click', function(e){
5761						if( !$(e.target).closest('.side-panel-wrapper').get(0) && !$(e.target).hasClass('side-panel-toggle') ) {
5762							$('.hamburguer-btn.side-panel-toggle:not(.side-panel-close)').removeClass('active');
5763							$('html').removeClass('side-panel-open');
5764						}
5765					});
5766				}
5767
5768				return this;
5769			},
5770
5771			scrollToTarget: function(target, offset) {
5772				var self = this;
5773
5774				$('body').addClass('scrolling');
5775
5776				$('html, body').animate({
5777					scrollTop: $(target).offset().top - offset
5778				}, self.options.scrollDelay, self.options.scrollAnimation, function() {
5779					$('body').removeClass('scrolling');
5780				});
5781
5782				return this;
5783
5784			}
5785
5786		}
5787
5788	});
5789
5790}).apply(this, [window.theme, jQuery]);
5791
5792
5793// Newsletter
5794(function(theme, $) {
5795
5796	theme = theme || {};
5797
5798	var initialized = false;
5799
5800	$.extend(theme, {
5801
5802		Newsletter: {
5803
5804			defaults: {
5805				wrapper: $('#newsletterForm')
5806			},
5807
5808			initialize: function($wrapper, opts) {
5809				if (initialized) {
5810					return this;
5811				}
5812
5813				initialized = true;
5814				this.$wrapper = ($wrapper || this.defaults.wrapper);
5815
5816				this
5817					.setOptions(opts)
5818					.build();
5819
5820				return this;
5821			},
5822
5823			setOptions: function(opts) {
5824				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
5825
5826				return this;
5827			},
5828
5829			build: function() {
5830				if (!($.isFunction($.fn.validate))) {
5831					return this;
5832				}
5833
5834				var self = this,
5835					$email = self.$wrapper.find('#newsletterEmail'),
5836					$success = $('#newsletterSuccess'),
5837					$error = $('#newsletterError');
5838
5839				self.$wrapper.validate({
5840					submitHandler: function(form) {
5841
5842						$.ajax({
5843							type: 'POST',
5844							url: self.$wrapper.attr('action'),
5845							data: {
5846								'email': $email.val()
5847							},
5848							dataType: 'json',
5849							success: function(data) {
5850								if (data.response == 'success') {
5851
5852									$success.removeClass('d-none');
5853									$error.addClass('d-none');
5854
5855									$email
5856										.val('')
5857										.blur()
5858										.closest('.control-group')
5859										.removeClass('success')
5860										.removeClass('error');
5861
5862								} else {
5863
5864									$error.html(data.message);
5865									$error.removeClass('d-none');
5866									$success.addClass('d-none');
5867
5868									$email
5869										.blur()
5870										.closest('.control-group')
5871										.removeClass('success')
5872										.addClass('error');
5873
5874								}
5875							}
5876						});
5877
5878					},
5879					rules: {
5880						newsletterEmail: {
5881							required: true,
5882							email: true
5883						}
5884					},
5885					errorPlacement: function(error, element) {
5886
5887					}
5888				});
5889
5890				return this;
5891			}
5892
5893		}
5894
5895	});
5896
5897}).apply(this, [window.theme, jQuery]);
5898
5899// Search
5900(function(theme, $) {
5901
5902	theme = theme || {};
5903
5904	var initialized = false;
5905
5906	$.extend(theme, {
5907
5908		Search: {
5909
5910			defaults: {
5911				wrapper: $('#searchForm')
5912			},
5913
5914			initialize: function($wrapper, opts) {
5915				if (initialized) {
5916					return this;
5917				}
5918
5919				initialized = true;
5920				this.$wrapper = ($wrapper || this.defaults.wrapper);
5921
5922				this
5923					.setOptions(opts)
5924					.build();
5925
5926				return this;
5927			},
5928
5929			setOptions: function(opts) {
5930				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
5931
5932				return this;
5933			},
5934
5935			build: function() {
5936				if (!($.isFunction($.fn.validate))) {
5937					return this;
5938				}
5939
5940				this.$wrapper.validate({
5941					errorPlacement: function(error, element) {}
5942				});
5943
5944				// Search Reveal
5945				$('.header-nav-features-search-reveal').each(function() {
5946
5947					var $el = $(this)
5948						$header = $('#header'),
5949						$html = $('htmnl');
5950
5951					$el.find('.header-nav-features-search-show-icon').on('click', function() {
5952						$el.addClass('show');
5953						$header.addClass('search-show');
5954						$html.addClass('search-show');
5955						$('#headerSearch').focus();
5956					});
5957
5958					$el.find('.header-nav-features-search-hide-icon').on('click', function() {
5959						$el.removeClass('show');
5960						$header.removeClass('search-show');
5961						$html.removeClass('search-show');
5962					});
5963
5964				});
5965
5966				return this;
5967			}
5968
5969		}
5970
5971	});
5972
5973}).apply(this, [window.theme, jQuery]);
5974
5975// Sticky Header
5976(function(theme, $) {
5977
5978	theme = theme || {};
5979
5980	var initialized = false;
5981
5982	$.extend(theme, {
5983
5984		StickyHeader: {
5985
5986			defaults: {
5987				wrapper: $('#header'),
5988				headerBody: $('#header .header-body'),
5989				stickyEnabled: true,
5990				stickyEnableOnBoxed: true,
5991				stickyEnableOnMobile: true,
5992				stickyStartAt: 0,
5993				stickyStartAtElement: false,
5994				stickySetTop: 0,
5995				stickyEffect: '',
5996				stickyHeaderContainerHeight: false,
5997				stickyChangeLogo: false,
5998				stickyChangeLogoWrapper: true
5999			},
6000
6001			initialize: function($wrapper, opts) {
6002				if (initialized) {
6003					return this;
6004				}
6005
6006				initialized = true;
6007				this.$wrapper = ($wrapper || this.defaults.wrapper);
6008
6009				this
6010					.setOptions(opts)
6011					.build()
6012					.events();
6013
6014				return this;
6015			},
6016
6017			setOptions: function(opts) {
6018				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
6019
6020				return this;
6021			},
6022
6023			build: function() {
6024				if (!this.options.stickyEnableOnBoxed && $('html').hasClass('boxed') || $('html').hasClass('side-header-hamburguer-sidebar') || !this.options.stickyEnabled) {
6025					return this;
6026				}
6027
6028				var self = this,
6029					$html = $('html'),
6030					$window = $(window),
6031					sideHeader = $html.hasClass('side-header'),
6032					initialHeaderTopHeight = self.options.wrapper.find('.header-top').outerHeight(),
6033					initialHeaderContainerHeight = self.options.wrapper.find('.header-container').outerHeight(),
6034					minHeight;
6035
6036				// HTML Classes
6037				$html.addClass('sticky-header-enabled');
6038
6039				if (parseInt(self.options.stickySetTop) < 0) {
6040					$html.addClass('sticky-header-negative');
6041				}
6042
6043				// Notice Top Bar First Load
6044				if( $('.notice-top-bar').get(0) ) {
6045					if (parseInt(self.options.stickySetTop) == 1 || self.options.stickyEffect == 'shrink') {
6046						$('.body').on('transitionend webkitTransitionEnd oTransitionEnd', function () {
6047						    setTimeout(function(){
6048								if( !$html.hasClass('sticky-header-active') ) {
6049								    self.options.headerBody.animate({
6050								    	top: $('.notice-top-bar').outerHeight()
6051								    }, 300, function(){
6052								    	if( $html.hasClass('sticky-header-active') ) {
6053								    		self.options.headerBody.css('top', 0);
6054								    	}
6055								    });
6056								}
6057						    }, 0);
6058						});
6059					}					
6060				}
6061
6062				// Set Start At
6063				if(self.options.stickyStartAtElement) {
6064
6065					var $stickyStartAtElement = $(self.options.stickyStartAtElement);
6066
6067					$(window).on('scroll resize', function() {
6068						self.options.stickyStartAt = $stickyStartAtElement.offset().top;
6069					});
6070
6071					$(window).trigger('resize');
6072				}
6073
6074				// Define Min Height value
6075				if( self.options.wrapper.find('.header-top').get(0) ) {
6076					minHeight = ( initialHeaderTopHeight + initialHeaderContainerHeight );
6077				} else {
6078					minHeight = initialHeaderContainerHeight;
6079				}
6080
6081				// Set Wrapper Min-Height
6082				if( !sideHeader ) {
6083					if( !$('.header-logo-sticky-change').get(0) ) {
6084						self.options.wrapper.css('height', self.options.headerBody.outerHeight());
6085					} else {
6086						$window.on('stickyChangeLogo.loaded', function(){
6087							self.options.wrapper.css('height', self.options.headerBody.outerHeight());
6088						});
6089					}
6090
6091					if( self.options.stickyEffect == 'shrink' ) {
6092						
6093						// Prevent wrong visualization of header when reload on middle of page
6094						$(document).ready(function(){
6095							if( $window.scrollTop() >= self.options.stickyStartAt ) {
6096								self.options.wrapper.find('.header-container').on('transitionend webkitTransitionEnd oTransitionEnd', function(){
6097									self.options.headerBody.css('position', 'fixed');
6098								});
6099							} else {
6100								self.options.headerBody.css('position', 'fixed');
6101							}
6102						});
6103
6104						self.options.wrapper.find('.header-container').css('height', initialHeaderContainerHeight);
6105						self.options.wrapper.find('.header-top').css('height', initialHeaderTopHeight);
6106					}
6107				}
6108
6109				// Sticky Header Container Height
6110				if( self.options.stickyHeaderContainerHeight ) {
6111					self.options.wrapper.find('.header-container').css('height', self.options.wrapper.find('.header-container').outerHeight());
6112				}
6113
6114				// Boxed
6115				if($html.hasClass('boxed') && self.options.stickyEffect == 'shrink') {
6116					if( (parseInt(self.options.stickyStartAt) == 0) && $window.width() > 991) {
6117						self.options.stickyStartAt = 30;
6118					}
6119
6120					// Set Header Body Position Absolute
6121					self.options.headerBody.css('position','absolute');
6122
6123					// Set position absolute because top margin from boxed layout
6124					$window.on('scroll', function(){
6125						if( $window.scrollTop() > $('.body').offset().top ) {
6126							self.options.headerBody.css({
6127								'position' : 'fixed',
6128								'top' : 0
6129							});								
6130						} else {
6131							self.options.headerBody.css({
6132								'position' : 'absolute',
6133								'top' : 0
6134							});
6135						}
6136					});
6137				}
6138
6139				// Check Sticky Header / Flags prevent multiple runs at same time
6140				var activate_flag   	 = true,
6141					deactivate_flag 	 = false,
6142					initialStickyStartAt = self.options.stickyStartAt;
6143
6144				self.checkStickyHeader = function() {
6145
6146					// Notice Top Bar
6147					var $noticeTopBar = $('.notice-top-bar');
6148					if ( $noticeTopBar.get(0) ) {
6149						self.options.stickyStartAt = ( $noticeTopBar.data('sticky-start-at') ) ? $noticeTopBar.data('sticky-start-at') : $('.notice-top-bar').outerHeight();
6150					} else {
6151						self.options.stickyStartAt = initialStickyStartAt;
6152					}
6153
6154					if( $window.width() > 991 && $html.hasClass('side-header') ) {
6155						$html.removeClass('sticky-header-active');
6156						activate_flag = true;
6157						return;
6158					}
6159
6160					if ($window.scrollTop() >= parseInt(self.options.stickyStartAt)) {
6161						if( activate_flag ) {
6162							self.activateStickyHeader();
6163							activate_flag = false;
6164							deactivate_flag = true;
6165						}
6166					} else {
6167						if( deactivate_flag ) {
6168							self.deactivateStickyHeader();
6169							deactivate_flag = false;
6170							activate_flag = true;
6171						}
6172					}
6173				};
6174				
6175				// Activate Sticky Header
6176				self.activateStickyHeader = function() {
6177
6178					if ($window.width() < 992) {
6179						if (!self.options.stickyEnableOnMobile) {
6180							self.deactivateStickyHeader();
6181							return;
6182						}
6183					} else {
6184						if (sideHeader) {
6185							self.deactivateStickyHeader();
6186							return;
6187						}
6188					}
6189
6190					$html.addClass('sticky-header-active');
6191
6192					// Sticky Effect - Reveal
6193					if( self.options.stickyEffect == 'reveal' ) {
6194
6195						self.options.headerBody.css('top','-' + self.options.stickyStartAt + 'px');
6196
6197						self.options.headerBody.animate({
6198							top: self.options.stickySetTop
6199						}, 400, function() {});
6200
6201					}
6202
6203					// Sticky Effect - Shrink
6204					if( self.options.stickyEffect == 'shrink' ) {
6205
6206						// If Header Top
6207						if( self.options.wrapper.find('.header-top').get(0) ) {
6208							self.options.wrapper.find('.header-top').css({
6209								height: 0,
6210								'min-height': 0,
6211								overflow: 'hidden'
6212							});
6213						}
6214
6215						// Header Container
6216						if( self.options.stickyHeaderContainerHeight ) {
6217							self.options.wrapper.find('.header-container').css({
6218								height: self.options.stickyHeaderContainerHeight,
6219								'min-height': 0
6220							});
6221						} else {
6222							self.options.wrapper.find('.header-container').css({
6223								height: (initialHeaderContainerHeight / 3) * 2, // two third of container height
6224								'min-height': 0
6225							});
6226
6227							var y = initialHeaderContainerHeight - ((initialHeaderContainerHeight / 3) * 2);
6228							$('.main').css({
6229								transform: 'translate3d(0, -'+ y +'px, 0)',
6230								transition: 'ease transform 300ms'
6231							}).addClass('has-sticky-header-transform');
6232
6233							if($html.hasClass('boxed')) {
6234								self.options.headerBody.css('position','fixed');
6235							}
6236						}
6237
6238					}
6239
6240					self.options.headerBody.css('top', self.options.stickySetTop);
6241
6242					if (self.options.stickyChangeLogo) {
6243						self.changeLogo(true);
6244					}
6245
6246					// Set Elements Style
6247					$('[data-sticky-header-style]').each(function() {
6248						var $el = $(this),
6249							css = theme.fn.getOptions($el.data('sticky-header-style-active')),
6250							opts = theme.fn.getOptions($el.data('sticky-header-style'));
6251
6252						if( $window.width() > opts.minResolution ) {
6253							$el.css(css);
6254						}
6255					});
6256
6257					$.event.trigger({
6258						type: 'stickyHeader.activate'
6259					});
6260				};
6261
6262				// Deactivate Sticky Header
6263				self.deactivateStickyHeader = function() {
6264
6265					$html.removeClass('sticky-header-active');
6266
6267					// Sticky Effect - Shrink
6268					if( self.options.stickyEffect == 'shrink' ) {
6269
6270						// Boxed Layout
6271						if( $html.hasClass('boxed') ) {
6272
6273							// Set Header Body Position Absolute
6274							self.options.headerBody.css('position','absolute');
6275
6276							if( $window.scrollTop() > $('.body').offset().top ) {
6277								// Set Header Body Position Fixed
6278								self.options.headerBody.css('position','fixed');								
6279							}
6280
6281						} else {
6282							// Set Header Body Position Fixed
6283							self.options.headerBody.css('position','fixed');
6284						}
6285
6286						// If Header Top
6287						if( self.options.wrapper.find('.header-top').get(0) ) {
6288							self.options.wrapper.find('.header-top').css({
6289								height: initialHeaderTopHeight,
6290								overflow: 'visible'
6291							});
6292						}
6293
6294						// Header Container
6295						self.options.wrapper.find('.header-container').css({
6296							height: initialHeaderContainerHeight
6297						});
6298
6299					}
6300
6301					self.options.headerBody.css('top', 0);
6302
6303					if (self.options.stickyChangeLogo) {
6304						self.changeLogo(false);
6305					}
6306
6307					// Set Elements Style
6308					$('[data-sticky-header-style]').each(function() {
6309						var $el = $(this),
6310							css = theme.fn.getOptions($el.data('sticky-header-style-deactive')),
6311							opts = theme.fn.getOptions($el.data('sticky-header-style'));
6312
6313						if( $window.width() > opts.minResolution ) {
6314							$el.css(css);
6315						}
6316					});
6317
6318					$.event.trigger({
6319						type: 'stickyHeader.deactivate'
6320					});
6321				};
6322
6323				// Always Sticky
6324				if (parseInt(self.options.stickyStartAt) <= 0) {
6325					self.activateStickyHeader();
6326				}
6327
6328				// Set Logo
6329				if (self.options.stickyChangeLogo) {
6330
6331					var $logoWrapper = self.options.wrapper.find('.header-logo'),
6332						$logo = $logoWrapper.find('img'),
6333						logoWidth = $logo.attr('width'),
6334						logoHeight = $logo.attr('height'),
6335						logoSmallTop = parseInt($logo.attr('data-sticky-top') ? $logo.attr('data-sticky-top') : 0),
6336						logoSmallWidth = parseInt($logo.attr('data-sticky-width') ? $logo.attr('data-sticky-width') : 'auto'),
6337						logoSmallHeight = parseInt($logo.attr('data-sticky-height') ? $logo.attr('data-sticky-height') : 'auto');
6338
6339					if (self.options.stickyChangeLogoWrapper) {
6340						$logoWrapper.css({
6341							'width': $logo.outerWidth(true),
6342							'height': $logo.outerHeight(true)
6343						});
6344					}
6345
6346					self.changeLogo = function(activate) {
6347						if(activate) {
6348							
6349							$logo.css({
6350								'top': logoSmallTop,
6351								'width': logoSmallWidth,
6352								'height': logoSmallHeight
6353							});
6354
6355						} else {
6356							
6357							$logo.css({
6358								'top': 0,
6359								'width': logoWidth,
6360								'height': logoHeight
6361							});
6362
6363						}
6364					}
6365
6366					$.event.trigger({
6367						type: 'stickyChangeLogo.loaded'
6368					});
6369
6370				}
6371
6372				// Side Header
6373				var headerBodyHeight,
6374					flag = false;
6375
6376				self.checkSideHeader = function() {
6377					if($window.width() < 992 && flag == false) {
6378						headerBodyHeight = self.options.headerBody.height();
6379						flag = true;
6380					}
6381
6382					if(self.options.stickyStartAt == 0 && sideHeader) {
6383						self.options.wrapper.css('min-height', 0);
6384					}
6385
6386					if(self.options.stickyStartAt > 0 && sideHeader && $window.width() < 992) {
6387						self.options.wrapper.css('min-height', headerBodyHeight);
6388					}
6389				}
6390
6391				return this;
6392			},
6393
6394			events: function() {
6395				var self = this;
6396
6397				if (!this.options.stickyEnableOnBoxed && $('body').hasClass('boxed') || $('html').hasClass('side-header-hamburguer-sidebar') || !this.options.stickyEnabled) {
6398					return this;
6399				}
6400
6401				if (!self.options.alwaysStickyEnabled) {
6402					$(window).on('scroll resize', function() {
6403						self.checkStickyHeader();
6404					});
6405				} else {
6406					self.activateStickyHeader();
6407				}
6408
6409				$(window).on('load resize', function(){
6410					self.checkSideHeader();
6411				});
6412
6413				return this;
6414			}
6415
6416		}
6417
6418	});
6419
6420}).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.