PageSourceSearch

https://wiedenmann-bestattungen.de/js/theme.js

js wiedenmann-bestattungen.de collected 2026-10-07 03:52:52 UTC 253,679 bytes, 9,509 lines download raw bytes

1/*
2Name: 			Theme Base
3Written by: 	Okler Themes - (http://www.okler.net)
4Theme Version:	13.0.0
5*/
6
7// Theme
8window.theme = {};
9
10// Theme Common Functions
11window.theme.fn = {
12
13	getOptions(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	execPluginFunction(functionName, context) {
36		const args = Array.prototype.slice.call(arguments, 2);
37		const namespaces = functionName.split(".");
38		const func = namespaces.pop();
39
40		for (let i = 0; i < namespaces.length; i++) {
41			context = context[namespaces[i]];
42		}
43
44		return context[func](...args);
45	},
46
47	intObs(selector, functionName, intObsOptions, alwaysObserve) {
48		const $el = document.querySelectorAll(selector);
49		let intersectionObserverOptions = {
50			rootMargin: '0px 0px 200px 0px'
51		};
52
53		if (Object.keys(intObsOptions).length) {
54			intersectionObserverOptions = $.extend(intersectionObserverOptions, intObsOptions);
55		}
56
57		const observer = new IntersectionObserver(entries => {
58            for (const entry of entries) {
59                if (entry.intersectionRatio > 0) {
60					if (typeof functionName === 'string') {
61						const func = Function('return ' + functionName)();
62					} else {
63						const callback = functionName;
64
65						callback.call($(entry.target));
66					}
67
68					// Unobserve
69					if (!alwaysObserve) {
70						observer.unobserve(entry.target);
71					}
72
73				}
74            }
75        }, intersectionObserverOptions);
76
77		$($el).each(function() {
78			observer.observe($(this)[0]);
79		});
80	},
81
82	intObsInit(selector, functionName) {
83		const $el = document.querySelectorAll(selector);
84		const intersectionObserverOptions = {
85			rootMargin: '200px'
86		};
87
88		const observer = new IntersectionObserver(entries => {
89            for (const entry of entries) {
90                if (entry.intersectionRatio > 0) {
91                    const $this = $(entry.target);
92                    let opts;
93
94                    const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
95                    if (pluginOptions)
96						opts = pluginOptions;
97
98                    theme.fn.execPluginFunction(functionName, $this, opts);
99
100                    // Unobserve
101                    observer.unobserve(entry.target);
102                }
103            }
104        }, intersectionObserverOptions);
105
106		$($el).each(function() {
107			observer.observe($(this)[0]);
108		});
109	},
110
111	dynIntObsInit(selector, functionName, pluginDefaults) {
112		const $el = document.querySelectorAll(selector);
113
114		$($el).each(function() {
115            const $this = $(this);
116            let opts;
117
118            const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
119            if (pluginOptions)
120				opts = pluginOptions;
121
122            const mergedPluginDefaults = theme.fn.mergeOptions(pluginDefaults, opts);
123
124            const intersectionObserverOptions = {
125				rootMargin: theme.fn.getRootMargin(functionName, mergedPluginDefaults),
126				threshold: 0
127			};
128
129            if (!mergedPluginDefaults.forceInit) {
130
131				const observer = new IntersectionObserver(entries => {
132                    for (const entry of entries) {
133                        if (entry.intersectionRatio > 0) {
134							theme.fn.execPluginFunction(functionName, $this, mergedPluginDefaults);
135
136							// Unobserve
137							observer.unobserve(entry.target);
138						}
139                    }
140                }, intersectionObserverOptions);
141
142				observer.observe($this[0]);
143
144			} else {
145				theme.fn.execPluginFunction(functionName, $this, mergedPluginDefaults);
146			}
147        });
148	},
149
150	getRootMargin(plugin, {accY}) {
151		switch (plugin) {
152			case 'themePluginCounter':
153				return accY ? `0px 0px ${accY}px 0px` : '0px 0px 200px 0px';
154				break;
155
156			case 'themePluginAnimate':
157				return accY ? `0px 0px ${accY}px 0px` : '0px 0px 200px 0px';
158				break;
159
160			case 'themePluginIcon':
161				return accY ? `0px 0px ${accY}px 0px` : '0px 0px 200px 0px';
162				break;
163
164			case 'themePluginRandomImages':
165				return accY ? `0px 0px ${accY}px 0px` : '0px 0px 200px 0px';
166				break;
167
168			default:
169				return '0px 0px 200px 0px';
170				break;
171		}
172	},
173
174	mergeOptions(obj1, obj2) {
175		const obj3 = {};
176
177		for (var attrname in obj1) {
178			obj3[attrname] = obj1[attrname];
179		}
180		for (var attrname in obj2) {
181			obj3[attrname] = obj2[attrname];
182		}
183
184		return obj3;
185	},
186
187	execOnceTroughEvent($el, event, callback) {
188		const self = this, dataName = self.formatDataName(event);
189
190		$($el).on(event, function() {
191			if (!$(this).data(dataName)) {
192
193				// Exec Callback Function
194				callback.call($(this));
195
196				// Add data name 
197				$(this).data(dataName, true);
198
199				// Unbind event
200				$(this).off(event);
201			}
202		});
203
204		return this;
205	},
206
207	execOnceTroughWindowEvent($el, event, callback) {
208		const self = this, dataName = self.formatDataName(event);
209
210		$($el).on(event, function() {
211			if (!$(this).data(dataName)) {
212
213				// Exec Callback Function
214				callback();
215
216				// Add data name 
217				$(this).data(dataName, true);
218
219				// Unbind event
220				$(this).off(event);
221			}
222		});
223
224		return this;
225	},
226
227	formatDataName(name) {
228		name = name.replace('.', '');
229		return name;
230	},
231
232	isElementInView($el) {
233		const rect = $el[0].getBoundingClientRect();
234
235		return (
236			rect.top <= (window.innerHeight / 3)
237		);
238	},
239
240	getScripts(arr, path) {
241		const _arr = $.map(arr, scr => $.getScript((path || "") + scr));
242
243		_arr.push($.Deferred(({resolve}) => {
244			$(resolve);
245		}));
246
247		return $.when(..._arr);
248	},
249
250	showErrorMessage(title, content) {
251
252		if ($('html').hasClass('disable-local-warning')) {
253			return;
254		}
255
256		$('.modalThemeErrorMessage').remove();
257		$('body').append('<div class="modal fade" id="modalThemeErrorMessage"><div class="modal-dialog modal-dialog-centered"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">' + title + '</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><div class="modal-body">' + content + '</div><div class="modal-footer"><button type="button" class="btn btn-primary" data-bs-dismiss="modal">Close</button></div></div></div></div>');
258
259		var modalThemeErrorMessage = document.getElementById('modalThemeErrorMessage');
260		var modalThemeErrorMessage = bootstrap.Modal.getOrCreateInstance(modalThemeErrorMessage);
261		modalThemeErrorMessage.show();
262
263	}
264
265};
266
267(((theme = {}, $) => {
268	/*
269	Local Environment Warning
270	*/
271	try {
272		if ("file://" === location.origin) {
273			if ($('[data-icon]').length || $('iframe').length) {
274
275				theme.fn.showErrorMessage('Local Environment Warning', 'SVG Objects, Icons, YouTube and Vimeo Videos might not show correctly on local environment. For better result, please preview on a server.<br><br><a target="_blank" href="https://www.okler.net/forums/topic/how-to-disable-local-environment-warning/" class="fw-semibold"><i class="fa-solid fa-link"></i> How to Disable Local Environment Warning</a>');
276
277			}
278		}
279	} catch (e) {}
280
281	/*
282	Browser Selector
283	*/
284	$.extend({
285
286		browserSelector() {
287
288			// jQuery.browser.mobile (http://detectmobilebrowser.com/)
289			(a => {(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera);
290
291			// Touch
292			const hasTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;
293
294			const u = navigator.userAgent, ua = u.toLowerCase(), is = t => ua.includes(t), g = 'gecko', w = 'webkit', s = 'safari', o = 'opera', h = document.documentElement, b = [(!(/opera|webtv/i.test(ua)) && /msie\s(\d)/.test(ua)) ? (`ie ie${parseFloat(navigator.appVersion.split("MSIE")[1])}`) : is('firefox/2') ? `${g} ff2` : is('firefox/3.5') ? `${g} ff3 ff3_5` : is('firefox/3') ? `${g} ff3` : is('gecko/') ? g : is('opera') ? o + (/version\/(\d+)/.test(ua) ? ` ${o}${RegExp.jQuery1}` : (/opera(\s|\/)(\d+)/.test(ua) ? ` ${o}${RegExp.jQuery2}` : '')) : is('konqueror') ? 'konqueror' : is('chrome') ? `${w} chrome` : is('iron') ? `${w} iron` : is('applewebkit/') ? `${w} ${s}${/version\/(\d+)/.test(ua) ? ` ${s}${RegExp.jQuery1}` : ''}` : is('mozilla/') ? g : '', is('j2me') ? 'mobile' : is('iphone') ? 'iphone' : is('ipod') ? 'ipod' : is('mac') ? 'mac' : is('darwin') ? 'mac' : is('webtv') ? 'webtv' : is('win') ? 'win' : is('freebsd') ? 'freebsd' : (is('x11') || is('linux')) ? 'linux' : '', 'js'];
295
296			c = b.join(' ');
297
298			if ($.browser.mobile) {
299				c += ' mobile';
300			}
301
302			if (hasTouch) {
303				c += ' touch';
304			}
305
306			h.className += ` ${c}`;
307
308			// Edge Detect
309			const isEdge = /Edge/.test(navigator.userAgent);
310
311			if(isEdge) {
312				$('html').removeClass('chrome').addClass('edge');
313			}
314
315			// Dark and Boxed Compatibility
316			if($('body').hasClass('dark')) {
317				$('html').addClass('dark');
318			}
319
320			if($('body').hasClass('boxed')) {
321				$('html').addClass('boxed');
322			}
323
324		}
325
326	});
327
328	$.browserSelector();
329
330	/*
331	Browser Workarounds
332	*/
333	if (/iPad|iPhone|iPod/.test(navigator.platform)) {
334
335		// iPad/Iphone/iPod Hover Workaround
336		$(document).ready($ => {
337			$('.thumb-info').attr('onclick', 'return true');
338		});
339	}
340
341	/*
342	Lazy Load Bacground Images
343	*/
344
345	// Check for IntersectionObserver support
346	if ('IntersectionObserver' in window) {
347		document.addEventListener("DOMContentLoaded", function() {
348
349			function handleIntersection(entries) {
350				entries.map((entry) => {
351					if (entry.isIntersecting) {
352						// Item has crossed our observation
353						// threshold - load src from data-src
354						entry.target.style.backgroundImage = "url('" + entry.target.dataset.bgSrc + "')";
355						// Job done for this item - no need to watch it!
356						observer.unobserve(entry.target);
357					}
358				});
359			}
360
361			const lazyLoadElements = document.querySelectorAll('.lazyload');
362			const observer = new IntersectionObserver(
363				handleIntersection, {
364					rootMargin: "100px"
365				}
366			);
367			lazyLoadElements.forEach(lazyLoadEl => observer.observe(lazyLoadEl));
368		});
369	} else {
370		// No interaction support? Load all background images automatically
371		const lazyLoadElements = document.querySelectorAll('.lazyload');
372		lazyLoadElements.forEach(lazyLoadEl => {
373			lazyLoadEl.style.backgroundImage = "url('" + lazyLoadEl.dataset.bgSrc + "')";
374		});
375	}
376
377	/*
378	Tabs
379	*/
380	if( $('a[data-bs-toggle="tab"]').length ) {
381		$('a[data-bs-toggle="tab"]').on('shown.bs.tab', function({target}) {
382			const $tabPane = $($(target).attr('href'));
383
384			// Carousel Refresh
385			if($tabPane.length) {
386				$tabPane.find('.owl-carousel').trigger('refresh.owl.carousel');
387			}
388
389			// Change Active Class
390			$(this).parents('.nav-tabs').find('.active').removeClass('active');
391			$(this).addClass('active').parent().addClass('active');
392		});	
393
394		if( window.location.hash ) {
395			$(window).on('load', () => {
396				if( window.location.hash !== '*' && $( window.location.hash ).get(0) ) {
397					new bootstrap.Tab( $('a.nav-link[href="'+ window.location.hash +'"]:not([data-hash])')[0] ).show();
398				}
399			});
400		}
401	}
402
403	/*
404	On Load Scroll
405	*/
406	if( !$('html').hasClass('disable-onload-scroll') && window.location.hash && !['#*'].includes( window.location.hash ) ) {
407
408		window.scrollTo(0, 0);
409
410		$(window).on('load', () => {
411			setTimeout(() => {
412				const target = window.location.hash;
413				let offset = ( $(window).width() < 768 ) ? 180 : 90;
414
415				if (!$(target).length) {
416					return;
417				}
418
419				if ( $("a[href$='" + window.location.hash + "']").is('[data-hash-offset]') ) {
420					offset = parseInt( $("a[href$='" + window.location.hash + "']").first().attr('data-hash-offset') );
421				} else if ( $("html").is('[data-hash-offset]') ) {
422					offset = parseInt( $("html").attr('data-hash-offset') );
423				}
424
425				if (isNaN(offset)) {
426					offset = 0;
427				}
428
429				$('body').addClass('scrolling');
430
431				$('html, body').animate({
432					scrollTop: $(target).offset().top - offset
433				}, 600, 'easeOutQuad', () => {
434					$('body').removeClass('scrolling');
435				});
436			}, 1);
437		});
438	}
439
440	/*
441	* Text Rotator
442	*/
443	$.fn.extend({
444		textRotator(options) {
445
446			const defaults = {
447				fadeSpeed: 500,
448				pauseSpeed: 100,
449				child: null
450			};
451
452			var options = $.extend(defaults, options);
453
454			return this.each(function() {
455				const o = options;
456				const obj = $(this);
457				const items = $(obj.children(), obj);
458				items.each(function() {
459					$(this).hide();
460				})
461				if (!o.child) {
462					var next = $(obj).children(':first');
463				} else {
464					var next = o.child;
465				}
466				$(next).fadeIn(o.fadeSpeed, () => {
467					$(next).delay(o.pauseSpeed).fadeOut(o.fadeSpeed, function() {
468						let next = $(this).next();
469						if (next.length == 0) {
470							next = $(obj).children(':first');
471						}
472						$(obj).textRotator({
473							child: next,
474							fadeSpeed: o.fadeSpeed,
475							pauseSpeed: o.pauseSpeed
476						});
477					})
478				});
479			});
480		}
481	});
482
483	/*
484	* Notice Top bar
485	*/
486	const $noticeTopBar = {
487		$wrapper: $('.notice-top-bar'),
488		$closeBtn: $('.notice-top-bar-close'),
489		$header: $('#header'),
490		$body: $('.body'),
491		init() {
492			const self = this;
493
494			if( !$.cookie('portoNoticeTopBarClose') ) {
495				self
496					.build()
497					.events();
498			} else {
499				self.$wrapper.parent().prepend( '<!-- Notice Top Bar removed by cookie -->' );
500				self.$wrapper.remove();
501			}
502
503			return this;
504		},
505		build() {
506			const self = this;
507
508			$(window).on('load', () => {
509				setTimeout(() => {
510					self.$body.css({
511						'margin-top': self.$wrapper.outerHeight(),
512						'transition': 'ease margin 300ms'
513					});
514
515					$('#noticeTopBarContent').textRotator({
516						fadeSpeed: 500,
517						pauseSpeed: 5000
518					});
519
520					if( ['absolute', 'fixed'].includes( self.$header.css('position') ) ) {
521						self.$header.css({
522							'top': self.$wrapper.outerHeight(),
523							'transition': 'ease top 300ms'
524						});
525					}
526
527					$(window).trigger('notice.top.bar.opened');
528
529				}, 1000);
530			});
531
532			return this;
533		},
534		events() {
535			const self = this;
536
537			self.$closeBtn.on('click', e => {
538				e.preventDefault();
539
540				self.$body.animate({
541					'margin-top': 0,
542				}, 300, () => {
543					self.$wrapper.remove();
544					self.saveCookie();
545				});
546
547				if( ['absolute', 'fixed'].includes( self.$header.css('position') ) ) {
548					self.$header.animate({
549						top: 0
550					}, 300);
551				}
552
553				// When header has shrink effect
554				if( self.$header.hasClass('header-effect-shrink') ) {
555					self.$header.find('.header-body').animate({
556						top: 0
557					}, 300);
558				}
559
560				$(window).trigger('notice.top.bar.closed');
561			});
562
563			return this;
564		},
565		checkCookie() {
566			const self = this;
567
568			if( $.cookie('portoNoticeTopBarClose') ) {
569				return true;
570			} else {
571				return false;
572			}
573
574			return this;
575		},
576		saveCookie() {
577			const self = this;
578
579			$.cookie('portoNoticeTopBarClose', true);
580
581			return this;
582		}
583	};
584
585	if( $('.notice-top-bar').length ) {
586		$noticeTopBar.init();
587	}
588
589	/*
590	* Image Hotspots
591	*/
592	if( $('.image-hotspot').length ) {
593		$('.image-hotspot')
594			.append('<span class="ring"></span>')
595			.append('<span class="circle"></span>');
596	}
597
598	/*
599	* Reading Progress
600	*/
601	if( $('.progress-reading').length ) {
602
603		function updateScrollProgress() {
604			const pixels = $(document).scrollTop();
605				pageHeight = $(document).height() - $(window).height()
606				progress = 100 * pixels / pageHeight;
607
608			$('.progress-reading .progress-bar').width(parseInt(progress) + "%");
609		}
610
611		$(document).on('scroll ready', () => {
612			updateScrollProgress();
613		});
614
615		$(document).ready(() => {
616			$(window).afterResize(() => {
617				updateScrollProgress();
618			});
619		});
620
621	}
622
623	/*
624	* Page Transition
625	*/
626	if( $('body[data-plugin-page-transition]').length ) {
627		
628		let link_click = false;
629
630		$(document).on('click', 'a', function(e){
631			link_click = $(this);
632		});
633
634		$(window).on("beforeunload", e => {
635			if( typeof link_click === 'object' ) {
636				const href = link_click.attr('href');
637
638				if( href.indexOf('mailto:') != 0 && href.indexOf('tel:') != 0 && !link_click.data('rm-from-transition') ) {
639					$('body').addClass('page-transition-active');
640				}
641			}
642		});
643
644		$(window).on("pageshow", ({persisted, originalEvent}) => {
645			if( persisted || originalEvent.persisted) {
646				if( $('html').hasClass('safari') ) {
647					window.location.reload();
648				}
649				
650				$('body').removeClass('page-transition-active');
651			}
652		});
653	}
654
655	/*
656	* Clone Element
657	*/
658	if( $('[data-clone-element]').length ) {
659
660		$('[data-clone-element]').each(function() {
661
662			const $el = $(this), content = $el.html(), qty = $el.attr('data-clone-element');
663
664			for (let i = 0; i < qty; i++) {
665				$el.html($el.html() + content);
666			}
667
668		});
669
670	}
671
672	if( $('[data-clone-element-to]').length ) {
673
674		$('[data-clone-element-to]').each(function() {
675
676			const $el = $(this);
677			const content = $el.html();
678			const $to = $($el.attr('data-clone-element-to'));
679
680			$to.html($to.html() + content);
681
682		});
683
684	}
685
686	/*
687	* Thumb Info Floating Caption
688	*/
689	$('.thumb-info-floating-caption').each(function() {
690
691		$(this)
692			.addClass('thumb-info-floating-element-wrapper')
693			.append( '<span class="thumb-info-floating-element thumb-info-floating-caption-title d-none">'+ $(this).data('title') +'</span>' );
694
695		if( $(this).data('type') ) {
696			$('.thumb-info-floating-caption-title', $(this))
697				.append( '<div class="thumb-info-floating-caption-type">'+ $(this).data('type') +'</div>' )
698				.css({
699					'padding-bottom' : 22
700				});
701		}
702
703		if( $(this).hasClass('thumb-info-floating-caption-clean') ) {
704			$('.thumb-info-floating-element', $(this)).addClass('bg-transparent');
705		}
706
707	});
708
709	/*
710	* Thumb Info Floating Element
711	*/
712	if( $('.thumb-info-floating-element-wrapper').length ) {
713
714		if (typeof gsap !== 'undefined') {
715
716			$('.thumb-info-floating-element-wrapper').on('mouseenter', function({clientX, clientY}) {
717				
718				if(!$(this).data('offset')) {
719					$(this).data('offset', 0);
720				}
721
722				const offset = parseInt($(this).data('offset'));
723
724				$('.thumb-info-floating-element-clone').remove();
725
726				$('.thumb-info-floating-element', $(this)).clone().addClass('thumb-info-floating-element-clone p-fixed p-events-none').attr('style', 'transform: scale(0.1);').removeClass('d-none').appendTo('body');
727
728				$('.thumb-info-floating-element-clone').css({
729					left: clientX + (offset),
730					top: clientY + (offset)
731				}).fadeIn(300);
732
733				gsap.to('.thumb-info-floating-element-clone', 0.5, {
734					css: {
735						scaleX: 1,
736						scaleY: 1
737					}
738				});
739
740				$(document).off('mousemove').on('mousemove', ({clientX, clientY}) => {
741
742					gsap.to('.thumb-info-floating-element-clone', 0.5, {
743						css: {
744							left: clientX + (offset),
745							top: clientY + (offset)
746						}
747					});
748
749				});
750
751			}).on('mouseout', () => {
752
753				gsap.to('.thumb-info-floating-element-clone', 0.5, {
754					css: {
755						scaleX: 0.5,
756						scaleY: 0.5,
757						opacity: 0
758					}
759				});
760
761			});
762
763		} else {
764			theme.fn.showErrorMessage('Failed to Load File', 'Failed to load: GSAP - Include the following file(s): (vendor/gsap/gsap.min.js)');
765		}
766
767	}
768
769	/*
770	* Thumb Info Direction Aware
771	*/
772	$(window).on('load', () => {
773		$('.thumb-info-wrapper-direction-aware').each( function() {
774			$(this).hoverdir({
775				speed : 300,
776				easing : 'ease',
777				hoverDelay : 0,
778				inverse : false,
779				hoverElem: '.thumb-info-wrapper-overlay'
780			});
781		});
782	});
783
784	/*
785	* Thumb Info Container Full
786	*/
787	$('.thumb-info-container-full-img').each(function() {
788
789		const $container = $(this);
790
791		$('[data-full-width-img-src]', $container).each(function() {
792			const uniqueId = 'img' + Math.floor(Math.random() * 10000);
793			$(this).attr('data-rel', uniqueId);
794
795			$container.append('<div style="background-image: url(' + $(this).attr('data-full-width-img-src') + ');" id="' + uniqueId + '" class="thumb-info-container-full-img-large opacity-0"></div>');
796		});
797
798		$('.thumb-info', $container).on('mouseenter', function(e){
799			$('.thumb-info-container-full-img-large').removeClass('active');
800			$('#' + $(this).attr('data-rel')).addClass('active');
801		});
802
803	});
804
805	/*
806	* Toggle Text Click
807	*/
808	$('[data-toggle-text-click]').on('click', function () {
809		$(this).text(function(i, text){
810			return text === $(this).attr('data-toggle-text-click') ? $(this).attr('data-toggle-text-click-alt') : $(this).attr('data-toggle-text-click');
811		});
812	});
813
814	/*
815	* Toggle Class
816	*/
817	$('[data-toggle-class]').on('click', function (e) {
818		e.preventDefault();
819
820		$(this).toggleClass( $(this).data('toggle-class') );
821	});
822
823	/*
824	* Shape Divider Aspect Ratio
825	*/
826	if( $('.shape-divider').length ) {
827		aspectRatioSVG();
828		$(window).on('resize', () => {
829			aspectRatioSVG();
830		});
831	}
832
833	/*
834	* Shape Divider Animated
835	*/
836	if( $('.shape-divider-horizontal-animation').length ) {
837		theme.fn.intObs('.shape-divider-horizontal-animation', function(){
838			for( let i = 0; i <= 1; i++ ) {
839				const svgClone = $(this).find('svg:nth-child(1)').clone();
840
841				$(this).append( svgClone )
842			}
843
844			$(this).addClass('start');
845		}, {});
846	}
847
848	/*
849	* Shape Divider - SVG Aspect Ratio
850	*/
851	function aspectRatioSVG() {
852		if( $(window).width() < 1950 ) {
853			$('.shape-divider svg[preserveAspectRatio]').each(function(){
854				if( !$(this).parent().hasClass('shape-divider-horizontal-animation') ) {
855					$(this).attr('preserveAspectRatio', 'xMinYMin');
856				} else {
857					$(this).attr('preserveAspectRatio', 'none');
858				}
859			});
860		} else {
861			$('.shape-divider svg[preserveAspectRatio]').each(function(){
862				$(this).attr('preserveAspectRatio', 'none');
863			});
864		}
865	}
866
867	/*
868	* Content Switcher
869	*/
870	$('[data-content-switcher]').on('change', function(e, v) {
871		const switcherRel = ($(this).is(':checked') ? '1' : '2' ), switcherId = $(this).attr('data-content-switcher-content-id');
872
873		$('[data-content-switcher-id=' + switcherId + ']').addClass('initialized').removeClass('active');
874
875		const $activeEl = $('[data-content-switcher-id=' + switcherId + '][data-content-switcher-rel=' + switcherRel + ']');
876
877		$activeEl.addClass('active');
878
879		$activeEl.parent().css('height', $activeEl.height());
880	});
881
882	$('[data-content-switcher]').trigger('change');
883
884	/*
885	* Dynamic Height
886	*/
887	const $window = $(window);
888	$window.on('resize dynamic.height.resize', () => {
889		$('[data-dynamic-height]').each(function(){
890			const $this = $(this), values = JSON.parse($this.data('dynamic-height').replace(/'/g,'"').replace(';',''));
891
892			// XS
893			if( $window.width() < 576 ) {
894				$this.height( values[4] );
895			}
896
897			// SM
898			if( $window.width() > 575 && $window.width() < 768 ) {
899				$this.height( values[3] );
900			}
901
902			// MD
903			if( $window.width() > 767 && $window.width() < 992 ) {
904				$this.height( values[2] );
905			}
906
907			// LG
908			if( $window.width() > 991 && $window.width() < 1200 ) {
909				$this.height( values[1] );
910			}
911
912			// XS
913			if( $window.width() > 1199 ) {
914				$this.height( values[0] );
915			}
916		});
917	});
918
919	// Mobile First Load
920	if( $window.width() < 992 ) {
921		$window.trigger('dynamic.height.resize');
922	}
923
924	/*
925	* Video - Trigger Play
926	*/
927	if( $('[data-trigger-play-video]').length ) {
928		theme.fn.execOnceTroughEvent( '[data-trigger-play-video]', 'mouseover.trigger.play.video', function(){
929			const $video = $( $(this).data('trigger-play-video') );
930
931			$(this).on('click', function(e){
932				e.preventDefault();
933
934				if( $(this).data('trigger-play-video-remove') == 'yes' ) {
935					$(this).animate({
936						opacity: 0
937					}, 300, function(){
938						$video[0].play();
939
940						$(this).remove();
941					});
942				} else {
943					setTimeout(() => {
944						$video[0].play();
945					},300);
946				}
947			});
948		});
949	}
950
951	/*
952	* Video - Auto Play
953	*/
954	if( $('video[data-auto-play]').length ) {
955		$(window).on('load', () => {
956			$('video[data-auto-play]').each(function(){
957				const $video = $(this);
958
959				setTimeout(() => {
960					if( $( '#' + $video.attr('id') ).length ) {
961						if( $( '[data-trigger-play-video="#' + $video.attr('id') + '"]' ).data('trigger-play-video-remove') == 'yes' ) {
962							$( '[data-trigger-play-video="#' + $video.attr('id') + '"]' ).animate({
963								opacity: 0
964							}, 300, () => {
965								$video[0].play();
966
967								$( '[data-trigger-play-video="#' + $video.attr('id') + '"]' ).remove();
968							});
969						} else {
970							setTimeout(() => {
971								$video[0].play();
972							},300);
973						}
974					}
975				}, 100);
976
977			});
978		});
979	}
980
981	/*
982	* Remove min height after the load of page
983	*/
984	if( $('[data-remove-min-height]').length ) {
985		$(window).on('load', () => {
986			$('[data-remove-min-height]').each(function(){
987				$(this).css({
988					'min-height': 0
989				});
990			});
991		});
992	}
993
994	/*
995	* Title Border
996	*/
997	if($('[data-title-border]').length) {
998
999		const $pageHeaderTitleBorder = $('<span class="page-header-title-border"></span>'), $pageHeaderTitle = $('[data-title-border]'), $window = $(window);
1000
1001		$pageHeaderTitle.before($pageHeaderTitleBorder);
1002
1003		const setPageHeaderTitleBorderWidth = () => {
1004			$pageHeaderTitleBorder.width($pageHeaderTitle.width());
1005		};
1006
1007		$window.afterResize(() => {
1008			setPageHeaderTitleBorderWidth();
1009		});
1010
1011		setPageHeaderTitleBorderWidth();
1012
1013		$pageHeaderTitleBorder.addClass('visible');
1014	}
1015
1016	/*
1017	* Footer Reveal
1018	*/
1019	($ => {
1020		const $footerReveal = {
1021			$wrapper: $('.footer-reveal'),
1022			init() {
1023				const self = this;
1024
1025				self.build();
1026				self.events();
1027			},
1028			build() {
1029				const self = this, footer_height = self.$wrapper.outerHeight(true), window_height = ( $(window).height() - $('.header-body').height() );
1030
1031				if( footer_height > window_height ) {
1032					$('#footer').removeClass('footer-reveal');
1033					$('body').css('margin-bottom', 0);
1034				} else {
1035					$('#footer').addClass('footer-reveal');
1036					$('body').css('margin-bottom', footer_height);
1037				}
1038
1039			},
1040			events() {
1041				const self = this, $window = $(window);
1042
1043				$window.on('load', () => {
1044					$window.afterResize(() => {
1045						self.build();
1046					});
1047				});
1048			}
1049		};
1050
1051		if( $('.footer-reveal').length ) {
1052			$footerReveal.init();
1053		}
1054	})(jQuery);
1055
1056	/*
1057	* Re-Init Plugin
1058	*/
1059	if( $('[data-reinit-plugin]').length ) {
1060		$('[data-reinit-plugin]').on('click', function(e) {
1061			e.preventDefault();
1062
1063			const pluginInstance = $(this).data('reinit-plugin'), pluginFunction = $(this).data('reinit-plugin-function'), pluginElement  = $(this).data('reinit-plugin-element'), pluginOptions  = theme.fn.getOptions($(this).data('reinit-plugin-options'));
1064
1065			$( pluginElement ).data( pluginInstance ).destroy();
1066
1067			setTimeout(() => {
1068				theme.fn.execPluginFunction(pluginFunction, $( pluginElement ), pluginOptions);	
1069			}, 1000);
1070
1071		});
1072	}
1073
1074	/*
1075	* Simple Copy To Clipboard
1076	*/
1077	if( $('[data-copy-to-clipboard]').length ) {
1078		theme.fn.intObs( '[data-copy-to-clipboard]', function(){
1079			const $this = $(this);
1080
1081			$this.wrap( '<div class="copy-to-clipboard-wrapper position-relative"></div>' );
1082
1083			const $copyButton = $('<a href="#" class="btn btn-primary btn-px-2 py-1 text-0 position-absolute top-8 right-8">COPY</a>');
1084			$this.parent().prepend( $copyButton );
1085
1086			$copyButton.on('click', function(e){
1087				e.preventDefault();
1088
1089				const $btn       = $(this), $temp = $('<textarea class="d-block opacity-0" style="height: 0;">');
1090
1091				$btn.parent().append( $temp );
1092
1093				$temp.val( $this.text() );
1094					
1095				$temp[0].select();
1096				$temp[0].setSelectionRange(0, 99999);
1097
1098				document.execCommand("copy");
1099
1100				$btn.addClass('copied');
1101				setTimeout(() => {
1102					$btn.removeClass('copied');
1103				}, 1000);
1104
1105				$temp.remove();
1106			});
1107		}, {
1108			rootMargin: '0px 0px 0px 0px'
1109		} );
1110	}
1111
1112	/*
1113	* Marquee
1114	*/
1115	if( $('.marquee').length && $.isFunction($.fn.marquee) ) {
1116		$('.marquee').marquee({
1117			duration: 5000,
1118			gap: 0,
1119			delayBeforeStart: 0,
1120			direction: 'left',
1121			duplicated: true
1122		});
1123	}
1124
1125	/*
1126	* Style Switcher Open Loader Button
1127	*/
1128	if( $('.style-switcher-open-loader').length ) {
1129
1130		const urlParams = new URLSearchParams(window.location.search);
1131
1132		let hideStyleSwitcherAfterShow = false;
1133
1134		$('.style-switcher-open-loader').on('click', function(e){
1135			e.preventDefault();
1136
1137			const $this = $(this);
1138
1139			// Add Spinner to icon
1140			$this.addClass('style-switcher-open-loader-loading');
1141
1142			const basePath = $(this).data('base-path'), skinSrc = $(this).data('skin-src');
1143
1144			const script1 = document.createElement("script");
1145			script1.src = basePath + "master/style-switcher/style.switcher.localstorage.js";
1146
1147			const script2 = document.createElement("script");
1148			script2.src = basePath + "master/style-switcher/style.switcher.js";
1149			script2.id = "styleSwitcherScript";
1150			script2.setAttribute('data-base-path', basePath);
1151			script2.setAttribute('data-skin-src', skinSrc);
1152
1153			script2.onload = () => {
1154				setTimeout(() => {
1155					// Trigger a click to open the style switcher sidebar
1156					function checkIfReady() {
1157						if( !$('.style-switcher-open').length ) {
1158							window.setTimeout(checkIfReady, 100);
1159						} else {
1160							$('.style-switcher-open').trigger('click');
1161
1162							if (hideStyleSwitcherAfterShow) {
1163								setTimeout(() => {
1164									$('.style-switcher-open').trigger('click');
1165								}, 2000);
1166							}
1167						}
1168					}
1169					checkIfReady();
1170
1171				}, 500);
1172			}
1173
1174			document.body.appendChild(script1);
1175			document.body.appendChild(script2);	
1176
1177		});
1178
1179		let htmlDataOptions = $('html').data('style-switcher-options');
1180		let showSwitcher = false;
1181
1182		if(htmlDataOptions) {
1183			htmlDataOptions = htmlDataOptions.replace(/'/g, '"');
1184
1185			if (JSON.parse(htmlDataOptions).showSwitcher) {
1186				showSwitcher = true;
1187			}
1188
1189			if (JSON.parse(htmlDataOptions).hideStyleSwitcherAfterShow) {
1190				hideStyleSwitcherAfterShow = true;
1191			}
1192		}
1193
1194		if (urlParams.has("showStyleSwitcher")) {
1195			showSwitcher = true;
1196		}
1197
1198		if (urlParams.has("hideStyleSwitcherAfterShow")) {
1199			hideStyleSwitcherAfterShow = true;
1200		}
1201
1202		if (showSwitcher) {
1203			$('.style-switcher-open-loader').trigger('click');
1204		}
1205
1206	}
1207
1208})).apply(this, [ window.theme, jQuery ]);
1209
1210// Animate
1211(((theme = {}, $) => {
1212    const instanceName = '__animate';
1213
1214    class PluginAnimate {
1215        constructor($el, opts) {
1216            return this.initialize($el, opts);
1217        }
1218
1219        initialize($el, opts) {
1220			if ($el.data(instanceName)) {
1221				return this;
1222			}
1223
1224			this.$el = $el;
1225
1226			this
1227				.setData()
1228				.setOptions(opts)
1229				.build();
1230
1231			return this;
1232		}
1233
1234        setData() {
1235			this.$el.data(instanceName, this);
1236
1237			return this;
1238		}
1239
1240        setOptions(opts) {
1241			this.options = $.extend(true, {}, PluginAnimate.defaults, opts, {
1242				wrapper: this.$el
1243			});
1244
1245			return this;
1246		}
1247
1248        build() {
1249			const self = this;
1250
1251			// Flag Class Only
1252			// - Useful for simple animations like hightlight
1253			// - Less process and memory
1254			if( self.options.flagClassOnly ) {
1255				const delay = self.options.wrapper.attr('data-appear-animation-delay') ? self.options.wrapper.attr('data-appear-animation-delay') : self.options.delay;
1256				
1257				self.options.wrapper.css({
1258					'animation-delay': delay + 'ms',
1259					'transition-delay': delay + 'ms'
1260				});
1261				self.options.wrapper.addClass( self.options.wrapper.attr('data-appear-animation') );
1262
1263				return this;
1264			}
1265
1266			if($('body').hasClass('loading-overlay-showing')) {
1267				$(window).on('loading.overlay.ready', () => {
1268					self.animate();
1269				});
1270			} else {
1271				self.animate();
1272			}
1273
1274			return this;
1275		}
1276
1277        animate() {
1278            const self = this;
1279            const $el = this.options.wrapper;
1280            let delay = 0;
1281            let duration = this.options.duration;
1282            const elTopDistance = $el.offset().top;
1283            const windowTopDistance = $(window).scrollTop();
1284
1285            // If has appear animation elements inside a SVG. 
1286            // Intersection Observer API do not check elements inside SVG's, so we need initialize trough top parent SVG
1287            if( $el.data('appear-animation-svg') ) {
1288				$el.find('[data-appear-animation]').each(function(){
1289                    const $this = $(this);
1290                    let opts;
1291
1292                    const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
1293                    if (pluginOptions)
1294						opts = pluginOptions;
1295
1296                    $this.themePluginAnimate(opts);
1297                });
1298
1299				return this;
1300			}
1301
1302            // No animation at the first load of page. This is good for performance
1303            if( self.options.firstLoadNoAnim ) {
1304				$el.removeClass('appear-animation');
1305
1306				// Inside Carousel
1307				if( $el.closest('.owl-carousel').get(0) ) {
1308					setTimeout(() => {
1309						$el.closest('.owl-carousel').on('change.owl.carousel', () => {
1310							self.options.firstLoadNoAnim = false;
1311							$el.removeData('__animate');
1312							$el.themePluginAnimate( self.options );
1313						});
1314					}, 500);
1315				}
1316
1317				return this;
1318			}
1319
1320            $el.addClass('appear-animation animated');
1321
1322            if (!$('html').hasClass('no-csstransitions') && $(window).width() > self.options.minWindowWidth && elTopDistance >= windowTopDistance || self.options.forceAnimation == true) {
1323				delay = ($el.attr('data-appear-animation-delay') ? $el.attr('data-appear-animation-delay') : self.options.delay);
1324				duration = ($el.attr('data-appear-animation-duration') ? $el.attr('data-appear-animation-duration') : self.options.duration);
1325
1326				if (duration != '750ms') {
1327					$el.css('animation-duration', duration);
1328				}
1329
1330				$el.css('animation-delay', delay + 'ms');
1331				$el.addClass($el.attr('data-appear-animation') + ' appear-animation-visible');
1332				
1333				$el.trigger('animation:show');
1334
1335			} else {
1336				$el.addClass('appear-animation-visible');
1337			}
1338
1339            return this;
1340        }
1341    }
1342
1343    PluginAnimate.defaults = {
1344		accX: 0,
1345		accY: -80,
1346		delay: 100,
1347		duration: '750ms',
1348		minWindowWidth: 0,
1349		forceAnimation: false,
1350		flagClassOnly: false
1351	};
1352
1353    // expose to scope
1354    $.extend(theme, {
1355		PluginAnimate
1356	});
1357
1358    // jquery plugin
1359    $.fn.themePluginAnimate = function(opts) {
1360		return this.map(function() {
1361			const $this = $(this);
1362
1363			if ($this.data(instanceName)) {
1364				return $this.data(instanceName);
1365			} else {
1366				return new PluginAnimate($this, opts);
1367			}
1368
1369		});
1370	};
1371})).apply(this, [window.theme, jQuery]);
1372
1373// Animated Content
1374(((theme = {}, $) => {
1375    const instanceName = '__animatedContent';
1376
1377    class PluginAnimatedContent {
1378        constructor($el, opts) {
1379            return this.initialize($el, opts);
1380        }
1381
1382        initialize($el, opts) {
1383			if ($el.data(instanceName)) {
1384				return this;
1385			}
1386
1387			const self = this;
1388
1389			this.$el = $el;
1390			this.initialText = $el.text();
1391
1392			this
1393				.setData()
1394				.setOptions(opts)
1395				.build()
1396				.events();
1397
1398			return this;
1399		}
1400
1401        setData() {
1402			this.$el.data(instanceName, this);
1403
1404			return this;
1405		}
1406
1407        setOptions(opts) {
1408			this.options = $.extend(true, {}, PluginAnimatedContent.defaults, opts, {
1409				wrapper: this.$el
1410			});
1411
1412			return this;
1413		}
1414
1415        build() {
1416			const self    = this;
1417
1418			if( $(window).width() < self.options.minWindowWidth ) {
1419				return this;
1420			}
1421
1422			if( self.options.firstLoadNoAnim ) {
1423				self.$el.css({
1424					visibility: 'visible'
1425				});
1426
1427				// Inside Carousel
1428				if( self.$el.closest('.owl-carousel').get(0) ) {
1429					setTimeout(() => {
1430						self.$el.closest('.owl-carousel').on('change.owl.carousel', () => {
1431							self.options.firstLoadNoAnim = false;
1432							self.build();
1433						});
1434					}, 500);
1435				}
1436
1437				return this;
1438			}
1439
1440			// Set Min Height to avoid flicking issues
1441			self.setMinHeight();
1442
1443			// Letter
1444			if( self.options.contentType == 'letter' ) {
1445
1446				self.$el.addClass('initialized');
1447
1448				const letters = self.$el.text().split('');
1449
1450				self.$el.text('');
1451
1452				// Type Writer
1453				if( self.options.animationName == 'typeWriter' ) {
1454					self.$el.append( '<span class="letters-wrapper"></span><span class="typeWriter"></pre>' );
1455
1456					let index = 0;
1457
1458					setTimeout(() => {
1459
1460						const timeout = () => {
1461							const st = setTimeout(() => {
1462								const letter = letters[index];
1463								
1464								self.$el.find('.letters-wrapper').append( '<span class="letter '+ ( self.options.letterClass ? self.options.letterClass + ' ' : '' ) +'">' + letter + '</span>' );
1465
1466								index++;
1467								timeout();
1468							}, self.options.animationSpeed);
1469
1470							if( index >= letters.length ) {
1471								clearTimeout(st);
1472							}
1473						};
1474						timeout();
1475
1476					}, self.options.startDelay);
1477
1478				// Class Animation
1479				} else {
1480					setTimeout(() => {
1481						for( let i = 0; i < letters.length; i++ ) {
1482							const letter = letters[i];
1483							
1484							self.$el.append( '<span class="animated-letters-wrapper ' + self.options.wrapperClass + '"><span class="animated-letters-item letter '+ ( self.options.letterClass ? self.options.letterClass + ' ' : '' ) + self.options.animationName +' animated" style="animation-delay: '+ ( i * self.options.animationSpeed ) +'ms;">' + ( letter == ' ' ? '&nbsp;' : letter ) + '</span></span>' );
1485		
1486						}
1487					}, self.options.startDelay);
1488				}
1489
1490			// Words
1491			} else if( self.options.contentType == 'word' ) {
1492                const words = self.$el.text().split(" ");
1493                let delay = self.options.startDelay;
1494
1495                self.$el.empty();
1496
1497                $.each(words, (i, v) => {
1498					self.$el.append( $('<span class="animated-words-wrapper ' + self.options.wrapperClass + '">').html('<span class="animated-words-item ' + self.options.wordClass + ' appear-animation" data-appear-animation="' + self.options.animationName + '" data-appear-animation-delay="' + delay + '">' + v + '&nbsp;</span>') );
1499					delay = delay + self.options.animationSpeed;
1500				});
1501
1502                if ($.isFunction($.fn['themePluginAnimate']) && $('.animated-words-item[data-appear-animation]').length) {
1503					theme.fn.dynIntObsInit( '.animated-words-item[data-appear-animation]', 'themePluginAnimate', theme.PluginAnimate.defaults );
1504				}
1505
1506                self.$el.addClass('initialized');
1507            }
1508
1509			return this;
1510		}
1511
1512        setMinHeight() {
1513			const self = this;
1514
1515			// if it's inside carousel
1516			if( self.$el.closest('.owl-carousel').get(0) ) {
1517				self.$el.closest('.owl-carousel').addClass('d-block');
1518				self.$el.css( 'min-height', self.$el.height() );
1519				self.$el.closest('.owl-carousel').removeClass('d-block');
1520			} else {
1521				self.$el.css( 'min-height', self.$el.height() );
1522			}
1523
1524			return this;
1525		}
1526
1527        destroy() {
1528			const self = this;
1529
1530			self.$el
1531				.html( self.initialText )
1532				.css( 'min-height', '' );
1533
1534			return this;
1535		}
1536
1537        events() {
1538			const self = this;
1539
1540			// Destroy
1541			self.$el.on('animated.letters.destroy', () => {
1542				self.destroy();
1543			});
1544
1545			// Initialize
1546			self.$el.on('animated.letters.initialize', () => {
1547				self.build();
1548			});
1549
1550			return this;
1551		}
1552    }
1553
1554    PluginAnimatedContent.defaults = {
1555		contentType: 'letter',
1556		animationName: 'fadeIn',
1557		animationSpeed: 50,
1558		startDelay: 500,
1559		minWindowWidth: 768,
1560		letterClass: '',
1561		wordClass: '',
1562		wrapperClass: ''
1563	};
1564
1565    // expose to scope
1566    $.extend(theme, {
1567		PluginAnimatedContent
1568	});
1569
1570    // jquery plugin
1571    $.fn.themePluginAnimatedContent = function(opts) {
1572		return this.map(function() {
1573			const $this = $(this);
1574
1575			if ($this.data(instanceName)) {
1576				return $this.data(instanceName);
1577			} else {
1578				return new PluginAnimatedContent($this, opts);
1579			}
1580
1581		});
1582	}
1583})).apply(this, [window.theme, jQuery]);
1584
1585// Before / After
1586(((theme = {}, $) => {
1587    const instanceName = '__beforeafter';
1588
1589    class PluginBeforeAfter {
1590        constructor($el, opts) {
1591            return this.initialize($el, opts);
1592        }
1593
1594        initialize($el, opts) {
1595			this.$el = $el;
1596
1597			this
1598				.setData()
1599				.setOptions(opts)
1600				.build();
1601
1602			return this;
1603		}
1604
1605        setData() {
1606			this.$el.data(instanceName, this);
1607
1608			return this;
1609		}
1610
1611        setOptions(opts) {
1612			this.options = $.extend(true, {}, PluginBeforeAfter.defaults, opts, {
1613				wrapper: this.$el
1614			});
1615
1616			return this;
1617		}
1618
1619        build() {
1620
1621			if ($.isFunction($.fn.twentytwenty)) {
1622
1623				const self = this;
1624
1625				self.options.wrapper.waitForImages(() => {
1626					self.options.wrapper.twentytwenty(self.options);
1627				});
1628
1629			} else {
1630
1631				theme.fn.showErrorMessage('Failed to Load File', 'Failed to load: twentytwenty - Include the following file(s): (vendor/twentytwenty/css/twentytwenty.css, vendor/twentytwenty/js/jquery.event.move.js, vendor/twentytwenty/js/jquery.twentytwenty.js)');
1632
1633			}
1634
1635			return this;
1636
1637		}
1638    }
1639
1640    PluginBeforeAfter.defaults = {
1641		forceInit: true,
1642		default_offset_pct: 0.5,
1643		orientation: 'horizontal',
1644		before_label: 'Before',
1645		after_label: 'After',
1646		no_overlay: false,
1647		move_slider_on_hover: false,
1648		move_with_handle_only: true,
1649		click_to_move: false
1650	};
1651
1652    // expose to scope
1653    $.extend(theme, {
1654		PluginBeforeAfter
1655	});
1656
1657    // jquery plugin
1658    $.fn.themePluginBeforeAfter = function(opts) {
1659		return this.map(function() {
1660			const $this = $(this);
1661
1662			if ($this.data(instanceName)) {
1663				return $this.data(instanceName);
1664			} else {
1665				return new PluginBeforeAfter($this, opts);
1666			}
1667
1668		});
1669	}
1670})).apply(this, [window.theme, jQuery]);
1671
1672// Carousel Light
1673(((theme = {}, $) => {
1674    const instanceName = '__carouselLight';
1675
1676    class PluginCarouselLight {
1677        constructor($el, opts) {
1678            return this.initialize($el, opts);
1679        }
1680
1681        initialize($el, opts) {
1682			if ($el.data(instanceName)) {
1683				return this;
1684			}
1685
1686			this.$el = $el;
1687			this.clickFlag = true;
1688
1689			this
1690				.setData()
1691				.setOptions(opts)
1692				.build()
1693				.owlNav()
1694				.owlDots()
1695				.autoPlay()
1696				.events();
1697
1698			return this;
1699		}
1700
1701        setData() {
1702			this.$el.data(instanceName, this);
1703
1704			return this;
1705		}
1706
1707        setOptions(opts) {
1708			this.options = $.extend(true, {}, PluginCarouselLight.defaults, opts, {
1709				wrapper: this.$el
1710			});
1711
1712			return this;
1713		}
1714
1715        build() {
1716			const self = this;
1717
1718			self.$el
1719				.css('opacity', 1)
1720				.find('.owl-item:first-child')
1721				.addClass('active');
1722
1723			self.$el.trigger('initialized.owl.carousel');
1724
1725			// Carousel Navigate By ID and item index
1726			self.carouselNavigate();
1727
1728			return this;
1729		}
1730
1731        changeSlide($nextSlide) {
1732			const self = this, $prevSlide = self.$el.find('.owl-item.active');
1733
1734			self.$el.find('.owl-item.active').addClass('removing');
1735
1736			$prevSlide
1737				.removeClass('fadeIn')
1738				.addClass( 'fadeOut animated' );
1739
1740			setTimeout(() => {
1741				setTimeout(() => {
1742					$prevSlide.removeClass('active');
1743				}, 400);
1744
1745				$nextSlide
1746					.addClass('active')
1747					.removeClass('fadeOut')
1748					.addClass( 'fadeIn animated' );
1749
1750			}, 200);
1751
1752			// Dots
1753			self.$el
1754				.find('.owl-dot')
1755				.removeClass('active')
1756				.eq( $nextSlide.index() )
1757				.addClass('active');
1758
1759			self.$el.trigger({
1760				type: 'change.owl.carousel',
1761				nextSlideIndex: $nextSlide.index(),
1762				prevSlideIndex: $prevSlide.index()
1763			});
1764
1765			setTimeout(() => {
1766				self.$el.trigger({
1767					type: 'changed.owl.carousel',
1768					nextSlideIndex: $nextSlide.index(),
1769					prevSlideIndex: $prevSlide.index()
1770				});
1771			}, 500);
1772		}
1773
1774        owlNav() {
1775			const self = this, $owlNext = self.$el.find('.owl-next'), $owlPrev = self.$el.find('.owl-prev');
1776
1777			$owlPrev.on('click', e => {
1778				e.preventDefault();
1779
1780				if( self.options.disableAutoPlayOnClick ) {
1781					window.clearInterval(self.autoPlayInterval);
1782				}
1783
1784				if( self.avoidMultipleClicks() ) {
1785					return false;
1786				}
1787
1788				self.owlPrev();
1789			});
1790
1791			$owlNext.on('click', e => {
1792				e.preventDefault();
1793
1794				if( self.options.disableAutoPlayOnClick ) {
1795					window.clearInterval(self.autoPlayInterval);
1796				}
1797
1798				if( self.avoidMultipleClicks() ) {
1799					return false;
1800				}
1801
1802				self.owlNext();
1803			});
1804
1805			return this;
1806		}
1807
1808        owlDots() {
1809			const self = this, $owlDot = self.$el.find('.owl-dot');
1810
1811			$owlDot.on('click', function(e){
1812				let $this = $(this);
1813
1814				e.preventDefault();
1815
1816				if( self.options.disableAutoPlayOnClick ) {
1817					window.clearInterval(self.autoPlayInterval);
1818				}
1819
1820				if( self.avoidMultipleClicks() ) {
1821					return false;
1822				}
1823
1824				const dotIndex = $(this).index();
1825
1826				// Do nothing if respective dot slide is active/showing
1827				if( $this.hasClass('active') ) {
1828					return false;
1829				}
1830
1831				self.changeSlide( self.$el.find('.owl-item').eq( dotIndex ) );
1832			});
1833
1834			return this;
1835		}
1836
1837        owlPrev() {
1838			const self = this;
1839
1840			if( self.$el.find('.owl-item.active').prev().get(0) ) {
1841				self.changeSlide( self.$el.find('.owl-item.active').prev() );
1842			} else {
1843				self.changeSlide( self.$el.find('.owl-item:last-child') );
1844			}
1845		}
1846
1847        owlNext() {
1848			const self = this;
1849
1850			if( self.$el.find('.owl-item.active').next().get(0) ) {
1851				self.changeSlide( self.$el.find('.owl-item.active').next() );
1852			} else {
1853				self.changeSlide( self.$el.find('.owl-item').eq(0) );
1854			}
1855		}
1856
1857        avoidMultipleClicks() {
1858			const self = this;
1859
1860			if( !self.clickFlag ) {
1861				return true;
1862			}
1863
1864			if( self.clickFlag ) {
1865				self.clickFlag = false;
1866				setTimeout(() => {
1867					self.clickFlag = true; 
1868				}, 1000);
1869			}
1870
1871			return false;
1872		}
1873
1874        autoPlay() {
1875			const self = this, $el  = this.options.wrapper;
1876
1877			if( self.options.autoplay ) {
1878				self.autoPlayInterval = window.setInterval(() => {
1879					self.owlNext();
1880				}, self.options.autoplayTimeout);
1881			}
1882
1883			return this;
1884		}
1885
1886        carouselNavigate() {
1887			const self      = this, $el       = this.options.wrapper, $carousel = $el;
1888
1889			if( $('[data-carousel-navigate]').get(0) ) {
1890				$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').each(function(){
1891					const $this = $(this), hasCarousel = $( $this.data('carousel-navigate-id') ).get(0), toIndex = $this.data('carousel-navigate-to');
1892
1893					if( hasCarousel ) {
1894
1895						$this.on('click', () => {
1896
1897							if( self.options.disableAutoPlayOnClick ) {
1898								window.clearInterval(self.autoPlayInterval);
1899							}
1900							
1901							self.changeSlide( self.$el.find('.owl-item').eq( parseInt(toIndex) - 1 ) );
1902						});
1903
1904					}
1905				});
1906
1907				$el.on('change.owl.carousel', e => {
1908					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').removeClass('active');
1909				});
1910
1911				$el.on('changed.owl.carousel', ({nextSlideIndex}) => {
1912					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"][data-carousel-navigate-to="'+ ( nextSlideIndex + 1 ) +'"]').addClass('active');
1913				});
1914			}
1915
1916			return this;
1917		}
1918
1919        events() {
1920			const self = this;
1921
1922			self.$el.on('change.owl.carousel', event => {
1923
1924				// Hide elements inside carousel
1925			    self.$el.find('[data-appear-animation]:not(.background-image-wrapper), [data-plugin-animated-letters]').addClass('invisible');
1926
1927			    // Animated Letters
1928			    self.$el.find('[data-plugin-animated-letters]').trigger('animated.letters.destroy');
1929
1930			    // Remove "d-none" class before show the element. This is useful when using background images inside a carousel. Like ken burns effect
1931			    self.$el.find('.owl-item:not(.active) [data-carousel-onchange-show]').removeClass('d-none');
1932
1933			});
1934
1935			self.$el.on('changed.owl.carousel', event => {
1936				setTimeout(() => {
1937
1938				    // Appear Animation
1939				    if( self.$el.find('.owl-item.cloned [data-appear-animation]').get(0) ) {
1940				    	self.$el.find('.owl-item.cloned [data-appear-animation]').each(function() {
1941                            const $this = $(this);
1942                            let opts;
1943
1944                            const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
1945                            if (pluginOptions)
1946								opts = pluginOptions;
1947
1948                            $this.themePluginAnimate(opts);
1949                        });
1950				    }
1951
1952					// Show elements inside carousel
1953				    self.$el.find('.owl-item.active [data-appear-animation]:not(.background-image-wrapper), [data-plugin-animated-letters]').removeClass('invisible');
1954
1955				    // Animated Letters
1956				    self.$el.find('.owl-item.active [data-plugin-animated-letters]').trigger('animated.letters.initialize');
1957
1958				    // Background Video
1959				    self.$el.find('.owl-item.cloned.active [data-plugin-video-background]').trigger('video.background.initialize');
1960
1961				}, 500);
1962			    
1963			});
1964
1965			if( self.options.swipeEvents ) {
1966				self.$el.swipe({
1967					swipe(event, direction, distance, duration, fingerCount, fingerData) {
1968						switch ( direction ) {
1969							case 'right':
1970								self.owlPrev();
1971							break;
1972				
1973							case 'left':
1974								self.owlNext();
1975							break;
1976						}
1977					},
1978					allowPageScroll: "vertical"
1979				});
1980			}
1981		}
1982    }
1983
1984    PluginCarouselLight.defaults = {
1985		autoplay: true,
1986		autoplayTimeout: 7000,
1987		disableAutoPlayOnClick: true,
1988		swipeEvents: true
1989	};
1990
1991    // expose to scope
1992    $.extend(theme, {
1993		PluginCarouselLight
1994	});
1995
1996    // jquery plugin
1997    $.fn.themePluginCarouselLight = function(opts) {
1998		return this.map(function() {
1999			const $this = $(this);
2000
2001			if ($this.data(instanceName)) {
2002				return $this.data(instanceName);
2003			} else {
2004				return new PluginCarouselLight($this, opts);
2005			}
2006
2007		});
2008	};
2009})).apply(this, [window.theme, jQuery]);
2010
2011// Carousel
2012(((theme = {}, $) => {
2013    const instanceName = '__carousel';
2014
2015    class PluginCarousel {
2016        constructor($el, opts) {
2017            return this.initialize($el, opts);
2018        }
2019
2020        initialize($el, opts) {
2021			if ($el.data(instanceName)) {
2022				return this;
2023			}
2024
2025			this.$el = $el;
2026
2027			// If has data-icon inside, initialize only after icons get rendered
2028			// Prevent flicking issues
2029			if( $el.find('[data-icon]').get(0) ) {
2030				const self = this;
2031
2032				$(window).on('icon.rendered', function(){
2033					if ($el.data(instanceName)) {
2034						return this;
2035					}
2036
2037					setTimeout(() => {
2038						self
2039							.setData()
2040							.setOptions(opts)
2041							.build();
2042					}, 1000);
2043				});
2044
2045				return this;
2046			}
2047
2048			this
2049				.setData()
2050				.setOptions(opts)
2051				.build();
2052
2053			return this;
2054		}
2055
2056        setData() {
2057			this.$el.data(instanceName, this);
2058
2059			return this;
2060		}
2061
2062        setOptions(opts) {
2063			this.options = $.extend(true, {}, PluginCarousel.defaults, opts, {
2064				wrapper: this.$el
2065			});
2066
2067			return this;
2068		}
2069
2070        build() {
2071			if (!($.isFunction($.fn.owlCarousel))) {
2072				return this;
2073			}
2074
2075			const self = this, $el = this.options.wrapper;
2076
2077			// Add Theme Class
2078			$el.addClass('owl-theme');
2079
2080			// Add Loading
2081			$el.addClass('owl-loading');
2082
2083			// Force RTL according to HTML dir attribute
2084			if ($('html').attr('dir') == 'rtl') {
2085				this.options = $.extend(true, {}, this.options, {
2086					rtl: true
2087				});
2088			}
2089
2090			if (this.options.items == 1) {
2091				this.options.responsive = {}
2092			}
2093
2094			if (this.options.items > 4) {
2095				this.options = $.extend(true, {}, this.options, {
2096					responsive: {
2097						1199: {
2098							items: this.options.items
2099						}
2100					}
2101				});
2102			}
2103
2104			// Auto Height Fixes
2105			if (this.options.autoHeight) {
2106				const itemsHeight = [];
2107
2108				$el.find('.owl-item').each(function(){
2109					if( $(this).hasClass('active') ) {
2110						itemsHeight.push( $(this).height() );
2111					}
2112				});
2113
2114				$(window).afterResize(() => {
2115					$el.find('.owl-stage-outer').height( Math.max.apply(null, itemsHeight) );
2116				});
2117
2118				$(window).on('load', () => {
2119					$el.find('.owl-stage-outer').height( Math.max.apply(null, itemsHeight) );
2120				});
2121			}
2122
2123			// Initialize OwlCarousel
2124			$el.owlCarousel(this.options).addClass('owl-carousel-init animated fadeIn');
2125
2126			// Remove "animated fadeIn" class to prevent conflicts
2127			setTimeout(() => {
2128				$el.removeClass('animated fadeIn');
2129			}, 1000);
2130
2131			// Owl Carousel Wrapper
2132			if( $el.closest('.owl-carousel-wrapper').get(0) ) {
2133				setTimeout(() => {
2134					$el.closest('.owl-carousel-wrapper').css({
2135						height: ''
2136					});
2137				}, 500);
2138			}
2139
2140			// Owl Carousel Loader
2141			if( $el.prev().hasClass('owl-carousel-loader') ) {
2142				$el.prev().remove();
2143			}
2144
2145			// Nav Offset
2146			self.navigationOffsets();
2147
2148			// Nav Outside
2149			if( $el.hasClass('nav-outside') ) {
2150				$(window).on('owl.carousel.nav.outside', () => {
2151					if( $(window).width() < 992 ) {
2152						self.options.stagePadding = 40;
2153						$el.addClass('stage-margin');
2154					} else {
2155						self.options.stagePadding = 0;
2156						$el.removeClass('stage-margin');
2157					}
2158
2159					$el.owlCarousel('destroy').owlCarousel( self.options );
2160
2161					// Nav Offset
2162					self.navigationOffsets();
2163				});
2164
2165				// Window Resize
2166				$(window).on('load', () => {
2167					$(window).afterResize(() => {
2168						$(window).trigger('owl.carousel.nav.outside');
2169					});
2170				});
2171
2172				// First Load
2173				$(window).trigger('owl.carousel.nav.outside');
2174			}
2175
2176			// Nav style 5 (SVG Arrows)
2177			if( $el.hasClass('nav-svg-arrows-1') ) {
2178				const svg_arrow = '' +
2179					'<svg version="1.1" viewBox="0 0 15.698 8.706" width="17" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' +
2180						'<polygon stroke="#212121" stroke-width="0.1" fill="#212121" points="11.354,0 10.646,0.706 13.786,3.853 0,3.853 0,4.853 13.786,4.853 10.646,8 11.354,8.706 15.698,4.353 "/>' +
2181					'</svg>';
2182
2183				$el.find('.owl-next, .owl-prev').append( svg_arrow );
2184			}
2185
2186			// Sync
2187			if( $el.attr('data-sync') ) {
2188				$el.on('change.owl.carousel', ({namespace, property, relatedTarget}) => {
2189					if (namespace && property.name === 'position') {
2190					    const target = relatedTarget.relative(property.value, true);
2191					    $( $el.data('sync') ).owlCarousel('to', target, 300, true);				        
2192				  	}
2193				});
2194			}
2195
2196			// Carousel Center Active Item
2197			if( $el.hasClass('carousel-center-active-item') ) {
2198				const itemsActive    = $el.find('.owl-item.active'), indexCenter    = Math.floor( ($el.find('.owl-item.active').length - 1) / 2 ), itemCenter     = itemsActive.eq
2198(indexCenter);
2199
2200				itemCenter.addClass('current');
2201
2202				$el.on('change.owl.carousel', event => {
2203				  	$el.find('.owl-item').removeClass('current');
2204					
2205					setTimeout(() => {
2206					  	const itemsActive    = $el.find('.owl-item.active'), indexCenter    = Math.floor( ($el.find('.owl-item.active').length - 1) / 2 ), itemCenter     = itemsActive.eq(indexCenter);
2207
2208					  	itemCenter.addClass('current');
2209					}, 100);
2210				});
2211
2212				// Refresh
2213				$el.trigger('refresh.owl.carousel');
2214
2215			}
2216
2217			// AnimateIn / AnimateOut Fix
2218			if( self.options.animateIn || self.options.animateOut ) {
2219				$el.on('change.owl.carousel', event => {
2220
2221					// Hide elements inside carousel
2222				    $el.find('[data-appear-animation], [data-plugin-animated-letters]').addClass('d-none');
2223
2224				    // Animated Letters
2225				    $el.find('[data-plugin-animated-letters]').trigger('animated.letters.destroy');
2226
2227				    // Remove "d-none" class before show the element. This is useful when using background images inside a carousel. Like ken burns effect
2228				    $el.find('.owl-item:not(.active) [data-carousel-onchange-show]').removeClass('d-none');
2229
2230				});
2231
2232				$el.on('changed.owl.carousel', event => {
2233					setTimeout(() => {
2234
2235					    // Appear Animation
2236				    	$el.find('[data-appear-animation]').each(function() {
2237                            const $this = $(this);
2238                            let opts;
2239
2240                            const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
2241                            if (pluginOptions)
2242								opts = pluginOptions;
2243
2244                            $this.themePluginAnimate(opts);
2245                        });
2246
2247						// Show elements inside carousel
2248					    $el.find('.owl-item.active [data-appear-animation], [data-plugin-animated-letters]').removeClass('d-none');
2249
2250					    // Animated Letters
2251					    $el.find('.owl-item.active [data-plugin-animated-letters]').trigger('animated.letters.initialize');
2252
2253					    // Background Video
2254					    $el.find('.owl-item.cloned.active [data-plugin-video-background]').trigger('video.background.initialize');
2255
2256					}, 10);
2257				    
2258				});
2259			}
2260
2261			// data-icon inside carousel
2262			if( $el.find('[data-icon]').length ) {
2263				$el.on('change.owl.carousel drag.owl.carousel', () => {
2264					$el.find('.owl-item.cloned [data-icon]').each(function(){
2265                        const $this = $(this);
2266                        let opts;
2267
2268                        const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
2269                        if (pluginOptions)
2270							opts = pluginOptions;
2271
2272                        $this.themePluginIcon(opts);
2273                    });
2274				});
2275			}
2276
2277			// Render Background Videos inside carousel. Just a trigger on window is sufficient to render
2278			if( $el.find('[data-plugin-video-background]').get(0) ) {
2279				$(window).resize();
2280			}
2281
2282			// Remove Loading
2283			$el.removeClass('owl-loading');
2284
2285			// Remove Height
2286			$el.css('height', 'auto');
2287
2288			// Carousel Navigate By ID and item index
2289			self.carouselNavigate();
2290
2291			// Refresh Carousel
2292			if( self.options.refresh ) {
2293				$el.owlCarousel('refresh');
2294			}
2295
2296			return this;
2297		}
2298
2299        navigationOffsets() {
2300			const self 			 = this, $el  			 = this.options.wrapper, navHasTransform  = $el.find('.owl-nav').css('transform') == 'none' ? false : true, dotsHasTransform = $el.find('.owl-dots').css('transform') == 'none' ? false : true;
2301
2302			// ************* NAV *****************
2303			// Nav Offset - Horizontal
2304			if( self.options.navHorizontalOffset && !self.options.navVerticalOffset ) {
2305				if( !navHasTransform ) {
2306					$el.find('.owl-nav').css({
2307						transform: 'translate3d('+ self.options.navHorizontalOffset +', 0, 0)'
2308					});
2309				} else {
2310					$el.find('.owl-nav').css({
2311						left: self.options.navHorizontalOffset
2312					});
2313				}
2314			}
2315
2316			// Nav Offset - Vertical
2317			if( self.options.navVerticalOffset && !self.options.navHorizontalOffset ) {
2318				if( !navHasTransform ) {
2319					$el.find('.owl-nav').css({
2320						transform: 'translate3d(0, '+ self.options.navVerticalOffset +', 0)'
2321					});
2322				} else {
2323					$el.find('.owl-nav').css({
2324						top: 'calc( 50% - '+ self.options.navVerticalOffset +' )'
2325					});
2326				}
2327			}
2328
2329			// Nav Offset - Horizontal & Vertical
2330			if( self.options.navVerticalOffset && self.options.navHorizontalOffset ) {
2331				if( !navHasTransform ) {
2332					$el.find('.owl-nav').css({
2333						transform: 'translate3d('+ self.options.navHorizontalOffset +', '+ self.options.navVerticalOffset +', 0)'
2334					});
2335				} else {
2336					$el.find('.owl-nav').css({
2337						top: 'calc( 50% - '+ self.options.navVerticalOffset +' )',
2338						left: self.options.navHorizontalOffset
2339					});
2340				}
2341			}
2342
2343			// ********** DOTS *********************
2344			// Dots Offset - Horizontal
2345			if( self.options.dotsHorizontalOffset && !self.options.dotsVerticalOffset ) {
2346				$el.find('.owl-dots').css({
2347					transform: 'translate3d('+ self.options.dotsHorizontalOffset +', 0, 0)'
2348				});
2349			}
2350
2351			// Dots Offset - Vertical
2352			if( self.options.dotsVerticalOffset && !self.options.dotsHorizontalOffset ) {
2353				if( !dotsHasTransform ) {
2354					$el.find('.owl-dots').css({
2355						transform: 'translate3d(0, '+ self.options.dotsVerticalOffset +', 0)'
2356					});
2357				} else {
2358					$el.find('.owl-dots').css({
2359						top: 'calc( 50% - '+ self.options.dotsVerticalOffset +' )'
2360					});
2361				}
2362			}
2363
2364			// Dots Offset - Horizontal & Vertical
2365			if( self.options.dotsVerticalOffset && self.options.dotsHorizontalOffset ) {
2366				$el.find('.owl-dots').css({
2367					transform: 'translate3d('+ self.options.dotsHorizontalOffset +', '+ self.options.dotsVerticalOffset +', 0)'
2368				});
2369			}
2370
2371			return this;
2372		}
2373
2374        carouselNavigate() {
2375			const self      = this, $el       = this.options.wrapper, $carousel = $el.data('owl.carousel');
2376
2377			if( $('[data-carousel-navigate]').get(0) ) {
2378				$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').each(function(){
2379					const $this = $(this), hasCarousel = $( $this.data('carousel-navigate-id') ).get(0), toIndex = $this.data('carousel-navigate-to');
2380
2381					if( hasCarousel ) {
2382
2383						$this.on('click', () => {
2384							$carousel.to( parseInt(toIndex) - 1 );
2385						});
2386
2387					}
2388				});
2389
2390				$el.on('change.owl.carousel', () => {
2391					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"]').removeClass('active');
2392				});
2393
2394				$el.on('changed.owl.carousel', ({item}) => {
2395					$('[data-carousel-navigate-id="#'+ $el.attr('id') +'"][data-carousel-navigate-to="'+ ( item.index + 1 ) +'"]').addClass('active');
2396				});
2397			}
2398
2399			return this;
2400		}
2401    }
2402
2403    PluginCarousel.defaults = {
2404		loop: true,
2405		responsive: {
2406			0: {
2407				items: 1
2408			},
2409			479: {
2410				items: 1
2411			},
2412			768: {
2413				items: 2
2414			},
2415			979: {
2416				items: 3
2417			},
2418			1199: {
2419				items: 4
2420			}
2421		},
2422		navText: [],
2423		refresh: false
2424	};
2425
2426    // expose to scope
2427    $.extend(theme, {
2428		PluginCarousel
2429	});
2430
2431    // jquery plugin
2432    $.fn.themePluginCarousel = function(opts) {
2433		return this.map(function() {
2434			const $this = $(this);
2435
2436			if ($this.data(instanceName)) {
2437				return $this.data(instanceName);
2438			} else {
2439				return new PluginCarousel($this, opts);
2440			}
2441
2442		});
2443	}
2444})).apply(this, [window.theme, jQuery]);
2445
2446// Chart Circular
2447(((theme = {}, $) => {
2448    const instanceName = '__chartCircular';
2449
2450    class PluginChartCircular {
2451        constructor($el, opts) {
2452            return this.initialize($el, opts);
2453        }
2454
2455        initialize($el, opts) {
2456			if ($el.data(instanceName)) {
2457				return this;
2458			}
2459
2460			this.$el = $el;
2461
2462			this
2463				.setData()
2464				.setOptions(opts)
2465				.build();
2466
2467			return this;
2468		}
2469
2470        setData() {
2471			this.$el.data(instanceName, this);
2472
2473			return this;
2474		}
2475
2476        setOptions(opts) {
2477			this.options = $.extend(true, {}, PluginChartCircular.defaults, opts, {
2478				wrapper: this.$el
2479			});
2480
2481			return this;
2482		}
2483
2484        build() {
2485			if (!($.isFunction($.fn.easyPieChart))) {
2486				return this;
2487			}
2488
2489			const self = this, $el = this.options.wrapper, value = ($el.attr('data-percent') ? $el.attr('data-percent') : 0), percentEl = $el.find('.percent');
2490
2491			$.extend(true, self.options, {
2492				onStep(from, to, currentValue) {
2493					percentEl.html(parseInt(currentValue));
2494				}
2495			});
2496
2497			$el.attr('data-percent', 0);
2498
2499			$el.easyPieChart(self.options);
2500
2501			setTimeout(() => {
2502
2503				$el.data('easyPieChart').update(value);
2504				$el.attr('data-percent', value);
2505
2506			}, self.options.delay);
2507
2508			return this;
2509		}
2510    }
2511
2512    PluginChartCircular.defaults = {
2513		accX: 0,
2514		accY: -150,
2515		delay: 1,
2516		barColor: '#0088CC',
2517		trackColor: '#f2f2f2',
2518		scaleColor: false,
2519		scaleLength: 5,
2520		lineCap: 'round',
2521		lineWidth: 13,
2522		size: 175,
2523		rotate: 0,
2524		animate: ({
2525			duration: 2500,
2526			enabled: true
2527		})
2528	};
2529
2530    // expose to scope
2531    $.extend(theme, {
2532		PluginChartCircular
2533	});
2534
2535    // jquery plugin
2536    $.fn.themePluginChartCircular = function(opts) {
2537		return this.map(function() {
2538			const $this = $(this);
2539
2540			if ($this.data(instanceName)) {
2541				return $this.data(instanceName);
2542			} else {
2543				return new PluginChartCircular($this, opts);
2544			}
2545
2546		});
2547	}
2548})).apply(this, [window.theme, jQuery]);
2549
2550// Countdown
2551(((theme = {}, $) => {
2552    const instanceName = '__countdown';
2553
2554    class PluginCountdown {
2555        constructor($el, opts) {
2556            return this.initialize($el, opts);
2557        }
2558
2559        initialize($el, opts) {
2560			if ($el.data(instanceName)) {
2561				return this;
2562			}
2563
2564			this.$el = $el;
2565
2566			this
2567				.setData()
2568				.setOptions(opts)
2569				.build();
2570
2571			return this;
2572		}
2573
2574        setData() {
2575			this.$el.data(instanceName, this);
2576
2577			return this;
2578		}
2579
2580        setOptions(opts) {
2581			this.options = $.extend(true, {}, PluginCountdown.defaults, opts, {
2582				wrapper: this.$el
2583			});
2584
2585			return this;
2586		}
2587
2588        build() {
2589			if (!($.isFunction($.fn.countTo))) {
2590				return this;
2591			}
2592
2593			const self = this, $el = this.options.wrapper, numberClass = ( self.options.numberClass ) ? ' ' + self.options.numberClass : '', wrapperClass = ( self.options.wrapperClass ) ? ' ' + self.options.wrapperClass : '';
2594
2595			if( self.options.uppercase ) {
2596				$el.countdown(self.options.date).on('update.countdown', function(event) {
2597					const $this = $(this).html(event.strftime(self.options.insertHTMLbefore
2598						+ '<span class="days'+ wrapperClass +'"><span class="'+ numberClass +'">%D</span> '+ self.options.textDay +'</span> '
2599						+ '<span class="hours'+ wrapperClass +'"><span class="'+ numberClass +'">%H</span> '+ self.options.textHour +'</span> '
2600						+ '<span class="minutes'+ wrapperClass +'"><span class="'+ numberClass +'">%M</span> '+ self.options.textMin +'</span> '
2601						+ '<span class="seconds'+ wrapperClass +'"><span class="'+ numberClass +'">%S</span> '+ self.options.textSec +'</span> '
2602						+ self.options.insertHTMLafter
2603					));
2604				});
2605			} else {
2606				$el.countdown(self.options.date).on('update.countdown', function(event) {
2607					const $this = $(this).html(event.strftime(self.options.insertHTMLbefore
2608						+ '<span class="days'+ wrapperClass +'"><span class="'+ numberClass +'">%D</span> '+ self.options.textDay +'</span> '
2609						+ '<span class="hours'+ wrapperClass +'"><span class="'+ numberClass +'">%H</span> '+ self.options.textHour +'</span> '
2610						+ '<span class="minutes'+ wrapperClass +'"><span class="'+ numberClass +'">%M</span> '+ self.options.textMin +'</span> '
2611						+ '<span class="seconds'+ wrapperClass +'"><span class="'+ numberClass +'">%S</span> '+ self.options.textSec +'</span> '
2612						+ self.options.insertHTMLafter
2613					));
2614				});
2615			}
2616
2617			return this;
2618		}
2619    }
2620
2621    PluginCountdown.defaults = {
2622		date: '2030/06/10 12:00:00',
2623		textDay: 'DAYS',
2624		textHour: 'HRS',
2625		textMin: 'MIN',
2626		textSec: 'SEC',
2627		uppercase: true,
2628		numberClass: '',
2629		wrapperClass: '',
2630		insertHTMLbefore: '',
2631		insertHTMLafter: ''
2632	};
2633
2634    // expose to scope
2635    $.extend(theme, {
2636		PluginCountdown
2637	});
2638
2639    // jquery plugin
2640    $.fn.themePluginCountdown = function(opts) {
2641		return this.map(function() {
2642			const $this = $(this);
2643
2644			if ($this.data(instanceName)) {
2645				return $this.data(instanceName);
2646			} else {
2647				return new PluginCountdown($this, opts);
2648			}
2649
2650		});
2651	}
2652})).apply(this, [window.theme, jQuery]);
2653
2654// Counter
2655(((theme = {}, $) => {
2656    const instanceName = '__counter';
2657
2658    class PluginCounter {
2659        constructor($el, opts) {
2660            return this.initialize($el, opts);
2661        }
2662
2663        initialize($el, opts) {
2664			if ($el.data(instanceName)) {
2665				return this;
2666			}
2667
2668			this.$el = $el;
2669
2670			this
2671				.setData()
2672				.setOptions(opts)
2673				.build();
2674
2675			return this;
2676		}
2677
2678        setData() {
2679			this.$el.data(instanceName, this);
2680
2681			return this;
2682		}
2683
2684        setOptions(opts) {
2685			this.options = $.extend(true, {}, PluginCounter.defaults, opts, {
2686				wrapper: this.$el
2687			});
2688
2689			return this;
2690		}
2691
2692        build() {
2693			if (!($.isFunction($.fn.countTo))) {
2694				return this;
2695			}
2696
2697			const self = this, $el = this.options.wrapper;
2698
2699			if (self.options.comma) {
2700				self.options.formatter = (value, {decimals}) => value.toFixed(decimals).toString().replace('.',',')
2701			}
2702
2703			$.extend(self.options, {
2704				onComplete() {
2705					
2706					if ($el.data('append')) {
2707						if( self.options.appendWrapper ) {
2708							const appendWrapper = $( self.options.appendWrapper );
2709
2710							appendWrapper.append( $el.data('append') );
2711
2712							$el.html( $el.html() + appendWrapper[0].outerHTML );
2713						} else {
2714							$el.html($el.html() + $el.data('append'));
2715						}
2716					}
2717
2718					if ($el.data('prepend')) {
2719						if( self.options.prependWrapper ) {
2720							const prependWrapper = $( self.options.prependWrapper );
2721
2722							prependWrapper.append( $el.data('prepend') );
2723
2724							$el.html( $el.html() + prependWrapper[0].outerHTML );
2725						} else {
2726							$el.html($el.data('prepend') + $el.html());
2727						}
2728					}
2729				}
2730			});
2731
2732			$el.countTo(self.options);
2733
2734			return this;
2735		}
2736    }
2737
2738    PluginCounter.defaults = {
2739		accX: 0,
2740		accY: 0,
2741		appendWrapper: false,
2742		prependWrapper: false,
2743		speed: 3000,
2744		refreshInterval: 100,
2745		decimals: 0,
2746		comma: false,
2747		onUpdate: null,
2748		onComplete: null
2749	}
2750
2751    // expose to scope
2752    $.extend(theme, {
2753		PluginCounter
2754	});
2755
2756    // jquery plugin
2757    $.fn.themePluginCounter = function(opts) {
2758		return this.map(function() {
2759			const $this = $(this);
2760
2761			if ($this.data(instanceName)) {
2762				return $this.data(instanceName);
2763			} else {
2764				return new PluginCounter($this, opts);
2765			}
2766
2767		});
2768	}
2769})).apply(this, [window.theme, jQuery]);
2770
2771// CursorEffect
2772(((theme = {}, $) => {
2773    const instanceName = '__cursorEffect';
2774
2775    class PluginCursorEffect {
2776        constructor($el, opts) {
2777            return this.initialize($el, opts);
2778        }
2779
2780        initialize($el, opts) {
2781			if ($el.data(instanceName)) {
2782				return this;
2783			}
2784
2785			this.$el = $el;
2786
2787			this
2788				.setData()
2789				.setOptions(opts)
2790				.build()
2791				.events();
2792
2793			return this;
2794		}
2795
2796        setData() {
2797			this.$el.data(instanceName, this);
2798
2799			return this;
2800		}
2801
2802        setOptions(opts) {
2803			this.options = $.extend(true, {}, PluginCursorEffect.defaults, opts, {
2804				wrapper: this.$el
2805			});
2806
2807			return this;
2808		}
2809
2810        build() {
2811			const self = this;
2812
2813			// Global Variables for cursor position
2814			self.clientX = -100;
2815			self.clientY = -100;
2816
2817			// Hide Mouse Cursor
2818			if( self.options.hideMouseCursor ) {
2819				self.$el.addClass('hide-mouse-cursor');
2820			}
2821
2822			// Creates the cursor wrapper node
2823			const cursorOuter = document.createElement('DIV');
2824				cursorOuter.className = 'cursor-outer';
2825
2826			// Creates the cursor inner node
2827			const cursorInner = document.createElement('DIV');
2828				cursorInner.className = 'cursor-inner';
2829
2830			// Custom Cursor Outer Color
2831			if( self.options.cursorOuterColor ) {
2832				cursorOuter.style = 'border-color: ' + self.options.cursorOuterColor + ';';
2833			}
2834
2835			// Custom Cursor Inner Color
2836			if( self.options.cursorInnerColor ) {
2837				cursorInner.style = 'background-color: ' + self.options.cursorInnerColor + ';';
2838			}
2839
2840			// Size
2841			if( self.options.size ) {
2842				switch ( self.options.size ) {
2843					case 'small':
2844						self.$el.addClass( 'cursor-effect-size-small' );
2845						break;
2846					
2847					case 'big':
2848						self.$el.addClass( 'cursor-effect-size-big' );
2849						break;
2850				}
2851			}
2852
2853			// Style
2854			if( self.options.style ) {
2855				self.$el.addClass( self.options.style );
2856			}
2857
2858			// Prepend cursor wrapper node to the body
2859			document.body.prepend( cursorOuter );
2860
2861			// Prepend cursor inner node to the body
2862			document.body.prepend( cursorInner );
2863
2864			// Loop for render
2865			const render = () => {
2866				cursorOuter.style.transform = 'translate('+ self.clientX +'px, '+ self.clientY +'px)';
2867				cursorInner.style.transform = 'translate('+ self.clientX +'px, '+ self.clientY +'px)';
2868
2869				self.loopInside = requestAnimationFrame(render);
2870			};
2871			self.loop = requestAnimationFrame(render);
2872
2873			return this;
2874		}
2875
2876        events() {
2877			const self = this, $cursorOuter = $('.cursor-outer'), $cursorInner = $('.cursor-inner');
2878
2879			const initialCursorOuterBox    = $cursorOuter[0].getBoundingClientRect(), initialCursorOuterRadius = $cursorOuter.css('border-radius');
2880
2881			// Update Cursor Position
2882			document.addEventListener('mousemove', ({clientX, clientY}) => {
2883				if( !self.isStuck ) {
2884					self.clientX = clientX - 20;
2885					self.clientY = clientY - 20;
2886				}
2887
2888				$cursorOuter.removeClass('opacity-0');
2889			});
2890
2891			self.isStuck = false;
2892			$('[data-cursor-effect-hover]').on('mouseenter', function(e){
2893
2894				// Identify Event With Hover Class
2895				$cursorOuter.addClass('cursor-outer-hover');
2896				$cursorInner.addClass('cursor-inner-hover');
2897
2898				// Hover Color
2899				const hoverColor = $(this).data('cursor-effect-hover-color');
2900				$cursorOuter.addClass( 'cursor-color-' + hoverColor );
2901				$cursorInner.addClass( 'cursor-color-' + hoverColor );
2902
2903				// Effect Types
2904				switch ( $(this).data('cursor-effect-hover') ) {
2905					case 'fit':
2906						const thisBox = $(this)[0].getBoundingClientRect();
2907
2908						self.clientX = thisBox.x;
2909						self.clientY = thisBox.y;
2910
2911						$cursorOuter.css({
2912							width: thisBox.width,
2913							height: thisBox.height,
2914							'border-radius': $(this).css('border-radius')
2915						}).addClass('cursor-outer-fit');
2916
2917						$cursorInner.addClass('opacity-0');
2918
2919						self.isStuck = true;
2920						break;
2921
2922					case 'plus':
2923						$cursorInner.addClass('cursor-inner-plus');
2924						break;
2925				}
2926			});
2927
2928			$('[data-cursor-effect-hover]').on('mouseleave', function(){
2929				
2930				// Identify Event With Hover Class
2931				$cursorOuter.removeClass('cursor-outer-hover');
2932				$cursorInner.removeClass('cursor-inner-hover');
2933
2934				// Remove Color Class
2935				const hoverColor = $(this).data('cursor-effect-hover-color');
2936				$cursorOuter.removeClass( 'cursor-color-' + hoverColor );
2937				$cursorInner.removeClass( 'cursor-color-' + hoverColor );
2938
2939				// Effect Types
2940				switch ( $(this).data('cursor-effect-hover') ) {
2941					case 'fit':
2942						$cursorOuter.css({
2943							width: initialCursorOuterBox.width,
2944							height: initialCursorOuterBox.height,
2945							'border-radius': initialCursorOuterRadius
2946						}).removeClass('cursor-outer-fit');
2947
2948						$cursorInner.removeClass('opacity-0');
2949
2950						self.isStuck = false;
2951						break;
2952
2953					case 'plus':
2954						$cursorInner.removeClass('cursor-inner-plus');
2955						break;
2956				}
2957			});
2958
2959			$(window).on('scroll', () => {
2960				if( $cursorOuter.hasClass('cursor-outer-fit') ) {
2961					$cursorOuter.addClass('opacity-0').removeClass('cursor-outer-fit');
2962				}
2963			});
2964
2965			return this;
2966		}
2967
2968        destroy() {
2969			const self = this;
2970
2971			self.$el.removeClass('hide-mouse-cursor cursor-effect-size-small cursor-effect-size-big cursor-effect-style-square');		
2972
2973			cancelAnimationFrame( self.loop );
2974			cancelAnimationFrame( self.loopInside );
2975
2976			document.querySelector('.cursor-outer').remove();
2977			document.querySelector('.cursor-inner').remove();
2978
2979			self.$el.removeData( instanceName, self );
2980		}
2981    }
2982
2983    PluginCursorEffect.defaults = {
2984
2985	}
2986
2987    // expose to scope
2988    $.extend(theme, {
2989		PluginCursorEffect
2990	});
2991
2992    // jquery plugin
2993    $.fn.themePluginCursorEffect = function(opts) {
2994		return this.map(function() {
2995			const $this = $(this);
2996
2997			if ($this.data(instanceName)) {
2998				return $this.data(instanceName);
2999			} else {
3000				return new PluginCursorEffect($this, opts);
3001			}
3002
3003		});
3004	}
3005})).apply(this, [window.theme, jQuery]);
3006
3007// Float Element
3008(((theme = {}, $) => {
3009    const instanceName = '__floatElement';
3010
3011    class PluginFloatElement {
3012        constructor($el, opts) {
3013            return this.initialize($el, opts);
3014        }
3015
3016        initialize($el, opts) {
3017			if ($el.data(instanceName)) {
3018				return this;
3019			}
3020
3021			this.$el = $el;
3022
3023			this
3024				.setData()
3025				.setOptions(opts)
3026				.build();
3027
3028			return this;
3029		}
3030
3031        setData() {
3032			this.$el.data(instanceName, this);
3033
3034			return this;
3035		}
3036
3037        setOptions(opts) {
3038			this.options = $.extend(true, {}, PluginFloatElement.defaults, opts, {
3039				wrapper: this.$el
3040			});
3041
3042			return this;
3043		}
3044
3045        build() {
3046            const self = this;
3047            const $el = this.options.wrapper;
3048            const $window = $(window);
3049            let minus;
3050
3051            // If has floating elements inside a SVG. 
3052            // Intersection Observer API do not check elements inside SVG's, so we need initialize trough top parent SVG
3053            if( $el.data('plugin-float-element-svg') ) {
3054				$el.find('[data-plugin-float-element]').each(function(){
3055                    const $this = $(this);
3056                    let opts;
3057
3058                    const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
3059                    if (pluginOptions)
3060						opts = pluginOptions;
3061
3062                    $this.themePluginFloatElement(opts);
3063                });
3064
3065				return this;
3066			}
3067
3068            if( self.options.style ) {
3069				$el.attr('style', self.options.style);
3070			}
3071
3072            if( $window.width() > self.options.minWindowWidth ) {
3073
3074				// Set Start Position
3075				if( self.options.startPos == 'none' ) {
3076					minus = '';
3077				} else if( self.options.startPos == 'top' ) {
3078					$el.css({
3079						top: 0
3080					});
3081					minus = '';
3082				} else {
3083					$el.css({
3084						bottom: 0
3085					});
3086					minus = '-';
3087				}
3088
3089				// Set Transition
3090				if( self.options.transition ) {
3091					$el.css({
3092						transition: 'ease-out transform '+ self.options.transitionDuration +'ms ' + self.options.transitionDelay + 'ms'
3093					});
3094				}
3095
3096				// First Load
3097				self.movement(minus);	
3098
3099				// Scroll
3100				$window.on('scroll', () => {
3101					self.movement(minus);				   
3102				});
3103
3104			}
3105
3106            return this;
3107        }
3108
3109        movement(minus) {
3110			const self = this, $el = this.options.wrapper, $window = $(window), scrollTop = $window.scrollTop(), elementOffset = $el.offset().top, currentElementOffset = (elementOffset - scrollTop), factor = ( self.options.isInsideSVG ) ? 2 : 100;
3111
3112		   	const scrollPercent = factor * currentElementOffset / ($window.height());
3113
3114		   	if( $el.visible( true ) ) {
3115
3116		   		if( !self.options.horizontal ) {
3117
3118		   			$el.css({
3119			   			transform: 'translate3d(0, '+ minus + scrollPercent / self.options.speed +'%, 0)'
3120			   		});
3121
3122		   		} else {
3123
3124		   			$el.css({
3125			   			transform: 'translate3d('+ minus + scrollPercent / self.options.speed +'%, 0, 0)'
3126			   		});
3127
3128		   		}
3129		   		
3130		   	}
3131
3132		}
3133    }
3134
3135    PluginFloatElement.defaults = {
3136		startPos: 'top',
3137		speed: 3,
3138		horizontal: false,
3139		isInsideSVG: false,
3140		transition: false,
3141		transitionDelay: 0,
3142		transitionDuration: 500,
3143		minWindowWidth: 991
3144	};
3145
3146    // expose to scope
3147    $.extend(theme, {
3148		PluginFloatElement
3149	});
3150
3151    // jquery plugin
3152    $.fn.themePluginFloatElement = function(opts) {
3153		return this.map(function() {
3154			const $this = $(this);
3155
3156			if ($this.data(instanceName)) {
3157				return $this.data(instanceName);
3158			} else {
3159				return new PluginFloatElement($this, opts);
3160			}
3161
3162		});
3163	}
3164})).apply(this, [window.theme, jQuery]);
3165
3166// GDPR
3167(((theme = {}, $) => {
3168    const instanceName = '__gdpr';
3169
3170    class PluginGDPR {
3171        constructor($el, opts) {
3172            return this.initialize($el, opts);
3173        }
3174
3175        initialize($el, opts) {
3176			const self = this;
3177
3178			this.$el = $el;
3179
3180			this
3181				.setData()
3182				.setOptions(opts)
3183				.build()
3184				.events();
3185
3186			return this;
3187		}
3188
3189        setData() {
3190			this.$el.data(instanceName, this);
3191
3192			return this;
3193		}
3194
3195        setOptions(opts) {
3196			this.options = $.extend(true, {}, PluginGDPR.defaults, opts, {
3197				wrapper: this.$el
3198			});
3199
3200			return this;
3201		}
3202
3203        build() {
3204			const self = this;
3205
3206			// Show
3207			if( !$.cookie( 'porto-privacy-bar' ) ) {
3208				setTimeout(() => {
3209					self.options.wrapper.addClass('show');
3210				}, self.options.cookieBarShowDelay);
3211			}
3212
3213			// If already has preferences cookie, check inputs according preferences cookie data
3214			if( $.cookie( 'porto-gdpr-preferences' ) ) {
3215				const preferencesArr = $.cookie( 'porto-gdpr-preferences' ).split(',');
3216
3217				for( let i = 0; i < preferencesArr.length; i++ ) {
3218					if( $('input[value="'+ preferencesArr[i] +'"]').get(0) ) {
3219						if( $('input[value="'+ preferencesArr[i] +'"]').is(':checkbox') ) {
3220							$('input[value="'+ preferencesArr[i] +'"]').prop('checked', true);
3221						}
3222					}
3223				}
3224			}
3225
3226			return this;
3227
3228		}
3229
3230        events() {
3231			const self = this;
3232
3233			// Agree Trigger
3234			self.options.wrapper.find('.gdpr-agree-trigger').on('click', e => {
3235				e.preventDefault();
3236
3237				$('.gdpr-preferences-form').find('.gdpr-input').each(function(){
3238					if( $(this).is(':checkbox') || $(this).is(':hidden') ) {
3239						$(this).prop('checked', true);
3240					}
3241				});
3242
3243				$('.gdpr-preferences-form').trigger('submit').removeClass('show');
3244
3245				self.removeCookieBar();
3246			});
3247
3248			// Preferences Trigger
3249			self.options.wrapper.find('.gdpr-preferences-trigger').on('click', e => {
3250				e.preventDefault();
3251
3252				$('.gdpr-preferences-popup').addClass('show');
3253			});
3254
3255			// Close Popup Button
3256			$('.gdpr-close-popup').on('click', e => {
3257				e.preventDefault();
3258
3259				$('.gdpr-preferences-popup').removeClass('show');
3260			});
3261
3262			// Close Popup When Click Outside of popup area
3263			$('.gdpr-preferences-popup').on('click', ({target}) => {
3264				if( !$(target).closest('.gdpr-preferences-popup-content').get(0) ) {
3265					$('.gdpr-preferences-popup').removeClass('show');
3266				}
3267			});
3268
3269			// Preference Form
3270			$('.gdpr-preferences-form').on('submit', function(e){
3271				e.preventDefault();
3272
3273				const $this = $(this);
3274
3275				// Save Preferences Button
3276				$this.find('button[type="submit"]').text( 'SAVING...' );
3277
3278				// Form Data
3279				const formData = [];
3280				$this.find('.gdpr-input').each(function(){
3281					if( $(this).is(':checkbox') && $(this).is(':checked') || $(this).is(':hidden') ) {
3282						formData.push( $(this).val() );
3283					}
3284				});
3285
3286				$.cookie( 'porto-privacy-bar', true, {expires: self.options.expires} );
3287
3288				setTimeout(() => {
3289					$this.find('button[type="submit"]').text( 'SAVED!' ).removeClass('btn-primary').addClass('btn-success');
3290
3291					setTimeout(() => {
3292						$('.gdpr-preferences-popup').removeClass('show');
3293						self.removeCookieBar();
3294
3295						$this.find('button[type="submit"]').text( 'SAVE PREFERENCES' ).removeClass('btn-success').addClass('btn-primary');
3296
3297						if( $.cookie( 'porto-gdpr-preferences' ) ) {
3298
3299							$.cookie( 'porto-gdpr-preferences', formData, {expires: self.options.expires} );
3300							location.reload();
3301
3302						} else {
3303
3304							$.cookie( 'porto-gdpr-preferences', formData, {expires: self.options.expires} );
3305
3306							if ($.isFunction($.fn['themePluginGDPRWrapper']) && $('[data-plugin-gdpr-wrapper]').length) {
3307
3308								$(() => {
3309									$('[data-plugin-gdpr-wrapper]:not(.manual)').each(function() {
3310                                        const $this = $(this);
3311                                        let opts;
3312
3313                                        $this.removeData('__gdprwrapper');
3314
3315                                        const pluginOptions = theme.fn.getOptions($this.data('plugin-options'));
3316                                        if (pluginOptions)
3317											opts = pluginOptions;
3318
3319                                        $this.themePluginGDPRWrapper(opts);
3320                                    });
3321								});
3322
3323							}
3324
3325						}
3326
3327					}, 500);
3328				}, 1000);
3329			});
3330
3331			// Remove/Reset Cookies
3332			$('.gdpr-reset-cookies').on('click', e => {
3333				e.preventDefault();
3334
3335				self.clearCookies();
3336
3337				location.reload();
3338			});
3339
3340			// Open Preferences
3341			$('.gdpr-open-preferences').on('click', e => {
3342				e.preventDefault();
3343
3344				$('.gdpr-preferences-popup').toggleClass('show');
3345			});
3346
3347			return this;
3348		}
3349
3350        removeCookieBar() {
3351			const self = this;
3352
3353			self.options.wrapper.addClass('removing').on('transitionend', () => {
3354				setTimeout(() => {
3355					self.options.wrapper.removeClass('show removing');
3356				}, 500);
3357			});
3358
3359			return this;
3360		}
3361
3362        clearCookies() {
3363			const self = this;
3364
3365			$.removeCookie( 'porto-privacy-bar' );
3366			$.removeCookie( 'porto-gdpr-preferences' );
3367
3368			return this;
3369		}
3370    }
3371
3372    PluginGDPR.defaults = {
3373		cookieBarShowDelay: 3000,
3374		expires: 365
3375	};
3376
3377    // expose to scope
3378    $.extend(theme, {
3379		PluginGDPR
3380	});
3381
3382    // jquery plugin
3383    $.fn.themePluginGDPR = function(opts) {
3384		return this.map(function() {
3385			const $this = $(this);
3386
3387			if ($this.data(instanceName)) {
3388				return $this.data(instanceName);
3389			} else {
3390				return new PluginGDPR($this, opts);
3391			}
3392
3393		});
3394	}
3395})).apply(this, [window.theme, jQuery]);
3396
3397// GDPR Wrapper
3398(((theme = {}, $) => {
3399    const instanceName = '__gdprwrapper';
3400
3401    class PluginGDPRWrapper {
3402        constructor($el, opts) {
3403            return this.initialize($el, opts);
3404        }
3405
3406        initialize($el, opts) {
3407			const self = this;
3408
3409			this.$el = $el;
3410
3411			this
3412				.setData()
3413				.setOptions(opts)
3414				.build();
3415				
3416			return this;
3417		}
3418
3419        setData() {
3420			this.$el.data(instanceName, this);
3421
3422			return this;
3423		}
3424
3425        setOptions(opts) {
3426			this.options = $.extend(true, {}, PluginGDPRWrapper.defaults, opts, {
3427				wrapper: this.$el
3428			});
3429
3430			return this;
3431		}
3432
3433        build() {
3434			const self = this;
3435
3436			if( $.cookie( 'porto-gdpr-preferences' ) && $.cookie( 'porto-gdpr-preferences' ).includes(self.options.checkCookie) ) {
3437
3438				$.ajax({
3439					url: self.options.ajaxURL,
3440					cache: false,
3441					complete({responseText}) {
3442					
3443						setTimeout(() => {
3444
3445							self.options.wrapper.html(responseText).addClass('show');
3446
3447						}, 1000);
3448
3449					}
3450				});
3451
3452			} else {
3453				self.options.wrapper.addClass('show');
3454			}
3455
3456			return this;
3457
3458		}
3459    }
3460
3461    PluginGDPRWrapper.defaults = {
3462
3463	};
3464
3465    // expose to scope
3466    $.extend(theme, {
3467		PluginGDPRWrapper
3468	});
3469
3470    // jquery plugin
3471    $.fn.themePluginGDPRWrapper = function(opts) {
3472		return this.map(function() {
3473			const $this = $(this);
3474
3475			if ($this.data(instanceName)) {
3476				return $this.data(instanceName);
3477			} else {
3478				return new PluginGDPRWrapper($this, opts);
3479			}
3480
3481		});
3482	}
3483})).apply(this, [window.theme, jQuery]);
3484
3485// Hover Effect
3486(((theme = {}, $) => {
3487    const instanceName = '__hoverEffect';
3488
3489    class PluginHoverEffect {
3490        constructor($el, opts) {
3491            return this.initialize($el, opts);
3492        }
3493
3494        initialize($el, opts) {
3495			if ($el.data(instanceName)) {
3496				return this;
3497			}
3498
3499			this.$el = $el;
3500
3501			this
3502				.setData()
3503				.setOptions(opts)
3504				.build();
3505
3506			return this;
3507		}
3508
3509        setData() {
3510			this.$el.data(instanceName, this);
3511
3512			return this;
3513		}
3514
3515        setOptions(opts) {
3516			this.options = $.extend(true, {}, PluginHoverEffect.defaults, opts, {
3517				wrapper: this.$el
3518			});
3519
3520			return this;
3521		}
3522
3523        build() {
3524			const self = this;
3525
3526			if(self.$el.hasClass('hover-effect-3d')) {
3527				self.options.effect = '3d';
3528			}
3529
3530			// Magnetic
3531			if(self.options.effect == 'magnetic') {
3532				self.magnetic();
3533			}
3534
3535			// 3d
3536			if(self.options.effect == '3d') {
3537				self.hover3d();
3538			}
3539
3540			return this;
3541		}
3542
3543        magnetic() {
3544			const self = this;
3545
3546			self.$el.mousemove(function({clientX, clientY}) {
3547
3548				const pos = this.getBoundingClientRect();
3549				const mx = clientX - pos.left - pos.width/2; 
3550				const my = clientY - pos.top - pos.height/2;
3551
3552				this.style.transform = 'translate('+ mx * self.options.magneticMx +'px, '+ my * self.options.magneticMx +'px)';
3553
3554			});
3555
3556			self.$el.mouseleave(function(e) {
3557
3558				this.style.transform = 'translate3d(0px, 0px, 0px)';
3559
3560			});
3561
3562			return this;
3563
3564		}
3565
3566        hover3d() {
3567			const self = this;
3568
3569			if ($.isFunction($.fn['hover3d'])) {
3570
3571				self.$el.hover3d({
3572					selector: self.options.selector,
3573					sensitivity: self.options.sensitivity
3574				});
3575
3576			}
3577
3578			return this;
3579
3580		}
3581    }
3582
3583    PluginHoverEffect.defaults = {
3584		effect: 'magnetic',
3585		magneticMx: 0.15,
3586		magneticMy: 0.3,
3587		magneticDeg: 12,
3588		selector: '.thumb-info, .hover-effect-3d-wrapper',
3589		sensitivity: 20
3590	};
3591
3592    // expose to scope
3593    $.extend(theme, {
3594		PluginHoverEffect
3595	});
3596
3597    // jquery plugin
3598    $.fn.themePluginHoverEffect = function(opts) {
3599		return this.map(function() {
3600			const $this = $(this);
3601
3602			if ($this.data(instanceName)) {
3603				return $this.data(instanceName);
3604			} else {
3605				return new PluginHoverEffect($this, opts);
3606			}
3607
3608		});
3609	};
3610})).apply(this, [window.theme, jQuery]);
3611
3612// Icon
3613(((theme = {}, $) => {
3614    const instanceName = '__icon';
3615
3616    class PluginIcon {
3617        constructor($el, opts) {
3618            return this.initialize($el, opts);
3619        }
3620
3621        initialize($el, opts) {
3622			if ($el.data(instanceName)) {
3623				return this;
3624			}
3625
3626			this.$el = $el;
3627
3628			this
3629				.setData()
3630				.setOptions(opts)
3631				.build();
3632
3633			return this;
3634		}
3635
3636        setData() {
3637			this.$el.data(instanceName, this);
3638
3639			return this;
3640		}
3641
3642        setOptions(opts) {
3643			this.options = $.extend(true, {}, PluginIcon.defaults, opts, {
3644				wrapper: this.$el
3645			});
3646
3647			return this;
3648		}
3649
3650        build() {
3651            const self  	 = this;
3652            let $el   	 = this.options.wrapper;
3653            const color 	 = self.options.color;
3654            const elTopDistance = $el.offset().top;
3655            const windowTopDistance = $(window).scrollTop();
3656            let duration = ( self.options.animated && !self.options.strokeBased ) ? 200 : 100;
3657
3658            // Check origin
3659            if( window.location.protocol === 'file:' ) {
3660				$el.css({
3661					opacity: 1,
3662					width: $el.attr('width')
3663				});
3664
3665				if( self.options.extraClass ) {
3666					$el.addClass( self.options.extraClass );
3667				}
3668
3669				if( self.options.extraClass.indexOf('-color-light') > 0 ) {
3670					$el.css({
3671						filter: 'invert(1)'
3672					});
3673				}
3674
3675				$(window).trigger('icon.rendered');
3676				return;
3677			}
3678
3679            // Duration
3680            if( self.options.duration ) {
3681				duration = self.options.duration;
3682			}
3683
3684            // SVG Content
3685			const fileName = $el.attr('src');
3686
3687			if(fileName.split('.').pop() == 'svg') {
3688				const SVGContent = $.get({
3689					url: fileName, 
3690					success(data, status, {responseText}) {
3691						const iconWrapper = self.options.fadeIn ? $('<div class="animated-icon animated fadeIn">'+ responseText +'</div>') : $('<div class="animated-icon animated">'+ responseText +'</div>'), uniqid = 'icon_' + Math.floor(Math.random() * 26) + Date.now();
3692
3693						// Add ID
3694						iconWrapper.find('svg').attr('id', uniqid);
3695
3696						// Identify with filename
3697						iconWrapper.find('svg').attr('data-filename', $el.attr('src').split(/(\\|\/)/g).pop());
3698
3699						if( $el.attr('width') ) {
3700							iconWrapper.find('svg')
3701								.attr('width', $el.attr('width'))
3702								.attr('height', $el.attr('width'));						
3703						}
3704
3705						if( $el.attr('height') ) {
3706							iconWrapper.find('svg')
3707								.attr('height', $el.attr('height'));	
3708						}
3709
3710						if( self.options.svgViewBox ) {
3711							iconWrapper.find('svg')
3712								.attr('viewBox', self.options.svgViewBox);
3713						}
3714
3715						$el.replaceWith(iconWrapper);
3716
3717						if( self.options.extraClass ) {
3718							iconWrapper.addClass( self.options.extraClass );
3719						}
3720
3721						if( self.options.removeClassAfterInit ) {
3722							iconWrapper.removeClass(self.options.removeClassAfterInit);
3723						}
3724
3725						if( self.options.onlySVG ) {
3726							$(window).trigger('icon.rendered');
3727							return this;
3728						}
3729
3730						$el = iconWrapper;
3731
3732						const icon = new Vivus(uniqid, {start: 'manual', type: 'sync', selfDestroy: true, duration, onReady({el}) {
3733							const styleElement = document.createElementNS("http://www.w3.org/2000/svg", "style");
3734							let animateStyle = '';
3735
3736							// SVG Fill Based
3737							if( self.options.animated && !self.options.strokeBased || !self.options.animated && color && !self.options.strokeBased ) {
3738								animateStyle = 'stroke-width: 0.1px; fill-opacity: 0; transition: ease fill-opacity 300ms;';
3739								
3740								// Set Style on SVG inside object
3741								styleElement.textContent = '#' + uniqid + ' path, #' + uniqid + ' line, #' + uniqid + ' rect, #' + uniqid + ' circle, #' + uniqid + ' polyline { fill: '+ color +'; stroke: '+ color +'; '+ animateStyle + (self.options.svgStyle ? self.options.svgStyle : "") + ' } .finished path { fill-opacity: 1; }';
3742								el.appendChild(styleElement);
3743							}
3744
3745							// SVG Stroke Based
3746							if( self.options.animated && self.options.strokeBased || !self.options.animated && color && self.options.strokeBased ) {
3747
3748								// Set Style on SVG inside object
3749								styleElement.textContent = '#' + uniqid + ' path, #' + uniqid + ' line, #' + uniqid + ' rect, #' + uniqid + ' circle, #' + uniqid + ' polyline { stroke: '+ color +'; ' + (self.options.svgStyle ? self.options.svgStyle : "") + '}';
3750								el.appendChild(styleElement);
3751							}
3752
3753							$.event.trigger('theme.plugin.icon.svg.ready');
3754						}});
3755
3756						// Isn't animated
3757						if( !self.options.animated ) {
3758							setTimeout(() => {
3759								icon.finish();
3760							}, 10);
3761							$el.css({ opacity: 1 });
3762						}
3763
3764						// Animated
3765						if( self.options.animated && $(window).width() > 767 ) {
3766							
3767							// First Load
3768							if( $el.visible( true ) ) {
3769								self.startIconAnimation( icon, $el );
3770							} else if( elTopDistance < windowTopDistance ) {
3771								self.startIconAnimation( icon, $el );
3772							}
3773
3774							// On Scroll
3775							$(window).on('scroll', () => {
3776								if( $el.visible( true ) ) {
3777									self.startIconAnimation( icon, $el );
3778								}
3779							});
3780
3781						} else {
3782							
3783							$el.css({ opacity: 1 });
3784							icon.finish();
3785							
3786							$(window).on('theme.plugin.icon.svg.ready', () => {
3787								setTimeout(() => {
3788									icon.el.setAttribute('class', 'finished');
3789									icon.finish();
3790								}, 300);
3791							});
3792							
3793						}
3794
3795						$(window).trigger('icon.rendered');
3796					}
3797				});
3798			} else {
3799				$el.removeAttr('data-icon');
3800			}
3801
3802            return this;
3803        }
3804
3805        startIconAnimation(icon, $el) {
3806			const self = this;
3807
3808			// Animate for better performance
3809			$({to:0}).animate({to:1}, ((self.options.strokeBased) ? self.options.delay : self.options.delay + 300 ), () => {
3810				$el.css({ opacity: 1 });
3811			});
3812
3813			$({to:0}).animate({to:1}, self.options.delay, () => {
3814				icon.play(1);
3815
3816				setTimeout(() => {
3817					icon.el.setAttribute('class', 'finished');
3818				}, icon.duration * 5 );
3819			});
3820		}
3821    }
3822
3823    PluginIcon.defaults = {
3824		color: '#2388ED',
3825		animated: false,
3826		delay: 300,
3827		onlySVG: false,
3828		removeClassAfterInit: false,
3829		fadeIn: true,
3830		accY: 0
3831	};
3832
3833    // expose to scope
3834    $.extend(theme, {
3835		PluginIcon
3836	});
3837
3838    // jquery plugin
3839    $.fn.themePluginIcon = function(opts) {
3840		return this.map(function() {
3841			const $this = $(this);
3842
3843			if ($this.data(instanceName)) {
3844				return $this.data(instanceName);
3845			} else {
3846				return new PluginIcon($this, opts);
3847			}
3848
3849		});
3850	};
3851})).apply(this, [window.theme, jQuery]);
3852
3853// In Viewport Style
3854(((theme = {}, $) => {
3855    const instanceName = '__inviewportstyle';
3856
3857    class PluginInViewportStyle {
3858        constructor($el, opts) {
3859            return this.initialize($el, opts);
3860        }
3861
3862        initialize($el, opts) {
3863			if ($el.data(instanceName)) {
3864				return this;
3865			}
3866
3867			this.$el = $el;
3868
3869			this
3870				.setData()
3871				.setOptions(opts)
3872				.build();
3873
3874			return this;
3875		}
3876
3877        setData() {
3878			this.$el.data(instanceName, this);
3879
3880			return this;
3881		}
3882
3883        setOptions(opts) {
3884			this.options = $.extend(true, {}, PluginInViewportStyle.defaults, opts, {});
3885
3886			return this;
3887		}
3888
3889        build() {
3890			const self = this, el = self.$el.get(0);
3891
3892			self.$el.css(self.options.style);
3893
3894		    if (typeof window.IntersectionObserver === 'function') {
3895			    const un = observeElementInViewport.observeElementInViewport(
3896			        el, () => {
3897			        	self.$el.css(self.options.styleIn);
3898			        	self.$el
3899			        		.addClass(self.options.classIn)
3900			        		.removeClass(self.options.classOut);
3901			        }, () => {
3902			        	self.$el.css(self.options.styleOut);
3903			        	self.$el
3904			        		.addClass(self.options.classOut)
3905			        		.removeClass(self.options.classIn);
3906			        }, {
3907			        	viewport: self.options.viewport, 
3908			            threshold: self.options.threshold,
3909						modTop: self.options.modTop,
3910						modBottom: self.options.modBottom
3911			        }
3912			    )
3913		    };
3914
3915			return this;
3916		}
3917    }
3918
3919    PluginInViewportStyle.defaults = {
3920		viewport: window, 
3921		threshold: [0],
3922		modTop: '-200px',
3923		modBottom: '-200px',
3924		style: {'transition': 'all 1s ease-in-out'},
3925		styleIn: '',
3926		styleOut: '',
3927		classIn: '',
3928		classOut: ''
3929	};
3930
3931    // expose to scope
3932    $.extend(theme, {
3933		PluginInViewportStyle
3934	});
3935
3936    // jquery plugin
3937    $.fn.themePluginInViewportStyle = function(opts) {
3938		return this.map(function() {
3939			const $this = $(this);
3940
3941			if ($this.data(instanceName)) {
3942				return $this.data(instanceName);
3943			} else {
3944				return new PluginInViewportStyle($this, opts);
3945			}
3946
3947		});
3948	}
3949})).apply(this, [window.theme, jQuery]);
3950
3951// Lightbox
3952(((theme = {}, $) => {
3953    const instanceName = '__lightbox';
3954
3955    class PluginLightbox {
3956        constructor($el, opts) {
3957            return this.initialize($el, opts);
3958        }
3959
3960        initialize($el, opts) {
3961			if ($el.data(instanceName)) {
3962				return this;
3963			}
3964
3965			this.$el = $el;
3966
3967			this
3968				.setData()
3969				.setOptions(opts)
3970				.build();
3971
3972			return this;
3973		}
3974
3975        setData() {
3976			this.$el.data(instanceName, this);
3977
3978			return this;
3979		}
3980
3981        setOptions(opts) {
3982			this.options = $.extend(true, {}, PluginLightbox.defaults, opts, {
3983				wrapper: this.$el
3984			});
3985
3986			return this;
3987		}
3988
3989        build() {
3990			if (!($.isFunction($.fn.magnificPopup))) {
3991				return this;
3992			}
3993
3994			this.options.wrapper.magnificPopup(this.options);
3995
3996			return this;
3997		}
3998    }
3999
4000    PluginLightbox.defaults = {
4001		tClose: 'Close (Esc)', // Alt text on close button
4002		tLoading: 'Loading...', // Text that is displayed during loading. Can contain %curr% and %total% keys
4003		gallery: {
4004			tPrev: 'Previous (Left arrow key)', // Alt text on left arrow
4005			tNext: 'Next (Right arrow key)', // Alt text on right arrow
4006			tCounter: '%curr% of %total%' // Markup for "1 of 7" counter
4007		},
4008		image: {
4009			tError: '<a href="%url%">The image</a> could not be loaded.' // Error message when image could not be loaded
4010		},
4011		ajax: {
4012			tError: '<a href="%url%">The content</a> could not be loaded.' // Error message when ajax request failed
4013		},
4014		callbacks: {
4015			open() {
4016				$('html').addClass('lightbox-opened');
4017			},
4018			close() {
4019				$('html').removeClass('lightbox-opened');
4020			}
4021		}
4022	};
4023
4024    // expose to scope
4025    $.extend(theme, {
4026		PluginLightbox
4027	});
4028
4029    // jquery plugin
4030    $.fn.themePluginLightbox = function(opts) {
4031		return this.map(function() {
4032			const $this = $(this);
4033
4034			if ($this.data(instanceName)) {
4035				return $this.data(instanceName);
4036			} else {
4037				return new PluginLightbox($this, opts);
4038			}
4039
4040		});
4041	}
4042})).apply(this, [window.theme, jQuery]);
4043
4044// Loading Overlay
4045(((theme = {}, $) => {
4046    // Default
4047    const loadingOverlayDefaultTemplate = [
4048		'<div class="loading-overlay">',
4049			'<div class="bounce-loader"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>',
4050		'</div>'
4051	].join('');
4052
4053    // Percentage
4054    const loadingOverlayPercentageTemplate = [
4055		'<div class="loading-overlay loading-overlay-percentage">',
4056			'<div class="page-loader-progress-wrapper"><span class="page-loader-progress">0</span><span class="page-loader-progress-symbol">%</span></div>',
4057		'</div>'
4058	].join('');
4059
4060    // Cubes
4061    const loadingOverlayCubesTemplate = [
4062		'<div class="loading-overlay">',
4063			'<div class="bounce-loader"><div class="cssload-thecube"><div class="cssload-cube cssload-c1"></div><div class="cssload-cube cssload-c2"></div><div class="cssload-cube cssload-c4"></div><div class="cssload-cube cssload-c3"></div></div></div>',
4064		'</div>'
4065	].join('');
4066
4067    // Cube Progress
4068    const loadingOverlayCubeProgressTemplate = [
4069		'<div class="loading-overlay">',
4070			'<div class="bounce-loader"><span class="cssload-cube-progress"><span class="cssload-cube-progress-inner"></span></span></div>',
4071		'</div>'
4072	].join('');
4073
4074    // Float Rings
4075    const loadingOverlayFloatRingsTemplate = [
4076		'<div class="loading-overlay">',
4077			'<div class="bounce-loader"><div class="cssload-float-rings-loader"><div class="cssload-float-rings-inner cssload-one"></div><div class="cssload-float-rings-inner cssload-two"></div><div class="cssload-float-rings-inner cssload-three"></div></div></div>',
4078		'</div>'
4079	].join('');
4080
4081    // Floating Bars
4082    const loadingOverlayFloatBarsTemplate = [
4083		'<div class="loading-overlay">',
4084			'<div class="bounce-loader"><div class="cssload-float-bars-container"><ul class="cssload-float-bars-flex-container"><li><span class="cssload-float-bars-loading"></span></li></div></div></div>',
4085		'</div>'
4086	].join('');
4087
4088    // Speeding Wheel
4089    const loadingOverlaySpeedingWheelTemplate = [
4090		'<div class="loading-overlay">',
4091			'<div class="bounce-loader"><div class="cssload-speeding-wheel-container"><div class="cssload-speeding-wheel"></div></div></div>',
4092		'</div>'
4093	].join('');
4094
4095    // Zenith
4096    const loadingOverlayZenithTemplate = [
4097		'<div class="loading-overlay">',
4098			'<div class="bounce-loader"><div class="cssload-zenith-container"><div class="cssload-zenith"></div></div></div>',
4099		'</div>'
4100	].join('');
4101
4102    // Spinning Square
4103    const loadingOverlaySpinningSquareTemplate = [
4104		'<div class="loading-overlay">',
4105			'<div class="bounce-loader"><div class="cssload-spinning-square-loading"></div></div>',
4106		'</div>'
4107	].join('');
4108
4109    // Pulse
4110    const loadingOverlayPulseTemplate = [
4111		'<div class="loading-overlay">',
4112			'<div class="bounce-loader"><div class="wrapper-pulse"><div class="cssload-pulse-loader"></div></div></div>',
4113		'</div>'
4114	].join('');
4115
4116    const LoadingOverlay = function( $wrapper, options, noInheritOptions ) {
4117		return this.initialize( $wrapper, options, noInheritOptions );
4118	};
4119
4120    LoadingOverlay.prototype = {
4121
4122		options: {
4123			css: {},
4124			hideDelay: 500,
4125			progressMinTimeout: 0,
4126			effect: 'default'
4127		},
4128
4129		initialize($wrapper, options, noInheritOptions) {
4130			this.$wrapper = $wrapper;
4131
4132			this
4133				.setVars()
4134				.setOptions( options, noInheritOptions )
4135				.build()
4136				.events()
4137				.dynamicShowHideEvents();
4138
4139			this.$wrapper.data( 'loadingOverlay', this );
4140		},
4141
4142		setVars() {
4143			this.$overlay = this.$wrapper.find('.loading-overlay');
4144			this.pageStatus = null;
4145			this.progress = null;
4146			this.animationInterval = 33;
4147
4148			return this;
4149		},
4150
4151		setOptions(options, noInheritOptions) {
4152			if ( !this.$overlay.get(0) ) {
4153				this.matchProperties();
4154			}
4155			
4156			if( noInheritOptions ) {
4157				this.options     = $.extend( true, {}, this.options, options );
4158			} else {
4159				this.options     = $.extend( true, {}, this.options, options, theme.fn.getOptions(this.$wrapper.data('plugin-options')) );
4160			}
4161
4162			this.loaderClass = this.getLoaderClass( this.options.css.backgroundColor );
4163
4164			return this;
4165		},
4166
4167		build() {
4168			const _self = this;
4169
4170			if ( !this.$overlay.closest(document.documentElement).get(0) ) {
4171				if ( !this.$cachedOverlay ) {
4172
4173					switch ( _self.options.effect ) {
4174						case 'percentageProgress1':
4175							this.$overlay = $( loadingOverlayPercentageTemplate ).clone();
4176							break;
4177
4178						case 'percentageProgress2':
4179							this.$overlay = $( loadingOverlayPercentageTemplate ).clone();
4180							this.$overlay
4181								.addClass('loading-overlay-percentage-effect-2')
4182								.prepend('<div class="loading-overlay-background-layer"></div>');
4183							break;
4184
4185						case 'cubes':
4186							this.$overlay = $( loadingOverlayCubesTemplate ).clone();
4187							break;
4188
4189						case 'cubeProgress':
4190							this.$overlay = $( loadingOverlayCubeProgressTemplate ).clone();
4191							break;
4192
4193						case 'floatRings':
4194							this.$overlay = $( loadingOverlayFloatRingsTemplate ).clone();
4195							break;
4196
4197						case 'floatBars':
4198							this.$overlay = $( loadingOverlayFloatBarsTemplate ).clone();
4199							break;
4200
4201						case 'speedingWheel':
4202							this.$overlay = $( loadingOverlaySpeedingWheelTemplate ).clone();
4203							break;
4204
4205						case 'zenith':
4206							this.$overlay = $( loadingOverlayZenithTemplate ).clone();
4207							break;
4208
4209						case 'spinningSquare':
4210							this.$overlay = $( loadingOverlaySpinningSquareTemplate ).clone();
4211							break;
4212
4213						case 'pulse':
4214							this.$overlay = $( loadingOverlayPulseTemplate ).clone();
4215							break;
4216
4217						case 'default':
4218						default:
4219							this.$overlay = $( loadingOverlayDefaultTemplate ).clone();
4220							break;
4221					}
4222					
4223					if ( this.options.css ) {
4224						this.$overlay.css( this.options.css );
4225						this.$overlay.find( '.loader' ).addClass( this.loaderClass );
4226					}
4227				} else {
4228					this.$overlay = this.$cachedOverlay.clone();
4229				}
4230
4231				this.$wrapper.prepend( this.$overlay );
4232			}
4233
4234			if ( !this.$cachedOverlay ) {
4235				this.$cachedOverlay = this.$overlay.clone();
4236			}
4237
4238			if( ['percentageProgress1', 'percentageProgress2'].includes(_self.options.effect) ) {
4239				_self.updateProgress();
4240
4241				if( _self.options.isDynamicHideShow ) {
4242					setTimeout(() => {
4243						_self.progress = 'complete';
4244						
4245						$('.page-loader-progress').text(100);
4246
4247						if( ['percentageProgress2'].includes(_self.options.effect) ) {
4248			            	$('.loading-overlay-background-layer').css({
4249			            		width: '100%'
4250			            	});
4251			            }
4252					}, 2800);
4253				}
4254			}
4255
4256			return this;
4257		},
4258
4259		events() {
4260			const _self = this;
4261
4262			if ( this.options.startShowing ) {
4263				_self.show();
4264			}
4265
4266			if ( this.$wrapper.is('body') || this.options.hideOnWindowLoad ) {
4267				$( window ).on( 'load error', () => {
4268					setTimeout(() => {
4269						_self.hide();
4270					}, _self.options.progressMinTimeout);
4271				});
4272			}
4273
4274			if ( this.options.listenOn ) {
4275				$( this.options.listenOn )
4276					.on( 'loading-overlay:show beforeSend.ic', e => {
4277						e.stopPropagation();
4278						_self.show();
4279					})
4280					.on( 'loading-overlay:hide complete.ic', e => {
4281						e.stopPropagation();
4282						_self.hide();
4283					});
4284			}
4285
4286			this.$wrapper
4287				.on( 'loading-overlay:show beforeSend.ic', e => {
4288					if ( e.target === _self.$wrapper.get(0) ) {
4289						e.stopPropagation();
4290						_self.show();
4291						return true;
4292					}
4293					return false;
4294				})
4295				.on( 'loading-overlay:hide complete.ic', e => {
4296					if ( e.target === _self.$wrapper.get(0) ) {
4297						e.stopPropagation();
4298						_self.hide();
4299						return true;
4300					}
4301					return false;
4302				});
4303
4304			if( ['percentageProgress1', 'percentageProgress2'].includes(_self.options.effect) ) {
4305				$(window).on('load', () => {
4306		            setTimeout(() => {
4307			            _self.pageStatus = "complete";
4308
4309			            $('.page-loader-progress').text(100);
4310
4311			            if( ['percentageProgress2'].includes(_self.options.effect) ) {
4312			            	$('.loading-overlay-background-layer').css({
4313			            		width: '100%'
4314			            	});
4315			            }
4316		            }, _self.options.progressMinTimeout);
4317				});
4318			}
4319		        
4320			return this;
4321		},
4322
4323		show() {
4324			this.build();
4325
4326			this.position = this.$wrapper.css( 'position' ).toLowerCase();
4327			if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
4328				this.$wrapper.css({
4329					position: 'relative'
4330				});
4331			}
4332			this.$wrapper.addClass( 'loading-overlay-showing' );
4333		},
4334
4335		hide() {
4336			const _self = this;
4337
4338			setTimeout(function() {
4339				_self.$wrapper.removeClass( 'loading-overlay-showing' );
4340				
4341				if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
4342					_self.$wrapper.css({ position: '' });
4343				}
4344
4345				$(window).trigger('loading.overlay.ready');
4346			}, _self.options.hideDelay);
4347		},
4348
4349		updateProgress() {
4350			const _self = this;
4351
4352			const render = () => {
4353				if(_self.pageStatus == "complete"){
4354		            $('.page-loader-progress').text(100);
4355		            setTimeout(() => {
4356		                $('.page-loader-progress').addClass('d-none');    
4357		            }, 700);
4358		        }
4359		        else{            
4360		            if(_self.progress == null){
4361		                _self.progress = 1;
4362		            }
4363		           
4364		            _self.progress = _self.progress + 1;
4365		            if(_self.progress >= 0 && _self.progress <= 30){
4366		                _self.animationInterval += 1;
4367		                $('.page-loader-progress').text(_self.progress);
4368		            }
4369		            else if(_self.progress > 30 && _self.progress <= 60){
4370		                _self.animationInterval += 2;
4371		                $('.page-loader-progress').text(_self.progress);
4372		            }
4373		            else if(_self.progress > 60 && _self.progress <= 80){
4374		                _self.animationInterval += 40;
4375		                $('.page-loader-progress').text(_self.progress);
4376		            }
4377		            else if(_self.progress > 80 && _self.progress <= 90){
4378		                _self.animationInterval += 80;
4379		                $('.page-loader-progress').text(_self.progress);
4380		            }
4381		            else if(_self.progress > 90 && _self.progress <= 95){
4382		                _self.animationInterval += 150;
4383		                $('.page-loader-progress').text(_self.progress);
4384		            }
4385		            else if(_self.progress > 95 && _self.progress <= 99){
4386		                _self.animationInterval += 400;
4387		                $('.page-loader-progress').text(_self.progress);
4388		            }
4389		            else if(_self.progress >= 100){
4390		                $('.page-loader-progress').text(99);
4391		            }
4392
4393		            if( ['percentageProgress2'].includes(_self.options.effect) ) {
4394		            	$('.loading-overlay-background-layer').css({
4395		            		width: _self.progress + '%'
4396		            	});
4397		            }
4398		              
4399					self.loopInside = setTimeout(render, _self.animationInterval);
4400		        }
4401
4402			};
4403			render();
4404
4405			return this;
4406		},
4407
4408		matchProperties() {
4409			let i, l, properties;
4410
4411			properties = [
4412				'backgroundColor',
4413				'borderRadius'
4414			];
4415
4416			l = properties.length;
4417
4418			for( i = 0; i < l; i++ ) {
4419				const obj = {};
4420				obj[ properties[ i ] ] = this.$wrapper.css( properties[ i ] );
4421
4422				$.extend( this.options.css, obj );
4423			}
4424		},
4425
4426		getLoaderClass(backgroundColor) {
4427			if ( !backgroundColor || backgroundColor === 'transparent' || backgroundColor === 'inherit' ) {
4428				return 'black';
4429			}
4430
4431			let hexColor, r, g, b, yiq;
4432
4433			const colorToHex = color => {
4434				let hex, rgb;
4435
4436				if( color.includes('#') ){
4437					hex = color.replace('#', '');
4438				} else {
4439					rgb = color.match(/\d+/g);
4440					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);
4441				}
4442
4443				if ( hex.length === 3 ) {
4444					hex = hex + hex;
4445				}
4446
4447				return hex;
4448			};
4449
4450			hexColor = colorToHex( backgroundColor );
4451
4452			r = parseInt( hexColor.substr( 0, 2), 16 );
4453			g = parseInt( hexColor.substr( 2, 2), 16 );
4454			b = parseInt( hexColor.substr( 4, 2), 16 );
4455			yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
4456
4457			return ( yiq >= 128 ) ? 'black' : 'white';
4458		},
4459
4460		dynamicShowHide(effect) {
4461			const _self = this;
4462
4463			// Remove Loading Overlay Data
4464			$('body').removeData('loadingOverlay');
4465
4466			// Remove Html Of Loading Overlay
4467			$('.loading-overlay').remove();
4468
4469			if( effect == '' ) {
4470				return this;
4471			}
4472
4473			// Initialize New Loading Overlay (second parameter is to NO inherit data-plugin-options)
4474			$('body').loadingOverlay({
4475				effect: effect ? effect : 'pulse',
4476				isDynamicHideShow: true
4477			}, true);
4478
4479			// Show Loading Overlay Loader
4480			$('body').data('loadingOverlay').show();
4481
4482			// Hide Loading Overlay Loader
4483			setTimeout(() => {
4484				$('body').data('loadingOverlay').hide();
4485			}, 3000);
4486
4487			return this;
4488		},
4489
4490		dynamicShowHideEvents() {
4491			const _self = this;
4492
4493			// Button
4494			$(document).off('click.loading-overlay-button').on('click.loading-overlay-button', '.loading-overlay-button', function(e){
4495				e.preventDefault();
4496
4497				_self.dynamicShowHide( $(this).data('effect') );
4498			});
4499
4500			// Select
4501			$(document).off('change.loading-overlay-select').on('change.loading-overlay-select', '.loading-overlay-select', function(){
4502				_self.dynamicShowHide( $(this).val() );
4503			});
4504
4505			return this;
4506		}
4507
4508	};
4509
4510    // expose to scope
4511    $.extend(theme, {
4512		LoadingOverlay
4513	});
4514
4515    // expose as a jquery plugin
4516    $.fn.loadingOverlay = function( opts, noInheritOptions ) {
4517		return this.each(function() {
4518			const $this = $( this );
4519
4520			const loadingOverlay = $this.data( 'loadingOverlay' );
4521			if ( loadingOverlay ) {
4522				return loadingOverlay;
4523			} else {
4524				const options = opts || $this.data( 'loading-overlay-options' ) || {};
4525				return new LoadingOverlay( $this, options, noInheritOptions );
4526			}
4527		});
4528	}
4529
4530    // auto init
4531    $('[data-loading-overlay]').loadingOverlay();
4532})).apply(this, [window.theme, jQuery]);
4533
4534// Masonry
4535(((theme = {}, $) => {
4536    const instanceName = '__masonry';
4537
4538    class PluginMasonry {
4539        constructor($el, opts) {
4540            return this.initialize($el, opts);
4541        }
4542
4543        initialize($el, opts) {
4544			if ($el.data(instanceName)) {
4545				return this;
4546			}
4547
4548			this.$el = $el;
4549
4550			this
4551				.setData()
4552				.setOptions(opts)
4553				.build();
4554
4555			return this;
4556		}
4557
4558        setData() {
4559			this.$el.data(instanceName, this);
4560
4561			return this;
4562		}
4563
4564        setOptions(opts) {
4565			this.options = $.extend(true, {}, PluginMasonry.defaults, opts, {
4566				wrapper: this.$el
4567			});
4568
4569			return this;
4570		}
4571
4572        build() {
4573			if (!($.isFunction($.fn.isotope))) {
4574				return this;
4575			}
4576
4577			const self = this, $window = $(window);
4578
4579			self.$loader = false;
4580
4581			if (self.options.wrapper.parents('.masonry-loader').get(0)) {
4582				self.$loader = self.options.wrapper.parents('.masonry-loader');
4583				self.createLoader();
4584			}
4585
4586			self.options.wrapper.one('layoutComplete', (event, laidOutItems) => {
4587				self.removeLoader();
4588			});
4589
4590			self.options.wrapper.waitForImages(() => {
4591				self.options.wrapper.isotope(self.options);	
4592			});
4593
4594			$(window).on('resize', () => {
4595				setTimeout(() => {
4596					self.options.wrapper.isotope('layout');
4597				}, 300);
4598			});
4599
4600			setTimeout(() => {
4601				self.removeLoader();
4602			}, 3000);
4603
4604			return this;
4605		}
4606
4607        createLoader() {
4608			const self = this;
4609
4610			const loaderTemplate = [
4611				'<div class="bounce-loader">',
4612					'<div class="bounce1"></div>',
4613					'<div class="bounce2"></div>',
4614					'<div class="bounce3"></div>',
4615				'</div>'
4616			].join('');
4617
4618			self.$loader.append(loaderTemplate);
4619
4620			return this;
4621		}
4622
4623        removeLoader() {
4624
4625			const self = this;
4626
4627			if (self.$loader) {
4628
4629				self.$loader.removeClass('masonry-loader-showing');
4630
4631				setTimeout(() => {
4632					self.$loader.addClass('masonry-loader-loaded');
4633				}, 300);
4634
4635			}
4636
4637		}
4638    }
4639
4640    PluginMasonry.defaults = {
4641
4642	};
4643
4644    // expose to scope
4645    $.extend(theme, {
4646		PluginMasonry
4647	});
4648
4649    // jquery plugin
4650    $.fn.themePluginMasonry = function(opts) {
4651		return this.map(function() {
4652			const $this = $(this);
4653
4654			if ($this.data(instanceName)) {
4655				return $this.data(instanceName);
4656			} else {
4657				return new PluginMasonry($this, opts);
4658			}
4659
4660		});
4661	}
4662})).apply(this, [window.theme, jQuery]);
4663
4664// Match Height
4665(((theme = {}, $) => {
4666    const instanceName = '__matchHeight';
4667
4668    class PluginMatchHeight {
4669        constructor($el, opts) {
4670            return this.initialize($el, opts);
4671        }
4672
4673        initialize($el, opts) {
4674			if ($el.data(instanceName)) {
4675				return this;
4676			}
4677
4678			this.$el = $el;
4679
4680			this
4681				.setData()
4682				.setOptions(opts)
4683				.build();
4684
4685			return this;
4686		}
4687
4688        setData() {
4689			this.$el.data(instanceName, this);
4690
4691			return this;
4692		}
4693
4694        setOptions(opts) {
4695			this.options = $.extend(true, {}, PluginMatchHeight.defaults, opts, {
4696				wrapper: this.$el
4697			});
4698
4699			return this;
4700		}
4701
4702        build() {
4703			if (!($.isFunction($.fn.matchHeight))) {
4704				return this;
4705			}
4706
4707			const self = this;
4708
4709			self.options.wrapper.matchHeight(self.options);
4710
4711			return this;
4712		}
4713    }
4714
4715    PluginMatchHeight.defaults = {
4716		byRow: true,
4717		property: 'height',
4718		target: null,
4719		remove: false
4720	};
4721
4722    // expose to scope
4723    $.extend(theme, {
4724		PluginMatchHeight
4725	});
4726
4727    // jquery plugin
4728    $.fn.themePluginMatchHeight = function(opts) {
4729		return this.map(function() {
4730			const $this = $(this);
4731
4732			if ($this.data(instanceName)) {
4733				return $this.data(instanceName);
4734			} else {
4735				return new PluginMatchHeight($this, opts);
4736			}
4737
4738		});
4739	}
4740})).apply(this, [window.theme, jQuery]);
4741
4742// Parallax
4743(((theme = {}, $) => {
4744    const instanceName = '__parallax';
4745
4746    class PluginParallax {
4747        constructor($el, opts) {
4748            return this.initialize($el, opts);
4749        }
4750
4751        initialize($el, opts) {
4752			if ($el.data(instanceName)) {
4753				return this;
4754			}
4755
4756			this.$el = $el;
4757
4758			this
4759				.setData()
4760				.setOptions(opts)
4761				.build();
4762
4763			return this;
4764		}
4765
4766        setData() {
4767			this.$el.data(instanceName, this);
4768
4769			return this;
4770		}
4771
4772        setOptions(opts) {
4773			this.options = $.extend(true, {}, PluginParallax.defaults, opts, {
4774				wrapper: this.$el
4775			});
4776
4777			return this;
4778		}
4779
4780        build() {
4781            const self = this;
4782            const $window = $(window);
4783            let offset;
4784            let yPos;
4785            let plxPos;
4786            let background;
4787            let rotateY;
4788
4789            // Mouse Parallax
4790            if( self.options.mouseParallax ) {
4791
4792				$window.mousemove(({clientX, clientY}) => {
4793
4794					$('.parallax-mouse-object', self.options.wrapper).each(function() {
4795
4796				        const moving_value = $( this ).attr('data-value');
4797				        const x = (clientX * moving_value) / 250;
4798				        const y = (clientY * moving_value) / 250;
4799
4800				        $( this ).css('transform', 'translateX(' + x + 'px) translateY(' + y + 'px)');
4801				    });
4802
4803				});
4804
4805				return this;
4806
4807			}
4808
4809            // Scrollable
4810            if( self.options.scrollableParallax && $(window).width() > self.options.scrollableParallaxMinWidth ) {
4811				const $scrollableWrapper = self.options.wrapper.find('.scrollable-parallax-wrapper');
4812
4813				if( $scrollableWrapper.get(0) ) {
4814                    let progress 	 = ( $(window).scrollTop() > ( self.options.wrapper.offset().top + $(window).outerHeight() ) ) ? self.options.cssValueEnd : self.options.cssValueStart;
4815                    const cssValueUnit = self.options.cssValueUnit ? self.options.cssValueUnit : '';
4816
4817                    $scrollableWrapper.css({
4818						'background-image' : 'url(' + self.options.wrapper.data('image-src') + ')',
4819						'background-size' : 'cover',
4820						'background-position' : 'center',
4821						'background-attachment' : 'fixed',
4822						'transition' : 'ease '+ self.options.cssProperty +' '+ self.options.transitionDuration,
4823						'width' : progress + '%'
4824					});
4825
4826                    $(window).on('scroll', e => {
4827						if( self.options.wrapper.visible( true ) ) {
4828							const $window = $(window), scrollTop = $window.scrollTop(), elementOffset = self.options.wrapper.offset().top, currentElementOffset = (elementOffset - scrollTop);
4829
4830						   	const scrollPercent = Math.abs( +( currentElementOffset - $window.height() ) / (self.options.startOffset ? self.options.startOffset : 7) );
4831						 	
4832						 	// Increment progress value according scroll position
4833						 	if( scrollPercent <= self.options.cssValueEnd && progress <= self.options.cssValueEnd ) {
4834						 		progress = self.options.cssValueStart + scrollPercent;
4835						 	}
4836
4837						 	// Adjust CSS end value
4838						 	if( progress > self.options.cssValueEnd ) {
4839						 		progress = self.options.cssValueEnd;
4840						 	}
4841
4842						 	// Adjust CSS start value
4843						 	if( progress < self.options.cssValueStart ) {
4844						 		progress = self.options.cssValueStart;
4845						 	}
4846
4847						 	const styles = {};
4848						 	styles[self.options.cssProperty] = progress + cssValueUnit;
4849
4850							$scrollableWrapper.css(styles);
4851						}
4852					});
4853                }
4854
4855				return;
4856			}
4857
4858            // Create Parallax Element
4859            if( self.options.fadeIn ) {
4860				background = $('<div class="parallax-background fadeIn animated"></div>');
4861			} else {
4862				background = $('<div class="parallax-background"></div>');
4863			}
4864
4865            // Set Style for Parallax Element
4866            background.css({
4867				'background-image' : 'url(' + self.options.wrapper.data('image-src') + ')',
4868				'background-size' : 'cover',
4869				'position' : 'absolute',
4870				'top' : 0,
4871				'left' : 0,
4872				'width' : '100%',
4873				'height' : self.options.parallaxHeight
4874			});
4875
4876            if( self.options.parallaxScale ) {
4877				background.css({
4878					'transition' : 'transform 500ms ease-out'
4879				});
4880			}
4881
4882            // Add Parallax Element on DOM
4883            self.options.wrapper.prepend(background);
4884
4885            // Set Overlfow Hidden and Position Relative to Parallax Wrapper
4886            self.options.wrapper.css({
4887				'position' : 'relative',
4888				'overflow' : 'hidden'
4889			});
4890
4891            // Parallax Effect on Scroll & Resize
4892            const parallaxEffectOnScrolResize = () => {
4893				$window.on('scroll resize', () => {
4894					offset  = self.options.wrapper.offset();
4895					yPos    = -($window.scrollTop() - (offset.top - 100)) / ((self.options.speed + 2 ));
4896					plxPos  = (yPos < 0) ? Math.abs(yPos) : -Math.abs(yPos);
4897					rotateY = ( $('html[dir="rtl"]').get(0) ) ? ' rotateY(180deg)' : ''; // RTL
4898					
4899					offset  = self.options.wrapper.offset();
4900					yPos    = -($window.scrollTop() - (offset.top - 100)) / ((self.options.speed + 2 ));
4901					plxPos  = (yPos < 0) ? Math.abs(yPos) : -Math.abs(yPos);
4902					rotateY = ( $('html[dir="rtl"]').get(0) ) ? ' rotateY(180deg)' : ''; // RTL
4903
4904					if( !self.options.parallaxScale ) {
4905
4906						if( self.options.parallaxDirection == 'bottom' ) {
4907							self.options.offset = 250;
4908						}
4909
4910						let y = ( (plxPos - 50) + (self.options.offset) );
4911						if( self.options.parallaxDirection == 'bottom' ) {
4912							y = ( y < 0 ) ? Math.abs( y ) : -Math.abs( y );
4913						}
4914
4915						background.css({
4916							'transform' : 'translate3d(0, '+ y +'px, 0)' + rotateY,
4917							'background-position-x' : self.options.horizontalPosition
4918						});
4919
4920					} else {
4921                        const scrollTop = $window.scrollTop();
4922                        const elementOffset = self.options.wrapper.offset().top;
4923                        const currentElementOffset = (elementOffset - scrollTop);
4924                        let scrollPercent = Math.abs( +( currentElementOffset - $window.height() ) / (self.options.startOffset ? self.options.startOffset : 7) );
4925
4926                        scrollPercent = parseInt((scrollPercent >= 100) ? 100 : scrollPercent);
4927
4928                        const currentScale = (scrollPercent / 100) * 50;
4929
4930                        if ( !self.options.parallaxScaleInvert ) {
4931							background.css({
4932								'transform' : 'scale(1.' + String(currentScale).padStart(2, '0') + ', 1.' + String(currentScale).padStart(2, '0') + ')'
4933							});
4934						} else {
4935							background.css({
4936								'transform' : 'scale(1.' + String(50 - currentScale).padStart(2, '0') + ', 1.' + String(50 - currentScale).padStart(2, '0') + ')'
4937							});
4938						}
4939                    }
4940				});
4941
4942				$window.trigger('scroll');
4943			};
4944
4945            if (!$.browser.mobile) {
4946				parallaxEffectOnScrolResize();
4947			} else {
4948				if( self.options.enableOnMobile == true ) {
4949					parallaxEffectOnScrolResize();
4950				} else {
4951					self.options.wrapper.addClass('parallax-disabled');
4952				}
4953			}
4954
4955            return this;
4956        }
4957    }
4958
4959    PluginParallax.defaults = {
4960		speed: 1.5,
4961		horizontalPosition: '50%',
4962		offset: 0,
4963		parallaxDirection: 'top',
4964		parallaxHeight: '180%',
4965		parallaxScale: false,
4966		parallaxScaleInvert: false,
4967		scrollableParallax: false,
4968		scrollableParallaxMinWidth: 991,
4969		startOffset: 7,
4970		transitionDuration: '200ms',
4971		cssProperty: 'width',
4972		cssValueStart: 40,
4973		cssValueEnd: 100,
4974		cssValueUnit: 'vw',
4975		mouseParallax: false,
4976		enableOnMobile: true
4977	};
4978
4979    // expose to scope
4980    $.extend(theme, {
4981		PluginParallax
4982	});
4983
4984    // jquery plugin
4985    $.fn.themePluginParallax = function(opts) {
4986		return this.map(function() {
4987			const $this = $(this);
4988
4989			if ($this.data(instanceName)) {
4990				return $this.data(instanceName);
4991			} else {
4992				return new PluginParallax($this, opts);
4993			}
4994
4995		});
4996	}
4997})).apply(this, [window.theme, jQuery]);
4998
4999// Progress Bar
5000(((theme = {}, $) => {
5001    const instanceName = '__progressBar';
5002
5003    class PluginProgressBar {
5004        constructor($el, opts) {
5005            return this.initialize($el, opts);
5006        }
5007
5008        initialize($el, opts) {
5009			if ($el.data(instanceName)) {
5010				return this;
5011			}
5012
5013			this.$el = $el;
5014
5015			this
5016				.setData()
5017				.setOptions(opts)
5018				.build();
5019
5020			return this;
5021		}
5022
5023        setData() {
5024			this.$el.data(instanceName, this);
5025
5026			return this;
5027		}
5028
5029        setOptions(opts) {
5030			this.options = $.extend(true, {}, PluginProgressBar.defaults, opts, {
5031				wrapper: this.$el
5032			});
5033
5034			return this;
5035		}
5036
5037        build() {
5038            const self = this;
5039            const $el = this.options.wrapper;
5040            let delay = 1;
5041
5042            delay = ($el.attr('data-appear-animation-delay') ? $el.attr('data-appear-animation-delay') : self.options.delay);
5043
5044            $el.addClass($el.attr('data-appear-animation'));
5045
5046            setTimeout(() => {
5047
5048				$el.animate({
5049					width: $el.attr('data-appear-progress-animation')
5050				}, 1500, 'easeOutQuad', () => {
5051					$el.find('.progress-bar-tooltip').animate({
5052						opacity: 1
5053					}, 500, 'easeOutQuad');
5054				});
5055
5056			}, delay);
5057
5058            return this;
5059        }
5060    }
5061
5062    PluginProgressBar.defaults = {
5063		accX: 0,
5064		accY: -50,
5065		delay: 1
5066	};
5067
5068    // expose to scope
5069    $.extend(theme, {
5070		PluginProgressBar
5071	});
5072
5073    // jquery plugin
5074    $.fn.themePluginProgressBar = function(opts) {
5075		return this.map(function() {
5076			const $this = $(this);
5077
5078			if ($this.data(instanceName)) {
5079				return $this.data(instanceName);
5080			} else {
5081				return new PluginProgressBar($this, opts);
5082			}
5083
5084		});
5085	}
5086})).apply(this, [window.theme, jQuery]);
5087
5088// Random Images
5089(((theme = {}, $) => {
5090    const instanceName = '__randomimages';
5091
5092    class PluginRandomImages {
5093        constructor($el, opts) {
5094            return this.initialize($el, opts);
5095        }
5096
5097        initialize($el, opts) {
5098			this.$el = $el;
5099            this.st = '';
5100			this.times = 0;
5101			this.perImageIndex = 0;
5102
5103            if( $el.is('img') && typeof opts.imagesListURL == 'undefined' ) {
5104                return false;
5105            }
5106
5107            this
5108				.setData()
5109				.setOptions(opts)
5110				.build();
5111
5112			return this;
5113		}
5114
5115        setData() {
5116			this.$el.data(instanceName, this);
5117
5118			return this;
5119		}
5120
5121        setOptions(opts) {
5122			this.options = $.extend(true, {}, PluginRandomImages.defaults, opts, {
5123				wrapper: this.$el
5124			});
5125
5126			return this;
5127		}
5128
5129        build() {
5130            const self = this;
5131			
5132			// Control the screens size we want to have the plugin working
5133			if( $(window).width() < self.options.minWindowWidth  ) {
5134				return false;
5135			}
5136
5137			// Check if is single image or wrapper with images inside
5138            if( self.$el.is('img') ) {
5139				
5140				// Check it's inside a lightbox
5141				self.isInsideLightbox = self.$el.closest('.lightbox').length ? true : false;
5142
5143				// Push the initial image to lightbox list/array
5144				if( self.isInsideLightbox && self.options.lightboxImagesListURL ) {
5145					self.options.lightboxImagesListURL.push( self.$el.closest('.lightbox').attr('href') );
5146				}
5147	
5148				// Push the current image src to the array
5149				self.options.imagesListURL.push( self.$el.attr('src') );
5150
5151				// Start with lastIndex as the first image loaded on the page
5152				self.lastIndex = self.options.imagesListURL.length - 1;
5153
5154				// Identify the last random image element (if has more than one on the page)
5155				if( self.options.random == false ) {
5156					$('.plugin-random-images').each(function(i){
5157						if( i == $('.plugin-random-images').length - 1 ) {
5158							$(this).addClass('the-last');
5159						}
5160					});
5161				}
5162
5163				// Start the recursive timeout
5164				setTimeout(() => {
5165					self.recursiveTimeout( 
5166						self.perImageTag, 
5167						self.options.delay == null ? 3000 : self.options.delay
5168					);
5169				}, self.options.delay == null ? 300 : self.options.delay / 3);
5170
5171			} else {
5172				
5173				// Start the recursive timeout
5174				setTimeout( self.recursiveTimeout( 
5175					self.perWrapper, 
5176					self.options.delay ? self.options.delay : getPerWrapperHighDelay(), 
5177					false 
5178				), 300);
5179
5180			}
5181
5182			// Stop After Few Seconds
5183			if( self.options.stopAfterFewSeconds ) {
5184				setTimeout(() => {
5185					clearTimeout(self.st);
5186				}, self.options.stopAfterFewSeconds);
5187			}
5188			
5189			return this;
5190
5191		}
5192
5193        perImageTag() {
5194			const self = this;
5195
5196			// Generate a random index to make the images rotate randomly
5197			let index = self.options.random ? Math.floor(Math.random() * self.options.imagesListURL.length) : self.lastIndex;
5198
5199			// Avoid repeat the same image
5200			if( self.lastIndex !== '' && self.lastIndex == index ) {
5201				if( self.options.random ) {
5202					while( index == self.lastIndex ) {
5203						index = Math.floor(Math.random() * self.options.imagesListURL.length);
5204					}
5205				} else {
5206					index = index - 1;
5207					if( index == -1 ) {
5208						index = self.options.imagesListURL.length - 1;
5209					}
5210				}
5211			}
5212
5213			// Turn the image ready for animations
5214			self.$el.addClass('animated');
5215
5216			// Remove the entrance animation class and add the out animation class
5217			self.$el.removeClass( self.options.animateIn ).addClass( self.options.animateOut );
5218			
5219			// Change the image src and add the class for entrance animation
5220			setTimeout( () => {
5221				self.$el.attr('src', self.options.imagesListURL[index]).removeClass( self.options.animateOut ).addClass(self.options.animateIn);
5222
5223				if( self.isInsideLightbox && self.options.lightboxImagesListURL ) {
5224					self.$el.closest('.lightbox').attr('href', self.options.lightboxImagesListURL[index]);
5225				}
5226			}, 1000);
5227			
5228			// Save the last index for future checks
5229			self.lastIndex = index;
5230			
5231			// Increment the times var
5232			self.times++;
5233
5234			// Save the index for stopAtImageIndex option
5235			self.perImageIndex = index;
5236
5237			return this;
5238		}
5239
5240        // Iterate the imaes loop and get the higher value
5241        getPerWrapperHighDelay() {
5242            const self = this;
5243            const $wrapper = self.$el;
5244            let delay = 0;
5245
5246            $wrapper.find('img').each(function(){
5247				const $image = $(this);
5248				
5249				if( $image.data('rimage-delay') && parseInt( $image.data('rimage-delay') ) > delay ) {
5250					delay = parseInt( $image.data('rimage-delay') );
5251				}
5252			});
5253
5254            return delay;
5255        }
5256
5257        perWrapper() {
5258			const self = this, $wrapper = self.$el;
5259
5260			// Turns the imageLlistURL into an array
5261			self.options.imagesListURL = [];
5262
5263			// Find all images inside the element wrapper and push their sources to image list array
5264			$wrapper.find('img').each(function(){
5265				const $image = $(this);
5266				self.options.imagesListURL.push( $image.attr('src') ); 
5267			});
5268
5269			// Shuffle the images list array (random effect)
5270			self.options.imagesListURL = self.shuffle( self.options.imagesListURL );
5271
5272			// Iterate over each image and make some checks like delay for each image, animations, etc...
5273			$wrapper.find('img').each(function(index){
5274				const $image = $(this), animateIn  = $image.data('rimage-animate-in') ? $image.data('rimage-animate-in') : self.options.animateIn, animateOut = $image.data('rimage-animate-out') ? $image.data('rimage-animate-out') : self.options.animateOut, delay      = $image.data('rimage-delay') ? $image.data('rimage-delay') : 2000;
5275
5276				$image.addClass('animated');
5277
5278				setTimeout( () => {
5279					$image.removeClass( animateIn ).addClass( animateOut );
5280				}, delay / 2);
5281
5282				setTimeout( () => {
5283					$image.attr('src', self.options.imagesListURL[index]).removeClass( animateOut ).addClass(animateIn);
5284				}, delay);
5285
5286			});
5287			
5288			// Increment the times variable
5289			self.times++;
5290
5291			return this;
5292		}
5293
5294        recursiveTimeout(callback, delay) {
5295			const self = this;
5296
5297			const timeout = () => {
5298
5299				if( callback !== null ) {
5300					callback.call(self);
5301				}
5302
5303				// Recursive
5304				self.st = setTimeout(timeout, delay == null ? 1000 : delay);
5305
5306				if( self.options.random == false ) {
5307					if( self.$el.hasClass('the-last') ) {
5308						$('.plugin-random-images').trigger('rimages.start');
5309					} else {
5310						clearTimeout(self.st);
5311					}
5312				}
5313
5314				// Stop At Image Index
5315				if( self.options.stopAtImageIndex && parseInt(self.options.stopAtImageIndex) == self.perImageIndex ) {
5316					clearTimeout(self.st);
5317				}
5318
5319				// Stop After X Timers
5320				if( self.options.stopAfterXTimes == self.times ) {
5321					clearTimeout(self.st);
5322				}
5323			};
5324			timeout();
5325
5326			self.$el.on('rimages.start', () => {
5327				clearTimeout(self.st);
5328				self.st = setTimeout(timeout, delay == null ? 1000 : delay);
5329			});
5330
5331		}
5332
5333        shuffle(array) {
5334			for (let i = array.length - 1; i > 0; i--) {
5335				const j = Math.floor(Math.random() * (i + 1));
5336				const temp = array[i];
5337				array[i] = array[j];
5338				array[j] = temp;
5339			}
5340
5341			return array;
5342		}
5343    }
5344
5345    PluginRandomImages.defaults = {
5346		minWindowWidth: 0,
5347		random: true,
5348		imagesListURL: null,
5349		lightboxImagesListURL: null,
5350        delay: null,
5351        animateIn: 'fadeIn',
5352		animateOut: 'fadeOut',
5353		stopAtImageIndex: false, // The value shoudl be the index value of array with images as string. Eg: '2' 
5354		stopAfterFewSeconds: false, // The value should be in mili-seconds. Eg: 10000 = 10 seconds
5355		stopAfterXTimes: false,
5356		accY: 0
5357	};
5358
5359    // expose to scope
5360    $.extend(theme, {
5361		PluginRandomImages
5362	});
5363
5364    // jquery plugin
5365    $.fn.themePluginRandomImages = function(opts) {
5366		return this.map(function() {
5367			const $this = $(this);
5368
5369			if ($this.data(instanceName)) {
5370				return $this.data(instanceName);
5371			} else {
5372				return new PluginRandomImages($this, opts);
5373			}
5374
5375		});
5376	}
5377})).apply(this, [window.theme, jQuery]);
5378
5379// Read More
5380(((theme = {}, $) => {
5381    const instanceName = '__readmore';
5382
5383    class PluginReadMore {
5384        constructor($el, opts) {
5385            return this.initialize($el, opts);
5386        }
5387
5388        initialize($el, opts) {
5389			const self = this;
5390
5391			this.$el = $el;
5392
5393			this
5394				.setData()
5395				.setOptions(opts)
5396				.build()
5397				.events();
5398
5399			if( self.options.startOpened ) {
5400				self.options.wrapper.find('.readmore-button-wrapper > a').trigger('click');
5401			}
5402
5403			return this;
5404		}
5405
5406        setData() {
5407			this.$el.data(instanceName, this);
5408
5409			return this;
5410		}
5411
5412        setOptions(opts) {
5413			this.options = $.extend(true, {}, PluginReadMore.defaults, opts, {
5414				wrapper: this.$el
5415			});
5416
5417			return this;
5418		}
5419
5420        build() {
5421			const self = this;
5422
5423			self.options.wrapper.addClass('position-relative');
5424
5425			// Overlay
5426			self.options.wrapper.append( '<div class="readmore-overlay"></div>' );
5427
5428			// Check if is Safari
5429			let backgroundCssValue = 'linear-gradient(180deg, rgba(2, 0, 36, 0) 0%, '+ self.options.overlayColor +' 100%)';
5430			if( $('html').hasClass('safari') ) {
5431				backgroundCssValue = '-webkit-linear-gradient(top, rgba(2, 0, 36, 0) 0%, '+ self.options.overlayColor +' 100%)'
5432			}
5433			
5434			self.options.wrapper.find('.readmore-overlay').css({
5435				background: backgroundCssValue,
5436				position: 'absolute',
5437				bottom: 0,
5438				left: 0,
5439				width: '100%',
5440				height: self.options.overlayHeight,
5441				'z-index': 1
5442			});
5443
5444			// Read More Button
5445			self.options.wrapper.find('.readmore-button-wrapper').removeClass('d-none').css({
5446				position: 'absolute',
5447				bottom: 0,
5448				left: 0,
5449				width: '100%',
5450				'z-index': 2
5451			});	
5452
5453			// Button Label
5454			self.options.wrapper.find('.readmore-button-wrapper > a').html( self.options.buttonOpenLabel );
5455
5456			self.options.wrapper.css({
5457				'height': self.options.maxHeight,
5458				'overflow-y': 'hidden'
5459			});
5460
5461			// Alignment
5462			switch ( self.options.align ) {
5463				case 'center':
5464					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-center');
5465					break;
5466
5467				case 'end':
5468					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-end');
5469					break;
5470
5471				case 'start':
5472				default:
5473					self.options.wrapper.find('.readmore-button-wrapper').addClass('text-start');
5474					break;
5475			}
5476
5477			return this;
5478
5479		}
5480
5481        events() {
5482			const self = this;
5483
5484			// Read More
5485			self.readMore = () => {
5486				self.options.wrapper.find('.readmore-button-wrapper > a:not(.readless)').on('click', function(e){
5487					e.preventDefault();
5488
5489					const $this = $(this);
5490
5491					setTimeout(() => {
5492						self.options.wrapper.animate({
5493							'height': self.options.wrapper[0].scrollHeight
5494						}, () => {
5495							if( !self.options.enableToggle ) {
5496								$this.fadeOut();
5497							}
5498
5499							$this.html( self.options.buttonCloseLabel ).addClass('readless').off('click');
5500
5501							self.readLess();
5502
5503							self.options.wrapper.find('.readmore-overlay').fadeOut();
5504							self.options.wrapper.css({
5505								'max-height': 'none',
5506								'overflow': 'visible'
5507							});
5508
5509							self.options.wrapper.find('.readmore-button-wrapper').animate({
5510								bottom: -20
5511							});
5512						});
5513					}, 200);
5514				});
5515			}
5516
5517			// Read Less
5518			self.readLess = () => {
5519				self.options.wrapper.find('.readmore-button-wrapper > a.readless').on('click', function(e){
5520					e.preventDefault();
5521
5522					const $this = $(this);
5523
5524					// Button
5525					self.options.wrapper.find('.readmore-button-wrapper').animate({
5526						bottom: 0
5527					});
5528
5529					// Overlay
5530					self.options.wrapper.find('.readmore-overlay').fadeIn();
5531
5532					setTimeout(() => {
5533						self.options.wrapper.height(self.options.wrapper[0].scrollHeight).animate({
5534							'height': self.options.maxHeight
5535						}, () => {
5536							$this.html( self.options.buttonOpenLabel ).removeClass('readless').off('click');
5537
5538							self.readMore();
5539
5540							self.options.wrapper.css({
5541								'overflow': 'hidden'
5542							});
5543						});
5544					}, 200);
5545				});
5546			}
5547
5548			// First Load
5549			self.readMore();
5550
5551			return this;
5552		}
5553    }
5554
5555    PluginReadMore.defaults = {
5556		buttonOpenLabel: 'Read More <i class="fas fa-chevron-down text-2 ms-1"></i>',
5557		buttonCloseLabel: 'Read Less <i class="fas fa-chevron-up text-2 ms-1"></i>',
5558		enableToggle: true,
5559		maxHeight: 110,
5560		overlayColor: '#FFF',
5561		overlayHeight: 100,
5562		startOpened: false,
5563		align: 'left'
5564	};
5565
5566    // expose to scope
5567    $.extend(theme, {
5568		PluginReadMore
5569	});
5570
5571    // jquery plugin
5572    $.fn.themePluginReadMore = function(opts) {
5573		return this.map(function() {
5574			const $this = $(this);
5575
5576			if ($this.data(instanceName)) {
5577				return $this.data(instanceName);
5578			} else {
5579				return new PluginReadMore($this, opts);
5580			}
5581
5582		});
5583	}
5584})).apply(this, [window.theme, jQuery]);
5585
5586// Revolution Slider
5587(((theme = {}, $) => {
5588    const instanceName = '__revolution';
5589
5590    class PluginRevolutionSlider {
5591        constructor($el, opts) {
5592            return this.initialize($el, opts);
5593        }
5594
5595        initialize($el, opts) {
5596			if ($el.data(instanceName)) {
5597				return this;
5598			}
5599
5600			this.$el = $el;
5601
5602			this
5603				.setData()
5604				.setOptions(opts)
5605				.build()
5606				.events();
5607
5608			return this;
5609		}
5610
5611        setData() {
5612			this.$el.data(instanceName, this);
5613
5614			return this;
5615		}
5616
5617        setOptions(opts) {
5618			this.options = $.extend(true, {}, PluginRevolutionSlider.defaults, opts, {
5619				wrapper: this.$el
5620			});
5621
5622			return this;
5623		}
5624
5625        build() {
5626			if (!($.isFunction($.fn.revolution))) {
5627				return this;
5628			}
5629
5630			// Single Slider Class
5631			if(this.options.wrapper.find('> ul > li').length == 1) {
5632				this.options.wrapper.addClass('slider-single-slide');
5633
5634				// Remove Bullets
5635				// this.options.navigation.bullets.enable = false;
5636				$.extend(this.options.navigation, {
5637					bullets: {
5638						enable: false
5639					}
5640				});
5641
5642			}
5643
5644			// Full Screen Class
5645			if(this.options.sliderLayout == 'fullscreen') {
5646				this.options.wrapper.closest('.slider-container').addClass('fullscreen-slider');
5647			}
5648			
5649			// Initialize Revolution Slider
5650			this.options.wrapper.revolution(this.options);
5651
5652			// Addon Init - Typewriter
5653			if(this.options.addOnTypewriter.enable) {
5654				RsTypewriterAddOn($, this.options.wrapper);
5655			}
5656
5657			// Addon Init - Whiteboard
5658			if(this.options.addOnWhiteboard.enable) {
5659				this.options.wrapper.rsWhiteBoard();
5660			}
5661
5662			// Addon Init - Particles
5663			if(this.options.addOnParticles.enable) {
5664				RsParticlesAddOn(this.options.wrapper);
5665			}
5666
5667			// Addon Init - Countdown
5668			if(this.options.addOnCountdown.enable) {
5669				tp_countdown(this.options.wrapper, this.options.addOnCountdown.targetdate, this.options.addOnCountdown.slidechanges);
5670			}
5671
5672			// Addon Init - Slicey
5673			if(this.options.addOnSlicey.enable) {
5674				this.options.wrapper.revSliderSlicey();
5675			}
5676
5677			// Addon Init - Filmstrip
5678			if(this.options.addOnFilmstrip.enable) {
5679				RsFilmstripAddOn($, this.options.wrapper, '../vendor/rs-plugin/revolution-addons/filmstrip/', false);
5680			}
5681
5682			// Addon Init - Before After
5683			if(this.options.addOnBeforeAfter.enable) {
5684				RevSliderBeforeAfter($, this.options.wrapper, this.options.addOnBeforeAfter.options);
5685			}
5686
5687			// Addon Init - Panorama
5688			if(this.options.addOnPanorama.enable) {
5689				RsAddonPanorama($, this.options.wrapper);
5690			}
5691
5692			// Addon Init - Revealer
5693			if(this.options.addOnRevealer.enable) {
5694				RsRevealerAddOn($, this.options.wrapper, this.options.revealer.spinnerHtml);
5695			}
5696
5697			// Addon Init - Duotone
5698			if(this.options.addOnDuotone.enable) {
5699				RsAddonDuotone($, this.options.wrapper, true, "cubic-bezier(0.645, 0.045, 0.355, 1.000)", "1000");
5700			}
5701
5702			// Addon Init - Bubblemorph
5703			if(this.options.addOnBubblemorph.enable) {
5704				BubbleMorphAddOn($, this.options.wrapper, false);
5705			}
5706
5707			// Addon Init - Distortion
5708			if(this.options.addOnDistortion.enable) {
5709				RsLiquideffectAddOn($, this.options.wrapper);
5710			}
5711
5712			return this;
5713		}
5714
5715        events() {
5716
5717			return this;
5718		}
5719    }
5720
5721    PluginRevolutionSlider.defaults = {
5722		sliderType: 'standard',
5723		sliderLayout: 'fullwidth',
5724		delay: 9000,
5725		gridwidth: 1170,
5726		gridheight: 500,
5727		spinner: 'spinner3',
5728		disableProgressBar: 'on',
5729		parallax: {
5730			type: 'off',
5731			bgparallax: 'off'
5732		},
5733		navigation: {
5734			keyboardNavigation: 'off',
5735			keyboard_direction: 'horizontal',
5736			mouseScrollNavigation: 'off',
5737			onHoverStop: 'off',
5738			touch: {
5739				touchenabled: 'on',
5740				swipe_threshold: 75,
5741				swipe_min_touches: 1,
5742				swipe_direction: 'horizontal',
5743				drag_block_vertical: false
5744			},
5745			arrows: {
5746				enable: true,
5747				hide_onmobile: false,
5748				hide_under: 0,
5749				hide_onleave: true,
5750				hide_delay: 200,
5751				hide_delay_mobile: 1200,
5752				left: {
5753					h_align: 'left',
5754					v_align: 'center',
5755					h_offset: 30,
5756					v_offset: 0
5757				},
5758				right: {
5759					h_align: 'right',
5760					v_align: 'center',
5761					h_offset: 30,
5762					v_offset: 0
5763				}
5764			}
5765		},
5766
5767		/* ADDONS */
5768	    addOnTypewriter: {
5769			enable: false
5770		},
5771		addOnWhiteboard: {
5772			enable: false,
5773
5774		},
5775	    whiteboard: {
5776	        movehand: {
5777	            src: '../vendor/rs-plugin/revolution-addons/whiteboard/assets/images/hand_point_right.png',
5778	            width: 400,
5779	            height: 1000,
5780	            handtype: 'right',
5781	            transform: {
5782	                transformX: 50,
5783	                transformY: 50
5784	            },
5785	            jittering: {
5786	                distance: '80',
5787	                distance_horizontal: '100',
5788	                repeat: '5',
5789	                offset: '10',
5790	                offset_horizontal: '0'
5791	            },
5792	            rotation: {
5793	                angle: '10',
5794	                repeat: '3'
5795	            }
5796	        },
5797	        writehand: {
5798	            src: '../vendor/rs-plugin/revolution-addons/whiteboard/assets/images/write_right_angle.png',
5799	            width: 572,
5800	            height: 691,
5801	            handtype: 'right',
5802	            transform: {
5803	                transformX: 50,
5804	                transformY: 50
5805	            },
5806	            jittering: {
5807	                distance: '80',
5808	                distance_horizontal: '100',
5809	                repeat: '5',
5810	                offset: '10',
5811	                offset_horizontal: '0'
5812	            },
5813	            rotation:{
5814	                angle: '10',
5815	                repeat: '3'
5816	            }
5817	        }
5818	    },
5819	    addOnParticles: {
5820	    	enable: false
5821	    },
5822	    particles: {
5823			startSlide: "first", 
5824			endSlide: "last", 
5825			zIndex: "1",
5826			particles: {
5827				number: {value: 80}, color: {value: "#ffffff"},
5828				shape: {
5829					type: "circle", stroke: {width: 0, color: "#ffffff", opacity: 1},
5830					image: {src: ""}
5831				},
5832				opacity: {value: 0.5, random: true, min: 0.25, anim: {enable: false, speed: 3, opacity_min: 0, sync: false}},
5833				size: {value: 2, random: false, min: 30, anim: {enable: false, speed: 40, size_min: 1, sync: false}},
5834				line_linked: {enable: true, distance: 150, color: "#ffffff", opacity: 0.4, width: 1},
5835				move: {enable: true, speed: 6, direction: "none", random: true, min_speed: 6, straight: false, out_mode: "out"}
5836			},
5837			interactivity: {
5838				events: {onhover: {enable: false, mode: "repulse"}, onclick: {enable: false, mode: "repulse"}},
5839				modes: {grab: {distance: 400, line_linked: {opacity: 0.5}}, bubble: {distance: 400, size: 40, opacity: 0.4}, repulse: {distance: 200}}
5840			}
5841		},
5842		addOnCountdown: {
5843			enable: false,
5844			targetdate: new Date().getTime() + 864000000, // http://www.freeformatter.com/epoch-timestamp-to-date-converter.html
5845			slidechanges: [{days: 0, hours: 0, minutes: 0, seconds: 0, slide: 2}]
5846		},
5847		addOnSlicey: {
5848			enable: false
5849		},
5850		addOnFilmstrip: {
5851			enable: false
5852		},
5853		addOnBeforeAfter : {
5854			enable: false,
5855			options: {
5856				cursor: "move",
5857			    carousel: false,
5858			    arrowStyles: {
5859			        leftIcon: "fa-icon-caret-left",
5860			        rightIcon: "fa-icon-caret-right",
5861			        topIcon: "fa-icon-caret-up",
5862			        bottomIcon: "fa-icon-caret-down",
5863			        size: "35",
5864			        color: "#ffffff",
5865			        spacing: "10",
5866			        bgColor: "transparent",
5867			        padding: "0",
5868			        borderRadius: "0"
5869			    },
5870			    dividerStyles: {
5871			        width: "1",
5872			        color: "rgba(255, 255, 255, 0.5)"
5873			    }
5874			}
5875		},
5876		addOnPanorama: {
5877			enable: false
5878		},
5879		addOnRevealer: {
5880			enable: false,
5881		},
5882		revealer: {
5883			direction: "open_horizontal",
5884			color: "#ffffff",
5885			duration: "1500",
5886			delay: "0",
5887			easing: "Power2.easeInOut",
5888			overlay_enabled: true,
5889			overlay_color: "#000000",
5890			overlay_duration: "1500",
5891			overlay_delay: "0",
5892			overlay_easing: "Power2.easeInOut",
5893			spinner: "1",
5894			spinnerColor: "#006dd2",
5895			spinnerHtml: "<div class='rsaddon-revealer-spinner rsaddon-revealer-spinner-1'><div class='rsaddon-revealer-1'><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><span style='background: {{color}}'><\/span><\/div><\/div \/>"
5896		},
5897		addOnDuotone: {
5898			enable: false
5899		},
5900		addOnBubblemorph: {
5901			enable: false
5902		},
5903		addOnDistortion: {
5904			enable: false
5905		}
5906		
5907	};
5908
5909    // expose to scope
5910    $.extend(theme, {
5911		PluginRevolutionSlider
5912	});
5913
5914    // jquery plugin
5915    $.fn.themePluginRevolutionSlider = function(opts) {
5916		return this.map(function() {
5917			const $this = $(this);
5918
5919			if ($this.data(instanceName)) {
5920				return $this.data(instanceName);
5921			} else {
5922				return new PluginRevolutionSlider($this, opts);
5923			}
5924
5925		});
5926	}
5927})).apply(this, [window.theme, jQuery]);
5928
5929// Scroll Spy
5930(((theme = {}, $) => {
5931    const instanceName = '__scrollSpy';
5932
5933    class PluginScrollSpy {
5934        constructor($el, opts) {
5935            return this.initialize($el, opts);
5936        }
5937
5938        initialize($el, opts) {
5939
5940			if( document.querySelector( opts.target ) == null ) {
5941				return false;
5942			}
5943
5944			this.$el = $el;
5945
5946			this
5947				.setData()
5948				.setOptions(opts);
5949			
5950			this.build();
5951
5952			return this;
5953		}
5954
5955        setData() {
5956			this.$el.data(instanceName, this);
5957
5958			return this;
5959		}
5960
5961        setOptions(opts) {
5962			this.options = $.extend(true, {}, PluginScrollSpy.defaults, opts, {
5963				wrapper: this.$el
5964			});
5965
5966			return this;
5967		}
5968
5969        build() {
5970            const self = this, target = document.querySelector( self.options.target ) != null ? document.querySelector( self.options.target ) : false, navItems = target == '#header' || target == '.wrapper-spy' ? target.querySelectorAll('.header-nav .nav > li a') : target.querySelectorAll('.nav > li a');
5971
5972			// Get all section ID's
5973			let sectionIDs = Object.keys(navItems).map((key, index) => navItems[key].hash);
5974
5975			// Remove empty values from sectionIDs array
5976			sectionIDs = sectionIDs.filter(value => value != '');
5977
5978			// Store in a global variable
5979			self.sectionIDs = sectionIDs;
5980
5981			for( let i = 0; i < sectionIDs.length; i++ ) {
5982
5983				// Default Root Margin
5984				let rootMargin = '-20% 0px -79.9% 0px';
5985				
5986				// Spy Offset
5987				if( $( sectionIDs[i] ).data('spy-offset') ) {
5988					const rootMarginOffset = $( sectionIDs[i] ).data('spy-offset'), isNegativeOffset = parseInt( rootMarginOffset ) < 0 ? true : false;
5989
5990					// Mount a new rootMargin based on offset value
5991					rootMargin = rootMargin.split(' ').map((element, index) => {
5992						if( element.indexOf('%') > 0 ) {
5993                            const valueToInt = parseInt( element.replace('%','') );
5994                            let newValue = 0;
5995
5996                            switch ( index ) {
5997								case 0:
5998									if( isNegativeOffset ) {
5999										newValue = valueToInt - rootMarginOffset;
6000									} else {
6001										newValue = Math.abs(valueToInt) + rootMarginOffset;
6002									}
6003									break;
6004
6005								case 2:
6006									if( isNegativeOffset ) {
6007										newValue = valueToInt + rootMarginOffset;
6008									} else {
6009										newValue = Math.abs(valueToInt) - rootMarginOffset;
6010									}
6011									break;
6012							
6013							}
6014
6015                            if( isNegativeOffset ) {
6016								newValue = newValue + '%';
6017							} else {
6018								newValue = '-' + newValue + '%';
6019							}
6020
6021                            return newValue;
6022                        } else {
6023							return element;
6024						}
6025					}).join(' ');
6026				}
6027
6028				const selector = sectionIDs[i],
6029                      callback = function() {
6030                          const $section = $(this);
6031
6032                          if( target == '#header' || target == '.wrapper-spy' ) {
6033                              $('#header .header-nav .nav > li a').removeClass('active');
6034                              $('#header .header-nav .nav > li a[href="#'+ $section[0].id +'"]').addClass('active');
6035                          } else {
6036                              $( target ).find('.nav > li a').removeClass('active');
6037                              $( target ).find('.nav > li a[href="#'+ $section[0].id +'"]').addClass('active');
6038                          }
6039                          
6040                      };
6041
6042				this.scrollSpyIntObs( selector, callback, { 
6043					rootMargin,
6044					threshold: 0
6045				}, true, i, true);
6046
6047            }
6048
6049            return this;
6050
6051		}
6052
6053        scrollSpyIntObs(selector, functionName, intObsOptions, al
6053waysObserve, index, firstLoad) {
6054			const self = this;
6055
6056			const $el = document.querySelectorAll( selector );
6057			let intersectionObserverOptions = {
6058				rootMargin: '0px 0px 200px 0px'
6059			};
6060
6061			if( Object.keys(intObsOptions).length ) {
6062				intersectionObserverOptions = $.extend(intersectionObserverOptions, intObsOptions);
6063			}
6064
6065			const observer = new IntersectionObserver(entries => {
6066                for (const entry of entries) {
6067                    if (entry.intersectionRatio > 0 ) {
6068						if( typeof functionName === 'string' ) {
6069							const func = Function( 'return ' + functionName )();
6070						} else {
6071							const callback = functionName;
6072
6073							callback.call( $(entry.target) );
6074						}
6075
6076						// Unobserve
6077						if( !alwaysObserve ) {
6078							observer.unobserve(entry.target);   
6079						}
6080
6081					} else {
6082						if( firstLoad == false ) {
6083							if( index == self.sectionIDs.length - 1 ) {
6084								$('#header .header-nav .nav > li a').removeClass('active');
6085								$('#header .header-nav .nav > li a[href="#'+ entry.target.id +'"]').parent().prev().find('a').addClass('active');
6086							}
6087						}
6088						firstLoad = false;
6089
6090					}
6091                }
6092            }, intersectionObserverOptions);
6093			
6094			$( $el ).each(function(){
6095				observer.observe( $(this)[0] );
6096			});
6097
6098			return this;
6099		}
6100    }
6101
6102    PluginScrollSpy.defaults = {
6103		target: '#header'
6104	};
6105
6106    // expose to scope
6107    $.extend(theme, {
6108		PluginScrollSpy
6109	});
6110
6111    // jquery plugin
6112    $.fn.themePluginScrollSpy = function(opts) {
6113		return this.map(function() {
6114			const $this = $(this);
6115
6116			if ($this.data(instanceName)) {
6117				return $this.data(instanceName);
6118			} else {
6119				return new PluginScrollSpy($this, opts);
6120			}
6121
6122		});
6123	}
6124})).apply(this, [window.theme, jQuery]);
6125
6126// Scroll to Top
6127(((theme = {}, $) => {
6128    $.extend(theme, {
6129
6130		PluginScrollToTop: {
6131
6132			defaults: {
6133				wrapper: $('body'),
6134				offset: 150,
6135				buttonClass: 'scroll-to-top',
6136				buttonAriaLabel: 'Scroll To Top',
6137				iconClass: 'fas fa-chevron-up',
6138				delay: 1000,
6139				visibleMobile: false,
6140				label: false,
6141				easing: 'easeOutBack'
6142			},
6143
6144			initialize(opts) {
6145				initialized = true;
6146
6147				// Don't initialize if the page has Section Scroll
6148				if( $('body[data-plugin-section-scroll]').get(0) ) {
6149					return;
6150				}
6151
6152				this
6153					.setOptions(opts)
6154					.build()
6155					.events();
6156
6157				return this;
6158			},
6159
6160			setOptions(opts) {
6161				this.options = $.extend(true, {}, this.defaults, opts);
6162
6163				return this;
6164			},
6165
6166			build() {
6167                const self = this;
6168                let $el;
6169
6170                // Base HTML Markup
6171                $el = $('<a />')
6172					.addClass(self.options.buttonClass)
6173					.attr({
6174						'href': '#',
6175						'aria-label': self.options.buttonAriaLabel
6176					})
6177					.append(
6178						$('<i />')
6179						.addClass(self.options.iconClass)
6180				);
6181
6182                // Visible Mobile
6183                if (!self.options.visibleMobile) {
6184					$el.addClass('hidden-mobile');
6185				}
6186
6187                // Label
6188                if (self.options.label) {
6189					$el.append(
6190						$('<span />').html(self.options.label)
6191					);
6192				}
6193
6194                this.options.wrapper.append($el);
6195
6196                this.$el = $el;
6197
6198                return this;
6199            },
6200
6201			events() {
6202                const self = this;
6203                let _isScrolling = false;
6204
6205                // Click Element Action
6206                self.$el.on('click', e => {
6207					e.preventDefault();
6208					$('html').animate({
6209						scrollTop: 0
6210					}, self.options.delay, self.options.easing);
6211					return false;
6212				});
6213
6214                // Show/Hide Button on Window Scroll event.
6215                $(window).scroll(() => {
6216
6217					if (!_isScrolling) {
6218
6219						_isScrolling = true;
6220
6221						if ($(window).scrollTop() > self.options.offset) {
6222
6223							self.$el.stop(true, true).addClass('visible');
6224							_isScrolling = false;
6225
6226						} else {
6227
6228							self.$el.stop(true, true).removeClass('visible');
6229							_isScrolling = false;
6230
6231						}
6232
6233					}
6234
6235				});
6236
6237                return this;
6238            }
6239
6240		}
6241
6242	});
6243})).apply(this, [window.theme, jQuery]);
6244
6245// Scrollable
6246(((theme = {}, $) => {
6247    const instanceName = '__scrollable';
6248
6249    class PluginScrollable {
6250        constructor($el, opts) {
6251            return this.initialize($el, opts);
6252        }
6253
6254        static updateModals() {
6255            PluginScrollable.updateBootstrapModal();
6256        }
6257
6258        static updateBootstrapModal() {
6259            let updateBoostrapModal;
6260
6261            updateBoostrapModal = typeof $.fn.modal !== 'undefined';
6262            updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor !== 'undefined';
6263            updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor.prototype !== 'undefined';
6264            updateBoostrapModal = updateBoostrapModal && typeof $.fn.modal.Constructor.prototype.enforceFocus !== 'undefined';
6265
6266            if ( !updateBoostrapModal ) {
6267                return false;
6268            }
6269
6270            const originalFocus = $.fn.modal.Constructor.prototype.enforceFocus;
6271            $.fn.modal.Constructor.prototype.enforceFocus = function() {
6272                originalFocus.apply( this );
6273
6274                const $scrollable = this.$element.find('.scrollable');
6275                if ( $scrollable ) {
6276                    if ( $.isFunction($.fn['themePluginScrollable'])  ) {
6277                        $scrollable.themePluginScrollable();
6278                    }
6279
6280                    if ( $.isFunction($.fn['nanoScroller']) ) {
6281                        $scrollable.nanoScroller();
6282                    }
6283                }
6284            };
6285        }
6286
6287        initialize($el, opts) {
6288			if ( $el.data( instanceName ) ) {
6289				return this;
6290			}
6291
6292			this.$el = $el;
6293
6294			this
6295				.setData()
6296				.setOptions(opts)
6297				.build();
6298
6299			return this;
6300		}
6301
6302        setData() {
6303			this.$el.data(instanceName, this);
6304
6305			return this;
6306		}
6307
6308        setOptions(opts) {
6309			this.options = $.extend(true, {}, PluginScrollable.defaults, opts, {
6310				wrapper: this.$el
6311			});
6312
6313			return this;
6314		}
6315
6316        build() {
6317			this.options.wrapper.nanoScroller(this.options);
6318
6319			return this;
6320		}
6321    }
6322
6323    PluginScrollable.defaults = {
6324		contentClass: 'scrollable-content',
6325		paneClass: 'scrollable-pane',
6326		sliderClass: 'scrollable-slider',
6327		alwaysVisible: true,
6328		preventPageScrolling: true
6329	};
6330
6331    // expose to scope
6332    $.extend(theme, {
6333		PluginScrollable
6334	});
6335
6336    // jquery plugin
6337    $.fn.themePluginScrollable = function(opts) {
6338		return this.each(function() {
6339			const $this = $(this);
6340
6341			if ($this.data(instanceName)) {
6342				return $this.data(instanceName);
6343			} else {
6344				return new PluginScrollable($this, opts);
6345			}
6346
6347		});
6348	};
6349
6350    $(() => {
6351		PluginScrollable.updateModals();
6352	});
6353})).apply(this, [window.theme, jQuery]);
6354
6355// Section Scroll
6356(((theme = {}, $) => {
6357    const instanceName = '__sectionScroll';
6358
6359    class PluginSectionScroll {
6360        constructor($el, opts) {
6361            return this.initialize($el, opts);
6362        }
6363
6364        initialize($el, opts) {
6365			if ($el.data(instanceName)) {
6366				return this;
6367			}
6368
6369			this.$el = $el;
6370
6371			this
6372				.setData()
6373				.setOptions(opts)
6374				.build()
6375				.events();
6376
6377			return this;
6378		}
6379
6380        setData() {
6381			this.$el.data(instanceName, this);
6382
6383			return this;
6384		}
6385
6386        setOptions(opts) {
6387			this.options = $.extend(true, {}, PluginSectionScroll.defaults, opts, {
6388				wrapper: this.$el
6389			});
6390
6391			return this;
6392		}
6393
6394        build() {
6395			const self = this, $el = this.options.wrapper;
6396
6397			// Check type of header and change the target for header (by change header color purpose)
6398			if( $('html').hasClass('side-header-overlay-full-screen') ) {
6399				self.$header = $('.sticky-wrapper');
6400			} else {
6401				self.$header = $('#header');
6402			}
6403
6404			// Turn the section full height or not depeding on the content size
6405			self.updateSectionsHeight();
6406
6407			// Wrap all sections in a section wrapper
6408			$( this.options.targetClass ).wrap('<div class="section-wrapper"></div>');
6409
6410			// Set the section wrapper height
6411	  		$('.section-wrapper').each(function(){
6412	  			$(this).height( $(this).find('.section-scroll').outerHeight() );
6413	  		});
6414
6415	  		// Add active class to the first section on page load
6416	  		$('.section-wrapper').first().addClass('active');
6417			
6418	        let flag = false, scrollableFlag = false, touchDirection = '', touchstartY = 0, touchendY = 0;
6419
6420	        $(window).on('touchstart', ({changedTouches}) => {
6421			    touchstartY = changedTouches[0].screenY;
6422			});
6423
6424	        let wheelEvent = 'onwheel' in document ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll';
6425	        if( $(window).width() < 992 && $('html').hasClass('touch') ) {
6426	        	wheelEvent = 'onwheel' in document ? 'wheel touchend' : document.onmousewheel !== undefined ? 'mousewheel touchend' : 'DOMMouseScroll touchend';
6427	        }
6428
6429        	if( $(window).width() < 992 ) {
6430	    		$('html').removeClass('overflow-hidden');
6431			    $(window).on('scroll', () => {
6432
6433		    		let index = 0;
6434		    		$('.section-scroll').each(function(){
6435		    			if( $(this).offset().top <= $(window).scrollTop() + 50 ) {
6436		    				const $currentSection2 = $('.section-wrapper').eq( index ).find('.section-scroll');
6437
6438			            	$('.section-scroll-dots-navigation > ul > li').removeClass('active');
6439							$('.section-scroll-dots-navigation > ul > li').eq( index ).addClass('active');
6440
6441							$(window).trigger({
6442								type: 'section.scroll.mobile.change.header.color',
6443								currentSection: $currentSection2
6444							});
6445		    			}
6446
6447		    			index++;
6448		    		});
6449		    		
6450			    });
6451
6452			    $(window).on('section.scroll.mobile.change.header.color', ({currentSection}) => {
6453			    	if( typeof currentSection == 'undefined' ) {
6454			    		return;
6455			    	}
6456
6457			    	const $currentSection = currentSection, headerColor     = $currentSection.data('section-scroll-header-color');
6458								    	
6459			    	$('#header .header-nav').removeClass('header-nav-light-text header-nav-dark-text').addClass('header-nav-' + headerColor + '-text');
6460			    	$('#header .header-nav-features').removeClass('header-nav-features-dark header-nav-features-light').addClass('header-nav-features-' + headerColor);
6461			    	$('#header .header-social-icons').removeClass('social-icons-icon-dark social-icons-icon-light').addClass('social-icons-icon-' + headerColor);
6462
6463			    	// Change Logo
6464			    	if( self.options.changeHeaderLogo && headerColor != undefined ) {
6465				    	if( headerColor == 'light' ) {
6466				    		$('#header .header-logo img').attr('src', self.options.headerLogoLight);
6467				    	} else if( headerColor == 'dark' ) {
6468				    		$('#header .header-logo img').attr('src', self.options.headerLogoDark);
6469				    	}
6470			    	}
6471
6472			    	self.$header.css({
6473			    		opacity: 1
6474			    	});
6475
6476			    });
6477        	}
6478
6479	        $(window).on(wheelEvent, ({target, originalEvent}) => {
6480                if( $(window).width() < 992 ) {
6481	        		return;
6482	        	}
6483
6484                if( $(window).width() < 992 && $('html').hasClass('touch') ) {
6485		        	if( $(target).closest('.section-scroll-dots-navigation').get(0) || $(target).closest('.header-body').get(0) || $(target).closest('.owl-carousel').get(0) ) {
6486		        		return;
6487		        	}
6488		        }
6489
6490                // Side Header Overlay Full Screen
6491                if( $('html.side-header-overlay-full-screen.side-header-hide').get(0) ) {
6492		        	return;
6493		        }
6494
6495                const wheelDirection = originalEvent.wheelDelta == undefined ? originalEvent.deltaY > 0 : originalEvent.wheelDelta < 0;
6496                if( $(window).width() < 992 && $('html').hasClass('touch') ) {
6497		        	touchendY = event.changedTouches[0].screenY;
6498	        		
6499				    if( touchendY <= touchstartY ) {
6500				    	touchDirection = 'up';
6501				    }
6502
6503				    if( touchendY >= touchstartY ) {
6504				    	touchDirection = 'down';
6505				    }
6506
6507				    if( touchendY == touchstartY ) {
6508				    	return;
6509				    }
6510	        	}
6511
6512                const $currentSection = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll');
6513                const $nextSection = self.getNextSection(wheelDirection, touchDirection);
6514                let nextSectionOffsetTop;
6515
6516                // If is the last section, then change the offsetTop value
6517                if( self.getCurrentIndex() == $('.section-wrapper').length - 1 ) {
6518            		nextSectionOffsetTop = $(document).height();
6519            	} else {
6520            		nextSectionOffsetTop = $nextSection.offset().top;
6521            	}
6522
6523                if( $(window).width() < 992 && $('html').hasClass('touch') ) {
6524				    setTimeout(() => {
6525					    if( $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').hasClass('section-scroll-scrollable') ) {
6526					    	$('html').removeClass('overflow-hidden');
6527					    } else {
6528					    	$('html').addClass('overflow-hidden');
6529					    }
6530				    }, 1200);
6531				}
6532
6533                // For non full height sections
6534                if( $currentSection.hasClass('section-scroll-scrollable') ) {
6535	        		if( !flag && !scrollableFlag ) {
6536
6537		        		// Scroll Direction
6538		        		if(wheelDirection || touchDirection == 'up') {
6539		        			if( ( $(window).scrollTop() + $(window).height() ) >= nextSectionOffsetTop ) {
6540		        				flag = true;
6541								setTimeout(() => {
6542									$(window).trigger('section.scroll.change.header.color');
6543
6544					            	setTimeout(() => {
6545										flag = false;
6546									}, 500);
6547								}, 1000);
6548
6549		        				if( self.getCurrentIndex() == ( $('.section-wrapper').length - 1 )  ) {
6550						    		return false;
6551						    	}
6552
6553		        				// Move to the next section
6554		        				self.moveTo( $currentSection.offset().top + $currentSection.outerHeight() );
6555
6556		        				// Change Section Active Class
6557					   			self.changeSectionActiveState( $nextSection );
6558
6559					   			self.$header.css({
6560							    	opacity: 0,
6561							    	transition: 'ease opacity 500ms'
6562							    });
6563					        }
6564
6565			        		if( !$('html').hasClass('touch') ) {
6566				        		for( var i = 1; i < 100; i++ ) {
6567					        		$('body, html').scrollTop( $(window).scrollTop() + 1 );
6568
6569					        		if( ( $(window).scrollTop() + $(window).height() ) >= nextSectionOffsetTop ) {
6570					        			scrollableFlag = true;
6571										setTimeout(() => {
6572											$(window).trigger('section.scroll.change.header.color');
6573							            	scrollableFlag = false;
6574										}, 500);
6575					        			break;
6576					        		}
6577				        		}
6578				        	}
6579					    } else {
6580					    	if( $(window).scrollTop() <= $currentSection.offset().top ) {
6581					    		flag = true;
6582								setTimeout(() => {
6583									$(window).trigger('section.scroll.change.header.color');
6584
6585					            	setTimeout(() => {
6586										flag = false;
6587									}, 500);
6588								}, 1000);
6589
6590					    		if( self.getCurrentIndex() == 0  ) {
6591						    		return false;
6592						    	}
6593
6594					   			// Move to the next section
6595		        				self.moveTo( $currentSection.offset().top - $(window).height() );
6596
6597		        				// Change Section Active Class
6598					   			self.changeSectionActiveState( $nextSection );
6599
6600					   			self.$header.css({
6601							    	opacity: 0,
6602							    	transition: 'ease opacity 500ms'
6603							    });
6604					        }
6605
6606					    	if( !$('html').hasClass('touch') ) {
6607				        		for( var i = 1; i < 100; i++ ) {
6608					        		$('body, html').scrollTop( $(window).scrollTop() - 1 );
6609
6610					        		if( $(window).scrollTop() <= $currentSection.offset().top ) {
6611					        			scrollableFlag = true;
6612										setTimeout(() => {
6613											$(window).trigger('section.scroll.change.header.color');
6614							            	scrollableFlag = false;
6615										}, 500);
6616					        			break;
6617					        		}
6618				        		}
6619				        	}
6620					    }
6621
6622			   			// Change Dots Active Class
6623				        self.changeDotsActiveState();
6624
6625		        		return;
6626
6627		        	}
6628	        	}
6629
6630                // For full height sections
6631                if( !flag && !scrollableFlag ) {
6632				    if(wheelDirection || touchDirection == 'up') {
6633				    	if( self.getCurrentIndex() == ( $('.section-wrapper').length - 1 )  ) {
6634				    		return false;
6635				    	}
6636
6637				   		// Change Section Active Class
6638			   			self.changeSectionActiveState( $nextSection );
6639
6640				   		setTimeout(() => {
6641				   			// Move to the next section
6642	        				self.moveTo( $nextSection.offset().top );
6643
6644				   		}, 150);
6645				    } else {
6646				    	if( self.getCurrentIndex() == 0  ) {
6647				    		return false;
6648				    	}
6649
6650				   		// Change Section Active Class
6651			   			self.changeSectionActiveState( $nextSection );
6652
6653				   		if( $nextSection.height() > $(window).height() ) {
6654				   			// Move to the next section
6655	        				self.moveTo( $currentSection.offset().top - $(window).height() );
6656				   		} else {
6657					        setTimeout(() => {
6658					   			// Move to the next section
6659		        				self.moveTo( $nextSection.offset().top );
6660
6661					   		}, 150);
6662				   		}
6663				    }
6664
6665				    // Change Dots Active Class
6666			        self.changeDotsActiveState();
6667
6668				    self.$header.css({
6669				    	opacity: 0,
6670				    	transition: 'ease opacity 500ms'
6671				    });
6672
6673				    // Style next section
6674	            	$nextSection.css({
6675	            		position: 'relative',
6676	            		opacity: 1,
6677	            		'z-index': 1,
6678	            		transform: 'translate3d(0,0,0) scale(1)'
6679	            	});
6680
6681	            	// Style previous section
6682	            	$currentSection.css({
6683	            		position: 'fixed',
6684	            		width: '100%',
6685	            		top: 0,
6686	            		left: 0,
6687	            		opacity: 0,
6688	            		'z-index': 0,
6689	            		transform: 'translate3d(0,0,-10px) scale(0.7)',
6690	            		transition: 'ease transform 600ms, ease opacity 600ms',
6691	            	});
6692
6693					setTimeout(() => {
6694						$currentSection.css({
6695		            		position: 'relative',
6696		            		opacity: 1,
6697		            		transform: 'translate3d(0,0,-10px) scale(1)'
6698		            	});
6699
6700						$(window).trigger('section.scroll.change.header.color');
6701
6702		            	setTimeout(() => {
6703							flag = false;
6704						}, 500);
6705					}, 1000);
6706
6707					flag = true;
6708
6709				}
6710
6711                return;
6712            });
6713
6714	        // Dots Navigation
6715	        if( this.options.dotsNav ) {
6716	        	self.dotsNavigation();
6717	        }
6718
6719	        // First Load
6720	        setTimeout(() => {
6721		        if( $(window.location.hash).get(0) ) {
6722		        	self.moveTo( $(window.location.hash).parent().offset().top );
6723
6724		        	self.changeSectionActiveState( $(window.location.hash) );
6725
6726		        	// Change Dots Active Class
6727			        self.changeDotsActiveState();
6728
6729		        	self.updateHash( true );
6730		        } else {
6731                    const hash  = window.location.hash;
6732                    let index = hash.replace('#','');
6733
6734                    if( !hash ) {
6735		        		index = 1;
6736		        	}
6737
6738                    self.moveTo( $('.section-wrapper').eq( index - 1 ).offset().top );
6739
6740                    self.changeSectionActiveState( $('.section-wrapper').eq( index - 1 ).find('.section-scroll') );
6741
6742                    // Change Dots Active Class
6743                    self.changeDotsActiveState();
6744
6745                    self.updateHash( true );
6746                }
6747
6748				$(window).trigger('section.scroll.ready');
6749				$(window).trigger('section.scroll.change.header.color');
6750			}, 500);
6751
6752			return this;
6753		}
6754
6755        updateSectionsHeight() {
6756			const self = this;
6757
6758			$('.section-scroll').css({ height: '' });
6759
6760			$('.section-scroll').each(function(){
6761				if( $(this).outerHeight() < ( $(window).height() + 3 ) ) {
6762					$(this).css({ height: '100vh' });		
6763				} else {
6764					$(this).addClass('section-scroll-scrollable');
6765				}
6766			});
6767
6768			// Set the section wrapper height
6769	  		$('.section-wrapper').each(function(){
6770	  			$(this).height( $(this).find('.section-scroll').outerHeight() );
6771	  		});
6772
6773			return this;
6774		}
6775
6776        updateHash(first_load) {
6777			const self = this;
6778
6779			if( !window.location.hash ) {
6780				window.location.hash = 1;
6781			} else {
6782				if(!first_load) {
6783					const $section = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll'), section_id = $section.attr('id') ? $section.attr('id') : $section.parent().index() + 1;
6784
6785					window.location.hash = section_id;
6786				}
6787			}
6788
6789			return this;
6790		}
6791
6792        getCurrentIndex() {
6793            const self = this;
6794            let currentIndex = 0;
6795
6796            currentIndex = $('.section-wrapper.active').index();
6797
6798            return currentIndex;
6799        }
6800
6801        moveTo($scrollTopValue, first_load) {
6802			const self = this;
6803
6804			$('body, html').animate({
6805   				scrollTop: $scrollTopValue
6806   			}, 1000, 'easeOutQuint');
6807
6808   			setTimeout(() => {
6809	   			self.updateHash();
6810   			}, 500);
6811
6812			return this;
6813		}
6814
6815        getNextSection(wheelDirection, touchDirection) {
6816            const self = this;
6817            let $nextSection = '';
6818
6819            // Scroll Direction
6820            if(wheelDirection || touchDirection == 'up') {
6821				$nextSection = $('.section-wrapper').eq( self.getCurrentIndex() + 1 ).find('.section-scroll');
6822        	} else {
6823        		$nextSection = $('.section-wrapper').eq( self.getCurrentIndex() - 1 ).find('.section-scroll');
6824        	}
6825
6826            return $nextSection;
6827        }
6828
6829        changeSectionActiveState($nextSection) {
6830			const self = this;
6831
6832			$('.section-wrapper').removeClass('active');
6833	   		$nextSection.parent().addClass('active');
6834
6835			return this;
6836		}
6837
6838        changeDotsActiveState() {
6839			const self = this;
6840
6841			$('.section-scroll-dots-navigation > ul > li').removeClass('active');
6842			$('.section-scroll-dots-navigation > ul > li').eq( self.getCurrentIndex() ).addClass('active');
6843
6844			return this;
6845		}
6846
6847        dotsNavigation() {
6848			const self = this;
6849
6850			const dotsNav = $('<div class="section-scroll-dots-navigation"><ul class="list list-unstyled"></ul></div>'), currentSectionIndex = self.getCurrentIndex();
6851
6852        	if( self.options.dotsClass ) {
6853        		dotsNav.addClass( self.options.dotsClass );
6854        	}
6855
6856        	for( let i = 0; i < $('.section-scroll').length; i++ ) {
6857        		const title = $('.section-wrapper').eq( i ).find('.section-scroll').data('section-scroll-title');
6858
6859        		dotsNav.find('> ul').append( '<li'+ ( ( currentSectionIndex == i ) ? ' class="active"' : '' ) +'><a href="#'+ i +'" data-nav-id="'+ i +'"><span>'+ title +'</span></a></li>' );
6860        	}
6861
6862        	$('.body').append( dotsNav );
6863
6864        	dotsNav.find('a[data-nav-id]').on('click touchstart', function(e){
6865        		e.preventDefault();
6866        		const $this = $(this);
6867
6868        		$('.section-scroll').css({
6869        			opacity: 0,
6870        			transition: 'ease opacity 300ms'
6871        		});
6872
6873        		self.$header.css({
6874			    	opacity: 0,
6875			    	transition: 'ease opacity 500ms'
6876			    });
6877
6878        		setTimeout(() => {
6879	        		self.moveTo( $('.section-wrapper').eq( $this.data('nav-id') ).offset().top )
6880
6881		   			$('.section-wrapper').removeClass('active');
6882			   		$('.section-wrapper').eq( $this.data('nav-id') ).addClass('active');
6883
6884	        		$('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').css({
6885	        			opacity: 1
6886	        		});
6887
6888	        		setTimeout(() => {
6889		        		$('.section-scroll').css({ opacity: 1 });
6890
6891		        		$(window).trigger('section.scroll.change.header.color');
6892	        		}, 500);
6893
6894	        		if( $(window).width() > 991 ) {
6895		        		self.changeDotsActiveState();
6896	        		}
6897        		}, 500);
6898        	});
6899
6900			return this;
6901		}
6902
6903        events() {
6904			const self = this;
6905
6906			$(window).on('section.scroll.ready', () => {
6907				$(window).scrollTop(0);
6908			});
6909
6910			$(window).on('section.scroll.change.header.color', () => {
6911		    	const headerColor = $('.section-wrapper').eq( self.getCurrentIndex() ).find('.section-scroll').data('section-scroll-header-color');
6912		    	
6913		    	$('#header .header-nav').removeClass('header-nav-light-text header-nav-dark-text').addClass('header-nav-' + headerColor + '-text');
6914		    	$('#header .header-nav-features').removeClass('header-nav-features-dark header-nav-features-light').addClass('header-nav-features-' + headerColor);
6915		    	$('#header .header-social-icons').removeClass('social-icons-icon-dark social-icons-icon-light').addClass('social-icons-icon-' + headerColor);
6916
6917		    	// Change Logo
6918		    	if( self.options.changeHeaderLogo && headerColor != undefined ) {
6919			    	if( headerColor == 'light' ) {
6920			    		$('#header .header-logo img').attr('src', self.options.headerLogoLight);
6921			    	} else if( headerColor == 'dark' ) {
6922			    		$('#header .header-logo img').attr('src', self.options.headerLogoDark);
6923			    	}
6924		    	}
6925
6926		    	self.$header.css({
6927		    		opacity: 1
6928		    	});
6929		    });
6930
6931			$(document).ready(() => {
6932			    $(window).afterResize(() => {
6933			    	self.updateSectionsHeight();
6934
6935			    	if( $(window).width() < 992 ) {
6936			    		$('html').removeClass('overflow-hidden');
6937			    	}
6938			    });
6939			});
6940
6941		    return this;
6942		}
6943    }
6944
6945    PluginSectionScroll.defaults = {
6946		targetClass: '.section',
6947		dotsNav: true,
6948		changeHeaderLogo: true,
6949		headerLogoDark: 'img/logo-default-slim.png',
6950		headerLogoLight: 'img/logo-default-slim-dark.png'
6951	};
6952
6953    // expose to scope
6954    $.extend(theme, {
6955		PluginSectionScroll
6956	});
6957
6958    // jquery plugin
6959    $.fn.themePluginSectionScroll = function(opts) {
6960		return this.map(function() {
6961			const $this = $(this);
6962
6963			if ($this.data(instanceName)) {
6964				return $this.data(instanceName);
6965			} else {
6966				return new PluginSectionScroll($this, opts);
6967			}
6968
6969		});
6970	};
6971})).apply(this, [window.theme, jQuery]);
6972
6973// Sort
6974(((theme = {}, $) => {
6975    const instanceName = '__sort';
6976
6977    class PluginSort {
6978        constructor($el, opts) {
6979            return this.initialize($el, opts);
6980        }
6981
6982        initialize($el, opts) {
6983			if ($el.data(instanceName)) {
6984				return this;
6985			}
6986
6987			this.$el = $el;
6988
6989			this
6990				.setData()
6991				.setOptions(opts)
6992				.build();
6993
6994			return this;
6995		}
6996
6997        setData() {
6998			this.$el.data(instanceName, this);
6999
7000			return this;
7001		}
7002
7003        setOptions(opts) {
7004			this.options = $.extend(true, {}, PluginSort.defaults, opts, {
7005				wrapper: this.$el
7006			});
7007
7008			return this;
7009		}
7010
7011        build() {
7012			if (!($.isFunction($.fn.isotope))) {
7013				return this;
7014			}
7015
7016			const self = this, $source = this.options.wrapper, $destination = $('.sort-destination[data-sort-id="' + $source.attr('data-sort-id') + '"]'), $window = $(window);
7017
7018			if ($destination.get(0)) {
7019
7020				self.$source = $source;
7021				self.$destination = $destination;
7022				self.$loader = false;
7023
7024				self.setParagraphHeight($destination);
7025
7026				if (self.$destination.parents('.sort-destination-loader').get(0)) {
7027					self.$loader = self.$destination.parents('.sort-destination-loader');
7028					self.createLoader();
7029				}
7030
7031				$destination.attr('data-filter', '*');
7032
7033				$destination.one('layoutComplete', (event, laidOutItems) => {
7034					self.removeLoader();
7035
7036					// If has data-plugin-sticky on the page we need recalculate sticky position
7037					if( $('[data-plugin-sticky]').length ) {
7038						setTimeout(() => {
7039							$('[data-plugin-sticky]').each(function(){
7040								$(this).data('__sticky').build();
7041								$(window).trigger('resize');
7042							});
7043						}, 500);
7044					}
7045				});
7046
7047				if ( $('#' + self.options.filterFieldId).length ) {
7048
7049					const $filterField = $('#' + self.options.filterFieldId);
7050
7051					$filterField.keyup(function() {
7052						self.options.filterFieldText = $(this).val();
7053						self.setFilter(self.options.filter);
7054					});
7055
7056				}
7057
7058				$destination.waitForImages(() => {
7059					$destination.isotope(self.options);
7060					self.events();
7061				});
7062
7063				setTimeout(() => {
7064					self.removeLoader();
7065				}, 3000);
7066
7067			}
7068
7069			return this;
7070		}
7071
7072        events() {
7073            const self = this;
7074            let filter = null;
7075            const $window = $(window);
7076
7077            self.$source.find('a').click(function(e) {
7078				e.preventDefault();
7079
7080				filter = $(this).parent().data('option-value');
7081
7082				self.setFilter(filter);
7083
7084				if (e.originalEvent) {
7085					self.$source.trigger('filtered');
7086				}
7087
7088				return this;
7089			});
7090
7091            self.$destination.trigger('filtered');
7092            self.$source.trigger('filtered');
7093
7094            if (self.options.useHash) {
7095				self.hashEvents();
7096			}
7097
7098            $window.on('resize sort.resize', () => {
7099				setTimeout(() => {
7100					self.$destination.isotope('layout');
7101				}, 300);
7102			});
7103
7104            setTimeout(() => {
7105				$window.trigger('sort.resize');
7106			}, 300);
7107
7108            return this;
7109        }
7110
7111        setFilter(filter) {
7112            const self = this;
7113            const page = false;
7114            let currentFilter = filter;
7115
7116            self.$source.find('.active').removeClass('active');
7117            self.$source.find('li[data-option-value="' + filter + '"], li[data-option-value="' + filter + '"] > a').addClass('active');
7118
7119            self.options.filter = currentFilter;
7120
7121            if (self.$destination.attr('data-current-page')) {
7122				currentFilter = currentFilter + '[data-page-rel=' + self.$destination.attr('data-current-page') + ']';
7123			}
7124
7125            if (self.options.filterFieldText != '') {
7126				currentFilter = currentFilter + '[data-sort-search*=' + self.options.filterFieldText.toLowerCase() + ']';
7127			}
7128
7129            self.$destination.attr('data-filter', filter).isotope({
7130				filter: currentFilter
7131			}).one('arrangeComplete', (event, filteredItems) => {
7132				
7133				if (self.options.useHash) {
7134					if (window.location.hash != '' || self.options.filter.replace('.', '') != '*') {
7135						window.location.hash = self.options.filter.replace('.', '');
7136					}
7137				}
7138				
7139				$(window).trigger('scroll');
7140
7141			}).trigger('filtered');
7142
7143            return this;
7144        }
7145
7146        hashEvents() {
7147            const self = this;
7148            let hash = null;
7149            let hashFilter = null;
7150            let initHashFilter = '.' + location.hash.replace('#', '');
7151
7152            // Check if has scroll to section trough URL hash and prevent the sort plugin from show nothing
7153            if( $(location.hash).length ) {
7154				initHashFilter = '.';
7155			}
7156
7157            if (initHashFilter != '.' && initHashFilter != '.*') {
7158				self.setFilter(initHashFilter);
7159			}
7160
7161            $(window).on('hashchange', e => {
7162
7163				hashFilter = '.' + location.hash.replace('#', '');
7164				hash = (hashFilter == '.' || hashFilter == '.*' ? '*' : hashFilter);
7165
7166				self.setFilter(hash);
7167
7168			});
7169
7170            return this;
7171        }
7172
7173        setParagraphHeight() {
7174            const self = this;
7175            let minParagraphHeight = 0;
7176            const paragraphs = $('span.thumb-info-caption p', self.$destination);
7177
7178            paragraphs.each(function() {
7179				if ($(this).height() > minParagraphHeight) {
7180					minParagraphHeight = ($(this).height() + 10);
7181				}
7182			});
7183
7184            paragraphs.height(minParagraphHeight);
7185
7186            return this;
7187        }
7188
7189        createLoader() {
7190			const self = this;
7191
7192			const loaderTemplate = [
7193				'<div class="bounce-loader">',
7194					'<div class="bounce1"></div>',
7195					'<div class="bounce2"></div>',
7196					'<div class="bounce3"></div>',
7197				'</div>'
7198			].join('');
7199
7200			self.$loader.append(loaderTemplate);
7201
7202			return this;
7203		}
7204
7205        removeLoader() {
7206
7207			const self = this;
7208
7209			if (self.$loader) {
7210
7211				self.$loader.removeClass('sort-destination-loader-showing');
7212
7213				setTimeout(() => {
7214					self.$loader.addClass('sort-destination-loader-loaded');
7215				}, 300);
7216
7217			}
7218
7219		}
7220    }
7221
7222    PluginSort.defaults = {
7223		useHash: true,
7224		itemSelector: '.isotope-item',
7225		layoutMode: 'masonry',
7226		filter: '*',
7227		filterFieldId: false,
7228		filterFieldText: '',
7229		hiddenStyle: {
7230			opacity: 0
7231		},
7232		visibleStyle: {
7233			opacity: 1
7234		},
7235		stagger: 30,
7236		isOriginLeft: ($('html').attr('dir') == 'rtl' ? false : true)
7237	};
7238
7239    // expose to scope
7240    $.extend(theme, {
7241		PluginSort
7242	});
7243
7244    // jquery plugin
7245    $.fn.themePluginSort = function(opts) {
7246		return this.map(function() {
7247			const $this = $(this);
7248
7249			if ($this.data(instanceName)) {
7250				return $this.data(instanceName);
7251			} else {
7252				return new PluginSort($this, opts);
7253			}
7254
7255		});
7256	}
7257})).apply(this, [window.theme, jQuery]);
7258
7259// Star Rating
7260(((theme = {}, $) => {
7261    const instanceName = '__starrating';
7262
7263    class PluginStarRating {
7264        constructor($el, opts) {
7265            return this.initialize($el, opts);
7266        }
7267
7268        initialize($el, opts) {
7269			this.$el = $el;
7270
7271			this
7272				.setData()
7273				.setOptions(opts)
7274				.build();
7275
7276			return this;
7277		}
7278
7279        setData() {
7280			this.$el.data(instanceName, this);
7281
7282			return this;
7283		}
7284
7285        setOptions(opts) {
7286			this.options = $.extend(true, {}, PluginStarRating.defaults, opts, {
7287				wrapper: this.$el
7288			});
7289
7290			return this;
7291		}
7292
7293        build() {
7294
7295			if (!($.isFunction($.fn.rating))) {
7296				return this;
7297			}
7298
7299			const self = this;
7300
7301			self.options.wrapper
7302				.rating(self.options);
7303
7304			self.options.wrapper.parents('.rating-container')
7305				.addClass('rating-' + self.options.color);
7306
7307			if( self.options.extraClass ) {
7308				self.options.wrapper.parents('.rating-container')
7309					.addClass(self.options.extraClass);
7310			}
7311
7312			return this;
7313
7314		}
7315    }
7316
7317    PluginStarRating.defaults = {
7318		theme: 'krajee-fas',
7319		color: 'primary',
7320		showClear: false,
7321		showCaption: false
7322	};
7323
7324    // expose to scope
7325    $.extend(theme, {
7326		PluginStarRating
7327	});
7328
7329    // jquery plugin
7330    $.fn.themePluginStarRating = function(opts) {
7331		return this.map(function() {
7332			const $this = $(this);
7333
7334			if ($this.data(instanceName)) {
7335				return $this.data(instanceName);
7336			} else {
7337				return new PluginStarRating($this, opts);
7338			}
7339
7340		});
7341	}
7342})).apply(this, [window.theme, jQuery]);
7343
7344// Sticky
7345(((theme = {}, $) => {
7346    const instanceName = '__sticky';
7347
7348    class PluginSticky {
7349        constructor($el, opts) {
7350            return this.initialize($el, opts);
7351        }
7352
7353        initialize($el, opts) {
7354			if ( $el.data( instanceName ) ) {
7355				return this;
7356			}
7357
7358			this.$el = $el;
7359
7360			this
7361				.setData()
7362				.setOptions(opts)
7363				.build()
7364				.events();
7365
7366			return this;
7367		}
7368
7369        setData() {
7370			this.$el.data(instanceName, this);
7371
7372			return this;
7373		}
7374
7375        setOptions(opts) {
7376			this.options = $.extend(true, {}, PluginSticky.defaults, opts, {
7377				wrapper: this.$el
7378			});
7379
7380			return this;
7381		}
7382
7383        build() {
7384			if (!($.isFunction($.fn.pin))) {
7385				return this;
7386			}
7387
7388			const self = this, $window = $(window);
7389			
7390			self.options.wrapper.pin(self.options);
7391
7392			if( self.options.wrapper.hasClass('sticky-wrapper-transparent') ) {
7393				self.options.wrapper.parent().addClass('position-absolute w-100');
7394			}
7395
7396			$window.afterResize(() => {
7397				self.options.wrapper.removeAttr('style').removeData('pin');
7398				self.options.wrapper.pin(self.options);
7399				$window.trigger('scroll');
7400			});
7401
7402			// Change Logo Src
7403			if( self.options.wrapper.find('img').attr('data-change-src') ) {
7404				const $logo = self.options.wrapper.find('img'), logoSrc = $logo.attr('src'), logoNewSrc = $logo.attr('data-change-src');
7405
7406				self.changeLogoSrc = activate => {
7407					if(activate) {
7408						$logo.attr('src', logoNewSrc);
7409					} else {
7410						$logo.attr('src', logoSrc);
7411					}
7412				}
7413			}
7414			
7415			return this;
7416		}
7417
7418        events() {
7419            const self = this;
7420            const $window = $(window);
7421            const $logo = self.options.wrapper.find('img');
7422			const classToCheck = ( self.options.wrapper.hasClass('sticky-wrapper-effect-1') ) ? 'sticky-effect-active' : 'sticky-active';
7423            let stickyActivateFlag = true;
7424            let stickyDeactivateFlag = false;
7425
7426            $window.on('scroll sticky.effect.active', () => {
7427				if( self.options.wrapper.hasClass( classToCheck ) ) {		
7428					if( stickyActivateFlag ) {			
7429						if( $logo.attr('data-change-src') ) {
7430							self.changeLogoSrc(true);
7431						}
7432
7433						stickyActivateFlag = false;
7434						stickyDeactivateFlag = true;
7435					}
7436				} else {	
7437					if( stickyDeactivateFlag ) {				
7438						if( $logo.attr('data-change-src') ) {
7439							self.changeLogoSrc(false);
7440						}
7441
7442						stickyDeactivateFlag = false;
7443						stickyActivateFlag = true;
7444					}
7445				}
7446			});
7447
7448            let isGoingUp = false;
7449            if( self.options.stickyStartEffectAt ) {
7450
7451				// First Load
7452				if( self.options.stickyStartEffectAt < $window.scrollTop() ) {
7453					self.options.wrapper.addClass('sticky-effect-active');
7454
7455					$window.trigger('sticky.effect.active');
7456				}
7457
7458				$window.on('scroll', () => {
7459					if( self.options.stickyStartEffectAt < $window.scrollTop() ) {	
7460						self.options.wrapper.addClass('sticky-effect-active');
7461						isGoingUp = true;
7462
7463						$window.trigger('sticky.effect.active');
7464					} else {	
7465						if( isGoingUp ) {
7466							self.options.wrapper.find('.sticky-body').addClass('position-fixed');
7467							isGoingUp = false;
7468						}
7469
7470						if( $window.scrollTop() == 0 ) {
7471							self.options.wrapper.find('.sticky-body').removeClass('position-fixed');
7472						}
7473
7474						self.options.wrapper.removeClass('sticky-effect-active');
7475					}
7476				});
7477			}
7478
7479            // Refresh Sticky Plugin if click in a data-toggle="collapse"
7480            if( $('[data-bs-toggle="collapse"]').get(0) ) {
7481
7482				$('[data-bs-toggle="collapse"]').on('click', () => {
7483					setTimeout(() => {
7484						self.build();
7485						$(window).trigger('scroll');
7486					}, 1000);
7487				});
7488
7489			}
7490
7491			// Visibility Issue
7492			document.addEventListener('visibilitychange', () => {
7493				$(window).trigger('resize');
7494			});
7495
7496			setInterval(() => {
7497				$(window).trigger('resize');
7498			}, 1000);
7499
7500        }
7501    }
7502
7503    PluginSticky.defaults = {
7504		minWidth: 991,
7505		activeClass: 'sticky-active'
7506	};
7507
7508    // expose to scope
7509    $.extend(theme, {
7510		PluginSticky
7511	});
7512
7513    // jquery plugin
7514    $.fn.themePluginSticky = function(opts) {
7515		return this.map(function() {
7516			const $this = $(this);
7517
7518			if ($this.data(instanceName)) {
7519				return $this.data(instanceName);
7520			} else {
7521				return new PluginSticky($this, opts);
7522			}
7523			
7524		});
7525	}
7526})).apply(this, [ window.theme, jQuery ]);
7527
7528// Toggle
7529(((theme = {}, $) => {
7530    const instanceName = '__toggle';
7531
7532    class PluginToggle {
7533        constructor($el, opts) {
7534            return this.initialize($el, opts);
7535        }
7536
7537        initialize($el, opts) {
7538			if ($el.data(instanceName)) {
7539				return this;
7540			}
7541
7542			this.$el = $el;
7543
7544			this
7545				.setData()
7546				.setOptions(opts)
7547				.build();
7548
7549			return this;
7550		}
7551
7552        setData() {
7553			this.$el.data(instanceName, this);
7554
7555			return this;
7556		}
7557
7558        setOptions(opts) {
7559			this.options = $.extend(true, {}, PluginToggle.defaults, opts, {
7560				wrapper: this.$el
7561			});
7562
7563			return this;
7564		}
7565
7566        build() {
7567            const self = this;
7568            const $wrapper = this.options.wrapper;
7569            const $items = $wrapper.find('> .toggle');
7570            let $el = null;
7571
7572            $items.each(function() {
7573				$el = $(this);
7574
7575				if ($el.hasClass('active')) {
7576					$el.find('> p').addClass('preview-active');
7577					$el.find('> .toggle-content').slideDown(self.options.duration);
7578				}
7579
7580				self.events($el);
7581			});
7582
7583            if (self.options.isAccordion) {
7584				self.options.duration = self.options.duration / 2;
7585			}
7586
7587            return this;
7588        }
7589
7590        events($el) {
7591            const self = this;
7592            let previewParCurrentHeight = 0;
7593            let previewParAnimateHeight = 0;
7594            let toggleContent = null;
7595
7596            $el.find('> label, > .toggle-title').click(function({originalEvent}) {
7597                const $this = $(this);
7598                const parentSection = $this.parent();
7599                const parentWrapper = $this.parents('.toggle');
7600                let previewPar = null;
7601                let closeElement = null;
7602
7603                if (self.options.isAccordion && typeof(originalEvent) != 'undefined') {
7604					closeElement = parentWrapper.find('.toggle.active > label, .toggle.active > .toggle-title');
7605
7606					if (closeElement[0] == $this[0]) {
7607						return;
7608					}
7609				}
7610
7611                parentSection.toggleClass('active');
7612
7613                // Preview Paragraph
7614                if (parentSection.find('> p').get(0)) {
7615
7616					previewPar = parentSection.find('> p');
7617					previewParCurrentHeight = previewPar.css('height');
7618					previewPar.css('height', 'auto');
7619					previewParAnimateHeight = previewPar.css('height');
7620					previewPar.css('height', previewParCurrentHeight);
7621
7622				}
7623
7624                // Content
7625                toggleContent = parentSection.find('> .toggle-content');
7626
7627                if (parentSection.hasClass('active')) {
7628
7629					$(previewPar).animate({
7630						height: previewParAnimateHeight
7631					}, self.options.duration, function() {
7632						$(this).addClass('preview-active');
7633					});
7634
7635					toggleContent.slideDown(self.options.duration, () => {
7636						if (closeElement) {
7637							closeElement.trigger('click');
7638						}
7639					});
7640
7641				} else {
7642
7643					$(previewPar).animate({
7644						height: 0
7645					}, self.options.duration, function() {
7646						$(this).removeClass('preview-active');
7647					});
7648
7649					toggleContent.slideUp(self.options.duration);
7650
7651				}
7652            });
7653        }
7654    }
7655
7656    PluginToggle.defaults = {
7657		duration: 350,
7658		isAccordion: false
7659	};
7660
7661    // expose to scope
7662    $.extend(theme, {
7663		PluginToggle
7664	});
7665
7666    // jquery plugin
7667    $.fn.themePluginToggle = function(opts) {
7668		return this.map(function() {
7669			const $this = $(this);
7670
7671			if ($this.data(instanceName)) {
7672				return $this.data(instanceName);
7673			} else {
7674				return new PluginToggle($this, opts);
7675			}
7676
7677		});
7678	}
7679})).apply(this, [window.theme, jQuery]);
7680
7681// Validation
7682(((theme = {}, $) => {
7683    $.extend(theme, {
7684
7685		PluginValidation: {
7686
7687			defaults: {
7688				formClass: 'needs-validation',
7689				validator: {
7690					highlight(element) {
7691						$(element)
7692							.addClass('is-invalid')
7693							.removeClass('is-valid')
7694							.parent()
7695							.removeClass('has-success')
7696							.addClass('has-danger');
7697					},
7698					success(label, element) {
7699						$(element)
7700							.removeClass('is-invalid')
7701							.addClass('is-valid')
7702							.parent()
7703							.removeClass('has-danger')
7704							.addClass('has-success')
7705							.find('label.error')
7706							.remove();
7707					},
7708					errorPlacement(error, element) {
7709						if (element.attr('type') == 'radio' || element.attr('type') == 'checkbox') {
7710							error.appendTo(element.parent().parent());
7711						} else {
7712							error.insertAfter(element);
7713						}
7714					}
7715				}
7716			},
7717
7718			initialize(opts) {
7719				initialized = true;
7720
7721				this
7722					.setOptions(opts)
7723					.build();
7724
7725				return this;
7726			},
7727
7728			setOptions(opts) {
7729				this.options = $.extend(true, {}, this.defaults, opts);
7730
7731				return this;
7732			},
7733
7734			build() {
7735				const self = this;
7736
7737				if (!($.isFunction($.validator))) {
7738					return this;
7739				}
7740
7741				self.setMessageGroups();
7742
7743				$.validator.setDefaults(self.options.validator);
7744
7745				$('.' + self.options.formClass).validate();
7746
7747				return this;
7748			},
7749
7750			setMessageGroups() {
7751
7752				$('.checkbox-group[data-msg-required], .radio-group[data-msg-required]').each(function() {
7753					const message = $(this).data('msg-required');
7754					$(this).find('input').attr('data-msg-required', message);
7755				});
7756
7757			}
7758
7759		}
7760
7761	});
7762})).apply(this, [window.theme, jQuery]);
7763
7764// Video Background
7765(((theme = {}, $) => {
7766    const instanceName = '__videobackground';
7767
7768    class PluginVideoBackground {
7769        constructor($el, opts) {
7770            return this.initialize($el, opts);
7771        }
7772
7773        initialize($el, opts) {
7774			this.$el = $el;
7775
7776			this
7777				.setData()
7778				.setOptions(opts)
7779				.build()
7780				.events();
7781
7782			return this;
7783		}
7784
7785        setData() {
7786			this.$el.data(instanceName, this);
7787
7788			return this;
7789		}
7790
7791        setOptions(opts) {
7792			this.options = $.extend(true, {}, PluginVideoBackground.defaults, opts, {
7793				path: this.$el.data('video-path'),
7794				wrapper: this.$el
7795			});
7796
7797			return this;
7798		}
7799
7800        build() {
7801			const self = this;
7802
7803			if (!($.isFunction($.fn.vide)) || (!this.options.path)) {
7804				return this;
7805			}
7806
7807			if (this.options.overlay) {
7808
7809				const overlayClass = this.options.overlayClass;
7810
7811				this.options.wrapper.prepend(
7812					$('<div />').addClass(overlayClass)
7813				);
7814			}
7815
7816			this.options.wrapper
7817				.vide(this.options.path, this.options)
7818				.first()
7819				.css('z-index', 0);
7820
7821			// Change Poster
7822			self.changePoster();
7823
7824			// Initialize Vide inside a carousel
7825			if( self.options.wrapper.closest('.owl-carousel').get(0) ) {
7826				self.options.wrapper.closest('.owl-carousel').on('initialized.owl.carousel', () => {
7827					$('.owl-item.cloned')
7828						.find('[data-plugin-video-background] .vide-video-wrapper')
7829						.remove();
7830
7831					$('.owl-item.cloned')
7832						.find('[data-plugin-video-background]')
7833						.vide(self.options.path, self.options)
7834						.first()
7835						.css('z-index', 0);
7836
7837					self.changePoster( self.options.wrapper.closest('.owl-carousel') );
7838				});
7839			}
7840
7841			// Play Video Button
7842			const $playButton = self.options.wrapper.find('.video-background-play');
7843
7844			if( $playButton.get(0) ) {
7845				const $playWrapper = self.options.wrapper.find('.video-background-play-wrapper');
7846
7847				self.options.wrapper.find('.video-background-play').on('click', e => {
7848					e.preventDefault();
7849
7850					if( $playWrapper.get(0) ) {
7851						$playWrapper.animate({
7852							opacity: 0
7853						}, 300, () => {
7854							$playWrapper.parent().height( $playWrapper.outerHeight() );
7855							$playWrapper.remove();
7856						});
7857					} else {
7858						$playButton.animate({
7859							opacity: 0
7860						}, 300, () => {
7861							$playButton.remove();
7862						});
7863					}
7864
7865					setTimeout(() => {
7866						self.options.wrapper.find('video')[0].play();
7867					}, 500)
7868				});
7869			}
7870
7871			$(window).trigger('vide.video.inserted.on.dom');
7872
7873			return this;
7874		}
7875
7876        changePoster($carousel) {
7877			const self = this;
7878
7879			// If it's inside carousel
7880			if( $carousel && self.options.changePoster ) {
7881				$carousel.find('.owl-item [data-plugin-video-background] .vide-video-wrapper').css({
7882					'background-image': 'url(' + self.options.changePoster + ')'
7883				});
7884
7885				return this;
7886			}
7887
7888			if( self.options.changePoster ) {
7889				self.options.wrapper.find('.vide-video-wrapper').css({
7890					'background-image': 'url(' + self.options.changePoster + ')'
7891				});
7892			}
7893
7894			return this;
7895		}
7896
7897        events() {
7898			const self = this;
7899
7900			// Initialize
7901			self.options.wrapper.on('video.background.initialize', () => {
7902				self.build();
7903			});
7904
7905			return this;
7906		}
7907    }
7908
7909    PluginVideoBackground.defaults = {
7910		overlay: false,
7911		volume: 1,
7912		playbackRate: 1,
7913		muted: true,
7914		loop: true,
7915		autoplay: true,
7916		position: '50% 50%',
7917		posterType: 'detect',
7918		className: 'vide-video-wrapper'
7919	};
7920
7921    // expose to scope
7922    $.extend(theme, {
7923		PluginVideoBackground
7924	});
7925
7926    // jquery plugin
7927    $.fn.themePluginVideoBackground = function(opts) {
7928		return this.map(function() {
7929			const $this = $(this);
7930
7931			if ($this.data(instanceName)) {
7932				return $this.data(instanceName);
7933			} else {
7934				return new PluginVideoBackground($this, opts);
7935			}
7936
7937		});
7938	}
7939})).apply(this, [window.theme, jQuery]);
7940
7941// Account
7942(((theme = {}, $) => {
7943    let initialized = false;
7944
7945    $.extend(theme, {
7946
7947		Account: {
7948
7949			defaults: {
7950				wrapper: $('#headerAccount')
7951			},
7952
7953			initialize($wrapper, opts) {
7954				if (initialized) {
7955					return this;
7956				}
7957
7958				initialized = true;
7959				this.$wrapper = ($wrapper || this.defaults.wrapper);
7960
7961				this
7962					.setOptions(opts)
7963					.events();
7964
7965				return this;
7966			},
7967
7968			setOptions(opts) {
7969				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
7970
7971				return this;
7972			},
7973
7974			events() {
7975				const self = this;
7976
7977				$(window).on('load', () => {
7978					$(document).ready(() => {
7979						setTimeout(() => {
7980
7981							self.$wrapper.find('input').on('focus', () => {
7982								self.$wrapper.addClass('open');
7983
7984								$(document).mouseup(({target}) => {
7985									if (!self.$wrapper.is(target) && self.$wrapper.has(target).length === 0) {
7986										self.$wrapper.removeClass('open');
7987									}
7988								});
7989							});
7990
7991						}, 1500);
7992					});
7993				});
7994
7995				$('#headerSignUp').on('click', e => {
7996					e.preventDefault();
7997					self.$wrapper.addClass('signup').removeClass('signin').removeClass('recover');
7998					self.$wrapper.find('.signup-form input:first').focus();
7999				});
8000
8001				$('#headerSignIn').on('click', e => {
8002					e.preventDefault();
8003					self.$wrapper.addClass('signin').removeClass('signup').removeClass('recover');
8004					self.$wrapper.find('.signin-form input:first').focus();
8005				});
8006
8007				$('#headerRecover').on('click', e => {
8008					e.preventDefault();
8009					self.$wrapper.addClass('recover').removeClass('signup').removeClass('signin');
8010					self.$wrapper.find('.recover-form input:first').focus();
8011				});
8012
8013				$('#headerRecoverCancel').on('click', e => {
8014					e.preventDefault();
8015					self.$wrapper.addClass('signin').removeClass('signup').removeClass('recover');
8016					self.$wrapper.find('.signin-form input:first').focus();
8017				});
8018			}
8019
8020		}
8021
8022	});
8023})).apply(this, [window.theme, jQuery]);
8024
8025// Nav
8026(((theme = {}, $) => {
8027    let initialized = false;
8028
8029    $.extend(theme, {
8030
8031		Nav: {
8032
8033			defaults: {
8034				wrapper: $('#mainNav'),
8035				scrollDelay: 600,
8036				scrollAnimation: 'easeOutQuad'
8037			},
8038
8039			initialize($wrapper, opts) {
8040				if (initialized) {
8041					return this;
8042				}
8043
8044				initialized = true;
8045				this.$wrapper = ($wrapper || this.defaults.wrapper);
8046
8047				this
8048					.setOptions(opts)
8049					.build()
8050					.events();
8051
8052				return this;
8053			},
8054
8055			setOptions(opts) {
8056				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
8057
8058				return this;
8059			},
8060
8061			build() {
8062                const self = this;
8063                const $html = $('html');
8064                const $header = $('#header');
8065                const $headerNavMain = $('#header .header-nav-main');
8066                let thumbInfoPreview;
8067
8068                // Preview Thumbs
8069                if( self.$wrapper.find('a[data-thumb-preview]').length ) {
8070					self.$wrapper.find('a[data-thumb-preview]').each(function() {
8071						thumbInfoPreview = $('<span />').addClass('thumb-info thumb-info-preview')
8072												.append($('<span />').addClass('thumb-info-wrapper')
8073													.append($('<span />').addClass('thumb-info-image').css('background-image', 'url(' + $(this).data('thumb-preview') + ')')
8074											   )
8075										   );
8076
8077						$(this).append(thumbInfoPreview);
8078					});
8079				}
8080
8081                // Side Header / Side Header Hamburguer Sidebar (Reverse Dropdown)
8082                if($html.hasClass('side-header') || $html.hasClass('side-header-hamburguer-sidebar')) {
8083					
8084					// Side Header Right / Side Header Hamburguer Sidebar Right
8085					if($html.hasClass('side-header-right') || $html.hasClass('side-header-hamburguer-sidebar-right')) {
8086						if(!$html.hasClass('side-header-right-no-reverse')) {
8087							$header.find('.dropdown-submenu').addClass('dropdown-reverse');
8088						}
8089					}
8090
8091				} else {
8092					
8093					// Reverse
8094					let checkReverseFlag = false;
8095					self.checkReverse = () => {
8096						if( !checkReverseFlag ) {
8097							self.$wrapper.find('.dropdown, .dropdown-submenu').removeClass('dropdown-reverse');
8098
8099							self.$wrapper.find('.dropdown:not(.manual):not(.dropdown-mega), .dropdown-submenu:not(.manual)').each(function() {
8100								if(!$(this).find('.dropdown-menu').visible( false, true, 'horizontal' )  ) {
8101									$(this).addClass('dropdown-reverse');
8102								}
8103							});
8104
8105							checkReverseFlag = true;
8106						}
8107					}
8108
8109					$(window).on('resize', () => {
8110						checkReverseFlag = false;
8111					});
8112
8113					$header.on('mouseover', () => {
8114						self.checkReverse();
8115					});
8116
8117				}
8118
8119                // Clone Items
8120                if($headerNavMain.hasClass('header-nav-main-clone-items')) {
8121
8122			    	$headerNavMain.find('nav > ul > li > a').each(function(){
8123				    	const parent = $(this).parent(), clone  = $(this).clone(), clone2 = $(this).clone(), wrapper = $('<span class="wrapper-items-cloned"></span>');
8124
8125				    	// Config Classes
8126				    	$(this).addClass('item-original');
8127				    	clone2.addClass('item-two');
8128
8129				    	// Insert on DOM
8130				    	parent.prepend(wrapper);
8131				    	wrapper.append(clone).append(clone2);
8132				    });
8133
8134				}
8135
8136                // Floating
8137                if($('#header.header-floating-icons').length && $(window).width() > 991) {
8138
8139					const menuFloatingAnim = {
8140						$menuFloating: $('#header.header-floating-icons .header-container > .header-row'),
8141
8142						build() {
8143							const self = this;
8144
8145							self.init();
8146						},
8147						init() {
8148                            const self  = this;
8149                            let divisor = 0;
8150
8151                            $(window).scroll(function() {
8152							    const scrollPercent = 100 * $(window).scrollTop() / ($(document).height() - $(window).height()), st = $(this).scrollTop();
8153
8154								divisor = $(document).height() / $(window).height();
8155
8156							    self.$menuFloating.find('.header-column > .header-row').css({
8157							    	transform : 'translateY( calc('+ scrollPercent +'vh - '+ st / divisor +'px) )' 
8158							    });
8159							});
8160                        }
8161					};
8162
8163					menuFloatingAnim.build();
8164
8165				}
8166
8167                // Slide
8168                if($('.header-nav-links-vertical-slide').length) {
8169					const slideNavigation = {
8170						$mainNav: $('#mainNav'),
8171						$mainNavItem: $('#mainNav li'),
8172
8173						build() {
8174							const self = this;
8175
8176							self.menuNav();
8177						},
8178						menuNav() {
8179							const self = this;
8180
8181							self.$mainNavItem.on('click', function(e){
8182								const currentMenuItem 	= $(this), currentMenu 		= $(this).parent(), nextMenu        	= $(this).find('ul').first(), prevMenu        	= $(this).closest('.next-menu'), isSubMenu       	= currentMenuItem.hasClass('dropdown') || currentMenuItem.hasClass('dropdown-submenu'), isBack          	= currentMenuItem.hasClass('back-button'), nextMenuHeightDiff  = ( ( nextMenu.find('> li').length * nextMenu.find('> li').outerHeight() ) - nextMenu.outerHeight() ), prevMenuHeightDiff  = ( ( prevMenu.find('> li').length * prevMenu.find('> li').outerHeight() ) - prevMenu.outerHeight() );
8183
8184								if( isSubMenu ) {
8185									currentMenu.addClass('next-menu');
8186									nextMenu.addClass('visible');
8187									currentMenu.css({
8188										overflow: 'visible',
8189										'overflow-y': 'visible'
8190									});
8191									
8192									if( nextMenuHeightDiff > 0 ) {
8193										nextMenu.css({
8194											overflow: 'hidden',
8195											'overflow-y': 'scroll'
8196										});
8197									}
8198
8199									for( i = 0; i < nextMenu.find('> li').length; i++ ) {
8200										if( nextMenu.outerHeight() < ($('.header-row-side-header').outerHeight() - 100) ) {
8201											nextMenu.css({
8202												height: nextMenu.outerHeight() + nextMenu.find('> li').outerHeight()
8203											});
8204										}
8205									}
8206
8207									nextMenu.css({
8208										'padding-top': nextMenuHeightDiff + 'px'
8209									});
8210								}
8211
8212								if( isBack ) {
8213									currentMenu.parent().parent().removeClass('next-menu');
8214									currentMenu.removeClass('visible');
8215
8216									if( prevMenuHeightDiff > 0 ) {
8217										prevMenu.css({
8218											overflow: 'hidden',
8219											'overflow-y': 'scroll'
8220										});
8221									}
8222								}
8223
8224								e.stopPropagation();
8225							});
8226						}
8227					};
8228
8229					$(window).trigger('resize');
8230					
8231					if( $(window).width() > 991 ) {
8232						slideNavigation.build();
8233					}
8234
8235					$(document).ready(() => {
8236						$(window).afterResize(() => {
8237							if( $(window).width() > 991 ) {
8238								slideNavigation.build();
8239							}
8240						});
8241					});
8242				}
8243
8244                // Header Nav Main Mobile Dark
8245                if($('.header-nav-main-mobile-dark').length) {
8246					$('#header:not(.header-transparent-dark-bottom-border):not(.header-transparent-light-bottom-border)').addClass('header-no-border-bottom');
8247				}
8248
8249                // Keyboard Navigation / Accessibility
8250                if( $(window).width() > 991 ) {
8251					let focusFlag = false;
8252					$header.find('.header-nav-main nav > ul > li > a').on('focus', function(){
8253						
8254						if( $(window).width() > 991 ) {
8255							if( !focusFlag ) {
8256								focusFlag = true;
8257								$(this).trigger('blur');
8258								
8259								self.focusMenuWithChildren();
8260							}
8261						}
8262
8263					});
8264				}
8265
8266                return this;
8267            },
8268
8269			focusMenuWithChildren() {
8270                // Get all the link elements within the primary menu.
8271                let links;
8272
8273                let i;
8274                let len;
8275                const menu = document.querySelector( 'html:not(.side-header):not(.side-header-hamburguer-sidebar):not(.side-header-overlay-full-screen) .header-nav-main > nav' );
8276
8277                if ( ! menu ) {
8278					return false;
8279				}
8280
8281                links = menu.getElementsByTagName( 'a' );
8282
8283                // Each time a menu link is focused or blurred, toggle focus.
8284                for ( i = 0, len = links.length; i < len; i++ ) {
8285					links[i].addEventListener( 'focus', toggleFocus, true );
8286					links[i].addEventListener( 'blur', toggleFocus, true );
8287				}
8288
8289                //Sets or removes the .focus class on an element.
8290                function toggleFocus() {
8291					let self = this;
8292
8293					// Move up through the ancestors of the current link until we hit .primary-menu.
8294					while ( !self.className.includes('header-nav-main') ) {
8295						// On li elements toggle the class .focus.
8296						if ( 'li' === self.tagName.toLowerCase() ) {
8297							if ( self.className.includes('accessibility-open') ) {
8298								self.className = self.className.replace( ' accessibility-open', '' );
8299							} else {
8300								self.className += ' accessibility-open';
8301							}
8302						}
8303						self = self.parentElement;
8304					}
8305				}
8306            },
8307
8308			events() {
8309                const self    = this;
8310                const $html   = $('html');
8311                let $header = $('#header');
8312                const $window = $(window);
8313                let headerBodyHeight = $('.header-body').outerHeight();
8314
8315                if( $header.hasClass('header') ) {
8316					$header = $('.header');
8317				}
8318
8319                $header.find('a[href="#"]').on('click', e => {
8320					e.preventDefault();
8321				});
8322
8323                // Mobile Arrows
8324                if( $html.hasClass('side-header-hamburguer-sidebar') ) {
8325					$header.find('.dropdown-toggle, .dropdown-submenu > a')
8326						.append('<i class="fas fa-chevron-down fa-chevron-right"></i>');
8327				} else {
8328					$header.find('.dropdown-toggle, .dropdown-submenu > a')
8329						.append('<i class="fas fa-chevron-down"></i>');
8330				}
8331
8332                $header.find('.dropdown-toggle[href="#"], .dropdown-submenu a[href="#"], .dropdown-toggle[href!="#"] .fa-chevron-down, .dropdown-submenu a[href!="#"] .fa-chevron-down').on('click', function(e) {
8333					e.preventDefault();
8334					if ($window.width() < 992) {
8335						$(this).closest('li').toggleClass('open');
8336
8337						// Adjust Header Body Height
8338						const height = ( $header.hasClass('header-effect-shrink') && $html.hasClass('sticky-header-active') ) ? theme.StickyHeader.options.stickyHeaderContainerHeight : headerBodyHeight;
8339						$('.header-body').animate({
8340					 		height: ($('.header-nav-main nav').outerHeight(true) + height) + 10
8341					 	}, 0);
8342					}
8343				});
8344
8345                $header.find('li a.active').addClass('current-page-active');
8346
8347                // Add Open Class
8348                $header.find('.header-nav-click-to-open .dropdown-toggle[href="#"], .header-nav-click-to-open .dropdown-submenu a[href="#"], .header-nav-click-to-open .dropdown-toggle > i').on('click', function(e) {
8349					if( !$('html').hasClass('side-header-hamburguer-sidebar') && $window.width() > 991 ) {
8350						e.preventDefault();
8351						e.stopPropagation();
8352					}
8353
8354					if ($window.width() > 991) {
8355						e.preventDefault();
8356						e.stopPropagation();
8357
8358						$header.find('li a.active').removeClass('active');
8359
8360						if( $(this).prop('tagName') == 'I' ) {
8361							$(this).parent().addClass('active');
8362						} else {
8363							$(this).addClass('active');
8364						}
8365
8366						if (!$(this).closest('li').hasClass('open')) {
8367                            const $li = $(this).closest('li');
8368                            let isSub = false;
8369
8370                            if( $(this).prop('tagName') == 'I' ) {
8371								$('#header .dropdown.open').removeClass('open');
8372								$('#header .dropdown-menu .dropdown-submenu.open').removeClass('open');
8373							}
8374
8375                            if ( $(this).parent().hasClass('dropdown-submenu') ) {
8376								isSub = true;
8377							}
8378
8379                            $(this).closest('.dropdown-menu').find('.dropdown-submenu.open').removeClass('open');
8380                            $(this).parent('.dropdown').parent().find('.dropdown.open').removeClass('open');
8381
8382                            if (!isSub) {
8383								$(this).parent().find('.dropdown-submenu.open').removeClass('open');
8384							}
8385
8386                            $li.addClass('open');
8387
8388                            $(document).off('click.nav-click-to-open').on('click.nav-click-to-open', ({target}) => {
8389								if (!$li.is(target) && $li.has(target).length === 0) {
8390									$li.removeClass('open');
8391									$li.parents('.open').removeClass('open');
8392									$header.find('li a.active').removeClass('active');
8393									$header.find('li a.current-page-active').addClass('active');
8394								}
8395							});
8396                        } else {
8397							$(this).closest('li').removeClass('open');
8398							$header.find('li a.active').removeClass('active');
8399							$header.find('li a.current-page-active').addClass('active');
8400						}
8401
8402						$window.trigger({
8403							type: 'resize',
8404							from: 'header-nav-click-to-open'
8405						});
8406					}
8407				});
8408
8409                // Collapse Nav
8410                $header.find('[data-collapse-nav]').on('click', function(e) {
8411					$(this).parents('.collapse').removeClass('show');
8412				});
8413
8414                // Top Features
8415                $header.find('.header-nav-features-toggle').on('click', function(e) {
8416					e.preventDefault();
8417
8418					const $toggleParent = $(this).parent();
8419
8420					if (!$(this).siblings('.header-nav-features-dropdown').hasClass('show')) {
8421
8422						const $dropdown = $(this).siblings('.header-nav-features-dropdown');
8423
8424						$('.header-nav-features-dropdown.show').removeClass('show');
8425
8426						$dropdown.addClass('show');
8427
8428						$(document).off('click.header-nav-features-toggle').on('click.header-nav-features-toggle', ({target}) => {
8429							if (!$toggleParent.is(target) && $toggleParent.has(target).length === 0) {
8430								$('.header-nav-features-dropdown.show').removeClass('show');
8431							}
8432						});
8433
8434						if ($(this).attr('data-focus')) {
8435							$('#' + $(this).attr('data-focus')).focus();
8436						}
8437
8438					} else {
8439						$(this).siblings('.header-nav-features-dropdown').removeClass('show');
8440					}
8441				});
8442
8443                // Hamburguer Menu
8444                const $hamburguerMenuBtn = $('.hamburguer-btn:not(.side-panel-toggle)'), $hamburguerSideHeader = $('#header.side-header, #header.side-header-overlay-full-screen');
8445
8446                $hamburguerMenuBtn.on('click', function(){
8447					if($(this).attr('data-set-active') != 'false') {
8448						$(this).toggleClass('active');
8449					}
8450					$hamburguerSideHeader.toggleClass('side-header-hide');
8451					$html.toggleClass('side-header-hide');
8452
8453					$window.trigger('resize');
8454				});
8455
8456                // Toggle Side Header
8457                $('.toggle-side-header').on('click', () => {
8458					$('.hamburguer-btn-side-header.active').trigger('click');
8459				});
8460
8461                $('.hamburguer-close:not(.side-panel-toggle)').on('click', () => {
8462					$('.hamburguer-btn:not(.hamburguer-btn-side-header-mobile-show)').trigger('click');
8463				});
8464
8465                // Set Header Body Height when open mobile menu
8466                $('.header-nav-main nav').on('show.bs.collapse', function () {
8467				 	$(this).removeClass('closed');
8468
8469				 	// Add Mobile Menu Opened Class
8470				 	$('html').addClass('mobile-menu-opened');
8471
8472			 		$('.header-body').animate({
8473				 		height: ($('.header-body').outerHeight() + $('.header-nav-main nav').outerHeight(true)) + 10
8474				 	});
8475
8476				 	// Header Below Slider / Header Bottom Slider - Scroll to menu position
8477				 	if( $('#header').is('.header-bottom-slider, .header-below-slider') && !$('html').hasClass('sticky-header-active') ) {
8478				 		self.scrollToTarget( $('#header'), 0 );
8479				 	}
8480				});
8481
8482                // Set Header Body Height when collapse mobile menu
8483                $('.header-nav-main nav').on('hide.bs.collapse', function () {
8484				 	$(this).addClass('closed');
8485
8486				 	// Remove Mobile Menu Opened Class
8487				 	$('html').removeClass('mobile-menu-opened');
8488
8489			 		$('.header-body').animate({
8490				 		height: ($('.header-body').outerHeight() - $('.header-nav-main nav').outerHeight(true))
8491				 	}, function(){
8492				 		$(this).height('auto');
8493				 	});
8494				});
8495
8496                // Header Effect Shrink - Adjust header body height on mobile
8497                $window.on('stickyHeader.activate', () => {
8498					if( $window.width() < 992 && $header.hasClass('header-effect-shrink') ) {
8499						if( $('.header-btn-collapse-nav').attr('aria-expanded') == 'true' ) {
8500							$('.header-body').animate({
8501						 		height: ( $('.header-nav-main nav').outerHeight(true) + theme.StickyHeader.options.stickyHeaderContainerHeight ) + ( ($('.header-nav-bar').length) ? $('.header-nav-bar').outerHeight() : 0 ) 
8502						 	});
8503						}
8504					}
8505				});
8506
8507                $window.on('stickyHeader.deactivate', () => {
8508					if( $window.width() < 992 && $header.hasClass('header-effect-shrink') ) {
8509						if( $('.header-btn-collapse-nav').attr('aria-expanded') == 'true' ) {
8510							$('.header-body').animate({
8511						 		height: headerBodyHeight + $('.header-nav-main nav').outerHeight(true) + 10
8512						 	});
8513						}
8514					}
8515				});
8516
8517                // Remove Open Class on Resize		
8518                $window.on('resize.removeOpen', ({from}) => {
8519					if( from == 'header-nav-click-to-open' ) {
8520						return;
8521					}
8522					
8523					setTimeout(() => {
8524						if( $window.width() > 991 ) {
8525							$header.find('.dropdown.open').removeClass('open');
8526						}
8527					}, 100);
8528				});
8529
8530                // Side Header - Change value of initial header body height
8531                $(document).ready(() => {
8532					if( $window.width() > 991 ) {
8533						let flag = false;
8534						
8535						$window.on('resize', ({from}) => {
8536							if( from == 'header-nav-click-to-open' ) {
8537								return;
8538							}
8539
8540							$header.find('.dropdown.open').removeClass('open');
8541
8542							if( $window.width() < 992 && flag == false ) {
8543								headerBodyHeight = $('.header-body').outerHeight();
8544								flag = true;
8545
8546								setTimeout(() => {
8547									flag = false;
8548								}, 500);
8549							}
8550						});
8551					}
8552				});
8553
8554                // Side Header - Set header height on mobile
8555                if( $html.hasClass('side-header') ) {
8556					if( $window.width() < 992 ) {
8557						$header.css({
8558							height: $('.header-body .header-container').outerHeight() + (parseInt( $('.header-body').css('border-top-width') ) + parseInt( $('.header-body').css('border-bottom-width') ))
8559						});
8560					}
8561
8562					$(document).ready(() => {
8563						$window.afterResize(() => {
8564							if( $window.width() < 992 ) {
8565								$header.css({
8566									height: $('.header-body .header-container').outerHeight() + (parseInt( $('.header-body').css('border-top-width') ) + parseInt( $('.header-body').css('border-bottom-width') ))
8567								});
8568							} else {
8569								$header.css({
8570									height: ''
8571								});
8572							}
8573						});
8574					});
8575				}
8576
8577                // Anchors Position
8578                if( $('[data-hash]').length ) {
8579					$('[data-hash]').on('mouseover', function(){
8580						const $this = $(this);
8581
8582						if( !$this.data('__dataHashBinded') ) {
8583                            let target = $this.attr('href');
8584                            let offset = ($this.is("[data-hash-offset]") ? $this.data('hash-offset') : 0);
8585                            const delay  = ($this.is("[data-hash-delay]") ? $this.data('hash-delay') : 0);
8586                            const force  = ($this.is("[data-hash-force]") ? true : false);
8587                            const windowWidth = $(window).width();
8588
8589                            // Hash Offset SM
8590                            if ($this.is("[data-hash-offset-sm]") && windowWidth > 576) {
8591								offset = $this.data('hash-offset-sm');
8592							}
8593
8594                            // Hash Offset MD
8595                            if ($this.is("[data-hash-offset-md]") && windowWidth > 768) {
8596								offset = $this.data('hash-offset-md');
8597							}
8598
8599                            // Hash Offset LG
8600                            if ($this.is("[data-hash-offset-lg]") && windowWidth > 992) {
8601								offset = $this.data('hash-offset-lg');
8602							}
8603
8604                            // Hash Offset XL
8605                            if ($this.is("[data-hash-offset-xl]") && windowWidth > 1200) {
8606								offset = $this.data('hash-offset-xl');
8607							}
8608
8609                            // Hash Offset XXL
8610                            if ($this.is("[data-hash-offset-xxl]") && windowWidth > 1400) {
8611								offset = $this.data('hash-offset-xxl');
8612							}
8613
8614                            if( !$(target).length ) {
8615								target = target.split('#');
8616								target = '#'+target[1];
8617							}
8618
8619                            if( target.includes('#') && $(target).length) {
8620								$this.on('click', e => {
8621									e.preventDefault();
8622
8623									if( !$(e.target).is('i') || force ) {
8624
8625										setTimeout(() => {
8626
8627											// Close Collapse if open
8628											$this.parents('.collapse.show').collapse('hide');
8629
8630											// Close Side Header
8631											$hamburguerSideHeader.addClass('side-header-hide');
8632											$html.addClass('side-header-hide');
8633											
8634											$window.trigger('resize');
8635
8636											self.scrollToTarget(target, offset);
8637
8638											// Data Hash Trigger Click
8639											if( $this.data('hash-trigger-click') ) {
8640
8641												const $clickTarget = $( $this.data('hash-trigger-click') ), clickDelay = $this.data('hash-trigger-click-delay') ? $this.data('hash-trigger-click-delay') : 0;
8642
8643												if( $clickTarget.length ) {
8644
8645													setTimeout(() => {
8646														// If is a "Tabs" plugin link
8647														if( $clickTarget.closest('.nav-tabs').length ) {
8648															new bootstrap.Tab( $clickTarget[0] ).show();
8649														} else {
8650															$clickTarget.trigger('click');
8651														}
8652														
8653													}, clickDelay);
8654												}
8655
8656											}
8657
8658										}, delay);
8659										
8660									}
8661
8662									return;
8663								});
8664							}
8665
8666                            $(this).data('__dataHashBinded', true);
8667                        }
8668					});
8669				}
8670
8671                // Floating
8672                if($('#header.header-floating-icons').length) {
8673
8674					$('#header.header-floating-icons [data-hash]').off().each(function() {
8675
8676						const target = $(this).attr('href'), offset = ($(this).is("[data-hash-offset]") ? $(this).data('hash-offset') : 0);
8677
8678						if($(target).length) {
8679							$(this).on('click', e => {
8680								e.preventDefault();
8681
8682									$('html, body').animate({
8683										scrollTop: $(target).offset().top - offset
8684									}, 600, 'easeOutQuad', () => {
8685
8686									});
8687
8688								return;
8689							});
8690						}
8691
8692					});
8693
8694				}
8695
8696                // Side Panel Toggle
8697                if( $('.side-panel-toggle').length ) {
8698					const init_html_class = $('html').attr('class');
8699
8700					$('.side-panel-toggle').on('click', function(e){
8701						const extra_class = $(this).data('extra-class'), delay       = ( extra_class ) ? 100 : 0, isActive    = $(this).data('is-active') ? $(this).data('is-active') : false;
8702
8703						e.preventDefault();
8704
8705						if( isActive ) {
8706							$('html').removeClass('side-panel-open');
8707							$(this).data('is-active', false);
8708							return false;
8709						}
8710
8711						if( extra_class ) {
8712							$('.side-panel-wrapper').css('transition','none');
8713							$('html')
8714								.removeClass()
8715								.addClass( init_html_class )
8716								.addClass( extra_class );
8717						}
8718						setTimeout(() => {
8719							$('.side-panel-wrapper').css('transition','');
8720							$('html').toggleClass('side-panel-open');
8721						}, delay);
8722
8723						$(this).data('is-active', true);						
8724					});
8725
8726					$(document).on('click', ({target}) => {
8727						if( !$(target).closest('.side-panel-wrapper').length && !$(target).hasClass('side-panel-toggle') ) {
8728							$('.hamburguer-btn.side-panel-toggle:not(.side-panel-close)').removeClass('active');
8729							$('html').removeClass('side-panel-open');
8730							$('.side-panel-toggle').data('is-active', false);
8731						}
8732					});
8733				}
8734
8735				// OffCanvas
8736				self.offCanvasMenu();
8737
8738                return this;
8739            },
8740
8741			scrollToTarget(target, offset) {
8742				const self = this, targetPosition = $(target).offset().top;
8743
8744				$('body').addClass('scrolling');
8745
8746				$('html, body').animate({
8747					scrollTop: $(target).offset().top - offset
8748				}, self.options.scrollDelay, self.options.scrollAnimation, () => {
8749					$('body').removeClass('scrolling');
8750
8751					// If by some reason the scroll finishes in a wrong position, this code will run the scrollToTarget() again until get the correct position
8752					// We need do it just one time to prevent infinite recursive loop at scrollToTarget() function
8753					if( $(target).offset().top !=  targetPosition) {
8754						$('html, body').animate({
8755							scrollTop: $(target).offset().top - offset
8756						}, 1, self.options.scrollAnimation, () => {});
8757					}
8758				});
8759
8760				return this;
8761
8762			},
8763
8764			offCanvasMenu() {
8765                const $headerNavMain = $('#header .header-nav-main');
8766				const $offCanvasNav = $('.offcanvas-nav');
8767
8768				if($offCanvasNav.length > 0) {
8769					const $navToClone = $headerNavMain.find('nav');
8770
8771					if($navToClone.length > 0) {
8772						$offCanvasNav.html($offCanvasNav.html() + $navToClone.html());
8773						$offCanvasNav.find('#mainNav').removeAttr('id').removeClass().addClass('nav flex-column w-100');
8774
8775						// Clean Classes
8776						$offCanvasNav.find('.dropdown').removeClass().addClass('dropdown');
8777
8778						$offCanvasNav.find('.dropdown-item:not(.dropdown-toggle)').removeClass().addClass('dropdown-item');
8779						$offCanvasNav.find('.dropdown-item.dropdown-toggle').removeClass().addClass('dropdown-item dropdown-toggle');
8780
8781						$offCanvasNav.find('.nav-link:not(.dropdown-toggle)').removeClass().addClass('nav-link');
8782						$offCanvasNav.find('.nav-link.dropdown-toggle').removeClass().addClass('nav-link dropdown-toggle');
8783
8784						$offCanvasNav.find('.dropdown-menu').removeClass().addClass('dropdown-menu');
8785
8786						// Dropdowns
8787						$offCanvasNav.find('.dropdown-toggle').each(function() {
8788							const $el = $(this);
8789							const $arrow = $el.find('i');
8790
8791							$arrow.on('click', function(e) {
8792								e.preventDefault();
8793								e.stopPropagation();
8794								$el.parents('li').toggleClass('open');
8795							})
8796
8797							if ($el.attr('href') == '#') {
8798								$el.on('click', function() {
8799									$arrow.trigger('click');
8800								});
8801							}
8802						});
8803					}
8804				}
8805
8806				return this;
8807			}
8808
8809		}
8810
8811	});
8812})).apply(this, [window.theme, jQuery]);
8813
8814
8815// Newsletter
8816(((theme = {}, $) => {
8817    let initialized = false;
8818
8819    $.extend(theme, {
8820
8821		Newsletter: {
8822
8823			defaults: {
8824				wrapper: $('#newsletterForm')
8825			},
8826
8827			initialize($wrapper, opts) {
8828				if (initialized) {
8829					return this;
8830				}
8831
8832				initialized = true;
8833				this.$wrapper = ($wrapper || this.defaults.wrapper);
8834
8835				this
8836					.setOptions(opts)
8837					.build();
8838
8839				return this;
8840			},
8841
8842			setOptions(opts) {
8843				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
8844
8845				return this;
8846			},
8847
8848			build() {
8849				if (!($.isFunction($.fn.validate))) {
8850					return this;
8851				}
8852
8853				const self = this, $email = self.$wrapper.find('#newsletterEmail'), $success = $('#newsletterSuccess'), $error = $('#newsletterError');
8854
8855				self.$wrapper.validate({
8856					submitHandler(form) {
8857
8858						$.ajax({
8859							type: 'POST',
8860							url: self.$wrapper.attr('action'),
8861							data: {
8862								'email': $email.val()
8863							},
8864							dataType: 'json',
8865							success({response, message}) {
8866								if (response == 'success') {
8867
8868									$success.removeClass('d-none');
8869									$error.addClass('d-none');
8870
8871									$email
8872										.val('')
8873										.blur()
8874										.closest('.control-group')
8875										.removeClass('success')
8876										.removeClass('error');
8877
8878								} else {
8879
8880									$error.html(message);
8881									$error.removeClass('d-none');
8882									$success.addClass('d-none');
8883
8884									$email
8885										.blur()
8886										.closest('.control-group')
8887										.removeClass('success')
8888										.addClass('error');
8889
8890								}
8891							}
8892						});
8893
8894					},
8895					rules: {
8896						newsletterEmail: {
8897							required: true,
8898							email: true
8899						}
8900					},
8901					errorPlacement(error, element) {
8902
8903					}
8904				});
8905
8906				return this;
8907			}
8908
8909		}
8910
8911	});
8912})).apply(this, [window.theme, jQuery]);
8913
8914// Search
8915(((theme = {}, $) => {
8916    let initialized = false;
8917
8918    $.extend(theme, {
8919
8920		Search: {
8921
8922			defaults: {
8923				wrapper: $('#searchForm')
8924			},
8925
8926			initialize($wrapper, opts) {
8927				if (initialized) {
8928					return this;
8929				}
8930
8931				initialized = true;
8932				this.$wrapper = ($wrapper || this.defaults.wrapper);
8933
8934				this
8935					.setOptions(opts)
8936					.build();
8937
8938				return this;
8939			},
8940
8941			setOptions(opts) {
8942				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
8943
8944				return this;
8945			},
8946
8947			build() {
8948				if (!($.isFunction($.fn.validate))) {
8949					return this;
8950				}
8951
8952				this.$wrapper.validate({
8953					errorPlacement(error, element) {}
8954				});
8955
8956				// Search Reveal
8957				theme.fn.execOnceTroughEvent( '#header', 'mouseover.search.reveal', () => {
8958					$('.header-nav-features-search-reveal').each(function() {
8959						const $el = $(this), $header = $('#header'), $html = $('html');
8960
8961						$el.find('.header-nav-features-search-show-icon').on('click', () => {
8962							$el.addClass('show');
8963							$header.addClass('search-show');
8964							$html.addClass('search-show');
8965							$('#headerSearch').focus();
8966						});
8967
8968						$el.find('.header-nav-features-search-hide-icon').on('click', () => {
8969							$el.removeClass('show');
8970							$header.removeClass('search-show');
8971							$html.removeClass('search-show');
8972						});
8973					});
8974				} );
8975
8976				return this;
8977			}
8978
8979		}
8980
8981	});
8982})).apply(this, [window.theme, jQuery]);
8983
8984// Sticky Header
8985(((theme = {}, $) => {
8986    let initialized = false;
8987
8988    $.extend(theme, {
8989
8990		StickyHeader: {
8991
8992			defaults: {
8993				wrapper: $('#header'),
8994				headerBody: $('#header .header-body'),
8995				stickyEnabled: true,
8996				stickyEnableOnBoxed: true,
8997				stickyEnableOnMobile: false,
8998				stickyStartAt: 0,
8999				stickyStartAtElement: false,
9000				stickySetTop: 0,
9001				stickyEffect: '',
9002				stickyHeaderContainerHeight: false,
9003				stickyChangeLogo: false,
9004				stickyChangeLogoWrapper: true,
9005				stickyForce: false,
9006				stickyScrollUp: false,
9007				stickyScrollValue: 0
9008			},
9009
9010			initialize($wrapper, opts) {
9011				if (initialized) {
9012					return this;
9013				}				
9014
9015				initialized = true;
9016				this.$wrapper = ($wrapper || this.defaults.wrapper);
9017
9018				if( this.$wrapper.hasClass('header') ) {
9019					this.$wrapper = $('.header[data-plugin-options]');
9020				}
9021
9022				this
9023					.setOptions(opts)
9024					.build()
9025					.events();
9026
9027				return this;
9028			},
9029
9030			setOptions(opts) {
9031				this.options = $.extend(true, {}, this.defaults, opts, theme.fn.getOptions(this.$wrapper.data('plugin-options')));
9032				return this;
9033			},
9034
9035			build() {
9036                if( $(window).width() < 992 && this.options.stickyEnableOnMobile == false ) {
9037					$('html').addClass('sticky-header-mobile-disabled');
9038					return this;
9039				}
9040
9041                if (!this.options.stickyEnableOnBoxed && $('html').hasClass('boxed') || $('html').hasClass('side-header-hamburguer-sidebar') && !this.options.stickyForce || !this.options.stickyEnabled) {
9042					return this;
9043				}
9044
9045                const self = this;
9046
9047                if( self.options.wrapper.hasClass('header') ) {
9048					self.options.wrapper = $('.header');
9049					self.options.headerBody = $('.header .header-body');
9050				}
9051
9052                const $html = $('html');
9053                const $window = $(window);
9054                const sideHeader = $html.hasClass('side-header');
9055                const initialHeaderTopHeight = self.options.wrapper.find('.header-top').outerHeight();
9056                const initialHeaderContainerHeight = self.options.wrapper.find('.header-container').outerHeight();
9057                let minHeight;
9058
9059                // HTML Classes
9060                $html.addClass('sticky-header-enabled');
9061
9062                if (parseInt(self.options.stickySetTop) < 0) {
9063					$html.addClass('sticky-header-negative');
9064				}
9065
9066                if (self.options.stickyScrollUp) {
9067					$html.addClass('sticky-header-scroll-direction');
9068				}
9069
9070                // Notice Top Bar First Load
9071                if( $('.notice-top-bar').get(0) ) {
9072					if (parseInt(self.options.stickySetTop) == 1 || self.options.stickyEffect == 'shrink') {
9073						$('.body').on('transitionend webkitTransitionEnd oTransitionEnd', () => {
9074						    setTimeout(() => {
9075								if( !$html.hasClass('sticky-header-active') ) {
9076								    self.options.headerBody.animate({
9077								    	top: $('.notice-top-bar').outerHeight()
9078								    }, 300, () => {
9079								    	if( $html.hasClass('sticky-header-active') ) {
9080								    		self.options.headerBody.css('top', 0);
9081								    	}
9082								    });
9083								}
9084						    }, 0);
9085						});
9086					}					
9087				}
9088
9089                // Set Start At
9090                if(self.options.stickyStartAtElement) {
9091
9092					const $stickyStartAtElement = $(self.options.stickyStartAtElement);
9093
9094					$(window).on('scroll resize sticky.header.resize', () => {
9095						self.options.stickyStartAt = $stickyStartAtElement.offset().top;
9096					});
9097
9098					$(window).trigger('sticky.header.resize');
9099				}
9100
9101                // Define Min Height value
9102                if( self.options.wrapper.find('.header-top').get(0) ) {
9103					minHeight = ( initialHeaderTopHeight + initialHeaderContainerHeight );
9104				} else {
9105					minHeight = initialHeaderContainerHeight;
9106				}
9107
9108                // Set Wrapper Min-Height
9109                if( !sideHeader ) {
9110					if( !$('.header-logo-sticky-change').get(0) ) {
9111						self.options.wrapper.css('height', self.options.headerBody.outerHeight());
9112					} else {
9113						$window.on('stickyChangeLogo.loaded', () => {
9114							self.options.wrapper.css('height', self.options.headerBody.outerHeight());
9115						});
9116					}
9117
9118					if( self.options.stickyEffect == 'shrink' ) {
9119						
9120						// Prevent wrong visualization of header when reload on middle of page
9121						$(document).ready(() => {
9122							if( $window.scrollTop() >= self.options.stickyStartAt ) {
9123								self.options.wrapper.find('.header-container').on('transitionend webkitTransitionEnd oTransitionEnd', () => {
9124									self.options.headerBody.css('position', 'fixed');
9125								});
9126							} else {
9127								if( !$html.hasClass('boxed') ) {
9128									self.options.headerBody.css('position', 'fixed');
9129								}
9130							}
9131						});
9132
9133						self.options.wrapper.find('.header-container').css('height', initialHeaderContainerHeight);
9134						self.options.wrapper.find('.header-top').css('height', initialHeaderTopHeight);
9135					}
9136				}
9137
9138                // Sticky Header Container Height
9139                if( self.options.stickyHeaderContainerHeight ) {
9140					self.options.wrapper.find('.header-container').css('height', self.options.wrapper.find('.header-container').outerHeight());
9141				}
9142
9143                // Boxed
9144                if($html.hasClass('boxed') && self.options.stickyEffect == 'shrink') {
9145					self.boxedLayout();
9146				}
9147
9148                // Check Sticky Header / Flags prevent multiple runs at same time
9149                let activate_flag   	 = true;
9150
9151                let deactivate_flag 	 = false;
9152                const initialStickyStartAt = self.options.stickyStartAt;
9153
9154                self.checkStickyHeader = () => {
9155
9156					// Notice Top Bar
9157					const $noticeTopBar = $('.notice-top-bar');
9158					if ( $noticeTopBar.get(0) ) {
9159						self.options.stickyStartAt = ( $noticeTopBar.data('sticky-start-at') ) ? $noticeTopBar.data('sticky-start-at') : $('.notice-top-bar').outerHeight();
9160					} else {
9161						if( $html.hasClass('boxed') ) {
9162							self.options.stickyStartAt = initialStickyStartAt + 25;
9163						} else {
9164							self.options.stickyStartAt = initialStickyStartAt;
9165						}
9166					}
9167
9168					if( $window.width() > 991 && $html.hasClass('side-header') ) {
9169						$html.removeClass('sticky-header-active');
9170						activate_flag = true;
9171						return;
9172					}
9173
9174					if ($window.scrollTop() >= parseInt(self.options.stickyStartAt)) {
9175						if( activate_flag ) {
9176							self.activateStickyHeader();
9177							activate_flag = false;
9178							deactivate_flag = true;
9179						}
9180					} else {
9181						if( deactivate_flag ) {
9182							self.deactivateStickyHeader();
9183							deactivate_flag = false;
9184							activate_flag = true;
9185						}
9186					}
9187
9188					// Scroll Up
9189					if (self.options.stickyScrollUp) {
9190						
9191					    // Get the new Value
9192					    self.options.stickyScrollNewValue = window.pageYOffset;
9193
9194					    //Subtract the two and conclude
9195					    if(self.options.stickyScrollValue - self.options.stickyScrollNewValue < 0){
9196					        $html.removeClass('sticky-header-scroll-up').addClass('sticky-header-scroll-down');
9197					    } else if(self.options.stickyScrollValue - self.options.stickyScrollNewValue > 0){
9198					        $html.removeClass('sticky-header-scroll-down').addClass('sticky-header-scroll-up');
9199					    }
9200
9201					    // Update the old value
9202					    self.options.stickyScrollValue = self.options.stickyScrollNewValue;
9203
9204					}
9205				};
9206
9207                // Activate Sticky Header
9208                self.activateStickyHeader = () => {
9209					if ($window.width() < 992) {
9210						if (self.options.stickyEnableOnMobile == false) {
9211							self.deactivateStickyHeader();
9212							self.options.headerBody.css({
9213								position: 'relative'
9214							});
9215							return false;
9216						}
9217					} else {
9218						if (sideHeader) {
9219							self.deactivateStickyHeader();
9220							return;
9221						}
9222					}
9223
9224					$html.addClass('sticky-header-active');
9225
9226					// Sticky Effect - Reveal
9227					if( self.options.stickyEffect == 'reveal' ) {
9228
9229						self.options.headerBody.css('top','-' + self.options.stickyStartAt + 'px');
9230
9231						self.options.headerBody.animate({
9232							top: self.options.stickySetTop
9233						}, 400, () => {});
9234
9235					}
9236
9237					// Sticky Effect - Shrink
9238					if( self.options.stickyEffect == 'shrink' ) {
9239
9240						// If Header Top
9241						if( self.options.wrapper.find('.header-top').get(0) ) {
9242							self.options.wrapper.find('.header-top').css({
9243								height: 0,
9244								'min-height': 0,
9245								overflow: 'hidden'
9246							});
9247						}
9248
9249						// Header Container
9250						if( self.options.stickyHeaderContainerHeight ) {
9251							self.options.wrapper.find('.header-container').css({
9252								height: self.options.stickyHeaderContainerHeight,
9253								'min-height': 0
9254							});
9255						} else {
9256							self.options.wrapper.find('.header-container').css({
9257								height: (initialHeaderContainerHeight / 3) * 2, // two third of container height
9258								'min-height': 0
9259							});
9260
9261							const y = initialHeaderContainerHeight - ((initialHeaderContainerHeight / 3) * 2);
9262							$('.main').css({
9263								transform: 'translate3d(0, -'+ y +'px, 0)',
9264								transition: 'ease transform 300ms'
9265							}).addClass('has-sticky-header-transform');
9266
9267							if($html.hasClass('boxed')) {
9268								self.options.headerBody.css('position','fixed');
9269							}
9270						}
9271
9272					}
9273
9274					self.options.headerBody.css('top', self.options.stickySetTop);
9275
9276					if (self.options.stickyChangeLogo) {
9277						self.changeLogo(true);
9278					}
9279
9280					// Set Elements Style
9281					if( $('[data-sticky-header-style]').length ) {
9282						$('[data-sticky-header-style]').each(function() {
9283							const $el = $(this), css = theme.fn.getOptions($el.data('sticky-header-style-active')), opts = theme.fn.getOptions($el.data('sticky-header-style'));
9284
9285							if( $window.width() > opts.minResolution ) {
9286								$el.css(css);
9287							}
9288						});
9289					}
9290
9291					$.event.trigger({
9292						type: 'stickyHeader.activate'
9293					});
9294				};
9295
9296                // Deactivate Sticky Header
9297                self.deactivateStickyHeader = () => {
9298					$html.removeClass('sticky-header-active');
9299
9300					if ( $(window).width() < 992 && self.options.stickyEnableOnMobile == false) {
9301						return false;
9302					}
9303
9304					// Sticky Effect - Shrink
9305					if( self.options.stickyEffect == 'shrink' ) {
9306
9307						// Boxed Layout
9308						if( $html.hasClass('boxed') ) {
9309
9310							// Set Header Body Position Absolute
9311							self.options.headerBody.css('position','absolute');
9312
9313							if( $window.scrollTop() > $('.body').offset().top ) {
9314								// Set Header Body Position Fixed
9315								self.options.headerBody.css('position','fixed');								
9316							}
9317
9318						} else {
9319							// Set Header Body Position Fixed
9320							self.options.headerBody.css('position','fixed');
9321						}
9322
9323						// If Header Top
9324						if( self.options.wrapper.find('.header-top').get(0) ) {
9325							self.options.wrapper.find('.header-top').css({
9326								height: initialHeaderTopHeight,
9327								overflow: 'visible'
9328							});
9329
9330							// Fix [data-icon] issue when first load is on middle of the page
9331							if( self.options.wrapper.find('.header-top [data-icon]').length ) {
9332								theme.fn.intObsInit( '.header-top [data-icon]:not(.svg-inline--fa)', 'themePluginIcon' );
9333							}
9334						}
9335
9336						// Header Container
9337						self.options.wrapper.find('.header-container').css({
9338							height: initialHeaderContainerHeight
9339						});
9340
9341					}
9342
9343					self.options.headerBody.css('top', 0);
9344
9345					if (self.options.stickyChangeLogo) {
9346						self.changeLogo(false);
9347					}
9348
9349					// Set Elements Style
9350					if( $('[data-sticky-header-style]').length ) {
9351						$('[data-sticky-header-style]').each(function() {
9352							const $el = $(this), css = theme.fn.getOptions($el.data('sticky-header-style-deactive')), opts = theme.fn.getOptions($el.data('sticky-header-style'));
9353
9354							if( $window.width() > opts.minResolution ) {
9355								$el.css(css);
9356							}
9357						});
9358					}
9359
9360					$.event.trigger({
9361						type: 'stickyHeader.deactivate'
9362					});
9363				};
9364
9365                // Always Sticky
9366                if (parseInt(self.options.stickyStartAt) <= 0) {
9367					self.activateStickyHeader();
9368				}
9369
9370                // Set Logo
9371                if (self.options.stickyChangeLogo) {
9372
9373					const $logoWrapper = self.options.wrapper.find('.header-logo'), $logo = $logoWrapper.find('img'), logoWidth = $logo.attr('width'), logoHeight = $logo.attr('height'), logoSmallTop = parseInt($logo.attr('data-sticky-top') ? $logo.attr('data-sticky-top') : 0), logoSmallWidth = parseInt($logo.attr('data-sticky-width') ? $logo.attr('data-sticky-width') : 'auto'), logoSmallHeight = parseInt($logo.attr('data-sticky-height') ? $logo.attr('data-sticky-height') : 'auto');
9374
9375					if (self.options.stickyChangeLogoWrapper) {
9376						$logoWrapper.css({
9377							'width': $logo.outerWidth(true),
9378							'height': $logo.outerHeight(true)
9379						});
9380					}
9381
9382					self.changeLogo = activate => {
9383						if(activate) {
9384							
9385							$logo.css({
9386								'top': logoSmallTop,
9387								'width': logoSmallWidth,
9388								'height': logoSmallHeight
9389							});
9390
9391						} else {
9392							
9393							$logo.css({
9394								'top': 0,
9395								'width': logoWidth,
9396								'height': logoHeight
9397							});
9398
9399						}
9400					}
9401
9402					$.event.trigger({
9403						type: 'stickyChangeLogo.loaded'
9404					});
9405
9406				}
9407
9408                // Side Header
9409                let headerBodyHeight, flag = false;
9410
9411                self.checkSideHeader = () => {
9412					if($window.width() < 992 && flag == false) {
9413						headerBodyHeight = self.options.headerBody.height();
9414						flag = true;
9415					}
9416
9417					if(self.options.stickyStartAt == 0 && sideHeader) {
9418						self.options.wrapper.css('min-height', 0);
9419					}
9420
9421					if(self.options.stickyStartAt > 0 && sideHeader && $window.width() < 992) {
9422						self.options.wrapper.css('min-height', headerBodyHeight);
9423					}
9424				}
9425
9426                return this;
9427            },
9428
9429			events() {
9430				const self = this;
9431
9432				if( $(window).width() < 992 && this.options.stickyEnableOnMobile == false ) {
9433					return this;
9434				}
9435
9436				if (!this.options.stickyEnableOnBoxed && $('body').hasClass('boxed') || $('html').hasClass('side-header-hamburguer-sidebar') && !this.options.stickyForce || !this.options.stickyEnabled) {
9437					return this;
9438				}
9439
9440				if (!self.options.alwaysStickyEnabled) {
9441					$(window).on('scroll resize', () => {
9442						if ( $(window).width() < 992 && self.options.stickyEnableOnMobile == false) {
9443							self.options.headerBody.css({
9444								position: ''
9445							});
9446
9447							if( self.options.stickyEffect == 'shrink' ) {
9448								self.options.wrapper.find('.header-top').css({
9449									height: ''
9450								});
9451							}
9452
9453							self.deactivateStickyHeader();
9454						} else {
9455							self.checkStickyHeader();
9456						}
9457					});
9458				} else {
9459					self.activateStickyHeader();
9460				}
9461
9462				$(window).on('load resize', () => {
9463					self.checkSideHeader();
9464				});
9465
9466				$(window).on('layout.boxed', () => {
9467					self.boxedLayout();
9468				});
9469
9470				return this;
9471			},
9472
9473			boxedLayout() {
9474				const self = this, $window = $(window);
9475
9476				if($('html').hasClass('boxed') && self.options.stickyEffect == 'shrink') {
9477					if( (parseInt(self.options.stickyStartAt) == 0) && $window.width() > 991) {
9478						self.options.stickyStartAt = 30;
9479					}
9480
9481					// Set Header Body Position Absolute
9482					self.options.headerBody.css({
9483						position: 'absolute',
9484						top: 0
9485					});
9486
9487					// Set position absolute because top margin from boxed layout
9488					$window.on('scroll', () => {
9489						if( $window.scrollTop() > $('.body').offset().top ) {
9490							self.options.headerBody.css({
9491								'position' : 'fixed',
9492								'top' : 0
9493							});								
9494						} else {
9495							self.options.headerBody.css({
9496								'position' : 'absolute',
9497								'top' : 0
9498							});
9499						}
9500					});
9501				}
9502
9503				return this;
9504			}
9505
9506		}
9507
9508	});
9509})).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.