PageSourceSearch

https://www.irsrecfvg.eu/frontend/js/theme.js

js irsrecfvg.eu collected 2026-09-25 06:53:53 UTC 65,098 bytes, 3,308 lines download raw bytes

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