PageSourceSearch

https://masjidtaqwa.org/js/theme.js

js masjidtaqwa.org collected 2026-10-08 09:58:36 UTC 57,245 bytes, 2,878 lines download raw bytes

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