PageSourceSearch

https://mezban.net/wp-content/themes/porto/js/theme.js?ver=6.9.3

js mezban.net collected 2026-09-29 12:28:09 UTC 182,707 bytes, 5,663 lines download raw bytes

1/**
2 * Porto theme's main JavaScript file
3 */
4
5/* Alternatives for old browsers */
6if ( !String.prototype.endsWith ) {
7	String.prototype.endsWith = function( search, this_len ) {
8		if ( this_len === undefined || this_len > this.length ) {
9			this_len = this.length;
10		}
11		return this.substring( this_len - search.length, this_len ) === search;
12	};
13}
14if ( window.NodeList && !NodeList.prototype.forEach ) {
15	NodeList.prototype.forEach = Array.prototype.forEach;
16}
17if ( !String.prototype.trim ) {
18	String.prototype.trim = function() {
19		return this.replace( /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '' );
20	};
21}
22
23/* Smart Resize  */
24( function( $, sr ) {
25	'use strict';
26
27	// debouncing function from John Hann
28	// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
29	var debounce = function( func, threshold, execAsap ) {
30		var timeout;
31
32		return function debounced() {
33			var obj = this, args = arguments;
34			function delayed() {
35				if ( !execAsap )
36					func.apply( obj, args );
37				timeout = null;
38			}
39
40			if ( timeout && timeout.val )
41				theme.deleteTimeout( timeout );
42			else if ( execAsap )
43				func.apply( obj, args );
44
45			timeout = theme.requestTimeout( delayed, threshold || 100 );
46		};
47	};
48	// smartresize 
49	jQuery.fn[sr] = function( fn ) { return fn ? this.on( 'resize', debounce( fn ) ) : this.trigger( sr ); };
50
51} )( jQuery, 'smartresize' );
52
53/* easing */
54jQuery.extend( jQuery.easing, {
55	def: 'easeOutQuad',
56	swing: function( x, t, b, c, d ) {
57		return jQuery.easing[jQuery.easing.def]( x, t, b, c, d );
58	},
59	easeOutQuad: function( x, t, b, c, d ) {
60		return -c * ( t /= d ) * ( t - 2 ) + b;
61	},
62	easeInOutQuart: function( x, t, b, c, d ) {
63		if ( ( t /= d / 2 ) < 1 ) return c / 2 * t * t * t * t + b;
64		return -c / 2 * ( ( t -= 2 ) * t * t * t - 2 ) + b;
65	},
66	easeOutQuint: function( x, t, b, c, d ) {
67		return c * ( ( t = t / d - 1 ) * t * t * t * t + 1 ) + b;
68	}
69} );
70
71( function( $ ) {
72
73	/**
74	 * Copyright 2012, Digital Fusion
75	 * Licensed under the MIT license.
76	 * http://teamdf.com/jquery-plugins/license/
77	 *
78	 * @author Sam Sehnert
79	 * @desc A small plugin that checks whether elements are within
80	 *       the user visible viewport of a web browser.
81	 *       only accounts for vertical position, not horizontal.
82	 */
83	$.fn.visible = function( partial, hidden, direction, container ) {
84
85		if ( this.length < 1 )
86			return;
87
88		var $t = this.length > 1 ? this.eq( 0 ) : this,
89			isContained = typeof container !== 'undefined' && container !== null,
90			$w = isContained ? $( container ) : $( window ),
91			wPosition = isContained ? $w.position() : 0,
92			t = $t.get( 0 ),
93			vpWidth = $w.outerWidth(),
94			vpHeight = $w.outerHeight(),
95			direction = ( direction ) ? direction : 'both',
96			clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;
97
98		if ( typeof t.getBoundingClientRect === 'function' ) {
99
100			// Use this native browser method, if available.
101			var rec = t.getBoundingClientRect(),
102				tViz = isContained ?
103					rec.top - wPosition.top >= 0 && rec.top < vpHeight + wPosition.top :
104					rec.top >= 0 && rec.top < vpHeight,
105				bViz = isContained ?
106					rec.bottom - wPosition.top > 0 && rec.bottom <= vpHeight + wPosition.top :
107					rec.bottom > 0 && rec.bottom <= vpHeight,
108				lViz = isContained ?
109					rec.left - wPosition.left >= 0 && rec.left < vpWidth + wPosition.left :
110					rec.left >= 0 && rec.left < vpWidth,
111				rViz = isContained ?
112					rec.right - wPosition.left > 0 && rec.right < vpWidth + wPosition.left :
113					rec.right > 0 && rec.right <= vpWidth,
114				vVisible = partial ? tViz || bViz : tViz && bViz,
115				hVisible = partial ? lViz || rViz : lViz && rViz;
116
117			if ( direction === 'both' )
118				return clientSize && vVisible && hVisible;
119			else if ( direction === 'vertical' )
120				return clientSize && vVisible;
121			else if ( direction === 'horizontal' )
122				return clientSize && hVisible;
123		} else {
124
125			var viewTop = isContained ? 0 : wPosition,
126				viewBottom = viewTop + vpHeight,
127				viewLeft = $w.scrollLeft(),
128				viewRight = viewLeft + vpWidth,
129				position = $t.position(),
130				_top = position.top,
131				_bottom = _top + $t.height(),
132				_left = position.left,
133				_right = _left + $t.width(),
134				compareTop = partial === true ? _bottom : _top,
135				compareBottom = partial === true ? _top : _bottom,
136				compareLeft = partial === true ? _right : _left,
137				compareRight = partial === true ? _left : _right;
138
139			if ( direction === 'both' )
140				return !!clientSize && ( ( compareBottom <= viewBottom ) && ( compareTop >= viewTop ) ) && ( ( compareRight <= viewRight ) && ( compareLeft >= viewLeft ) );
141			else if ( direction === 'vertical' )
142				return !!clientSize && ( ( compareBottom <= viewBottom ) && ( compareTop >= viewTop ) );
143			else if ( direction === 'horizontal' )
144				return !!clientSize && ( ( compareRight <= viewRight ) && ( compareLeft >= viewLeft ) );
145		}
146	};
147
148} )( jQuery );
149
150/*
151 Name: Porto Theme Javascript
152 Writtern By: P-THEMES
153 Javascript Version: 1.2
154 */
155
156// Theme
157window.theme = {};
158
159// Configuration
160( function( theme, $ ) {
161	'use strict';
162
163	theme = theme || {};
164
165	$.extend( theme, {
166
167		rtl: js_porto_vars.rtl == '1' ? true : false,
168		rtl_browser: $( 'html' ).hasClass( 'browser-rtl' ),
169
170		ajax_url: js_porto_vars.ajax_url,
171		request_error: js_porto_vars.request_error,
172
173		change_logo: js_porto_vars.change_logo == '1' ? true : false,
174
175		show_sticky_header: js_porto_vars.show_sticky_header == '1' ? true : false,
176		show_sticky_header_tablet: js_porto_vars.show_sticky_header_tablet == '1' ? true : false,
177		show_sticky_header_mobile: js_porto_vars.show_sticky_header_mobile == '1' ? true : false,
178
179		category_ajax: js_porto_vars.category_ajax == '1' ? true : false,
180		prdctfltr_ajax: js_porto_vars.prdctfltr_ajax == '1' ? true : false,
181
182		container_width: parseInt( js_porto_vars.container_width ),
183		grid_gutter_width: parseInt( js_porto_vars.grid_gutter_width ),
184		screen_lg: parseInt( js_porto_vars.screen_lg ),
185		slider_loop: js_porto_vars.slider_loop == '1' ? true : false,
186		slider_autoplay: js_porto_vars.slider_autoplay == '1' ? true : false,
187		slider_autoheight: js_porto_vars.slider_autoheight == '1' ? true : false,
188		slider_speed: js_porto_vars.slider_speed ? js_porto_vars.slider_speed : 5000,
189		slider_nav: js_porto_vars.slider_nav == '1' ? true : false,
190		slider_nav_hover: js_porto_vars.slider_nav_hover == '1' ? true : false,
191		slider_margin: js_porto_vars.slider_margin == '1' ? 40 : 0,
192		slider_dots: js_porto_vars.slider_dots == '1' ? true : false,
193		slider_animatein: js_porto_vars.slider_animatein ? js_porto_vars.slider_animatein : '',
194		slider_animateout: js_porto_vars.slider_animateout ? js_porto_vars.slider_animateout : '',
195		product_thumbs_count: js_porto_vars.product_thumbs_count ? js_porto_vars.product_thumbs_count : 4,
196		product_zoom: js_porto_vars.product_zoom == '1' ? true : false,
197		product_zoom_mobile: js_porto_vars.product_zoom_mobile == '1' ? true : false,
198		product_image_popup: js_porto_vars.product_image_popup == '1' ? 'fadeOut' : false,
199
200		animation_support: !$( 'html' ).hasClass( 'no-csstransitions' ) && window.innerWidth > 767,
201
202		owlConfig: {
203			rtl: js_porto_vars.rtl == '1' ? true : false,
204			loop: js_porto_vars.slider_loop == '1' ? true : false,
205			autoplay: js_porto_vars.slider_autoplay == '1' ? true : false,
206			autoHeight: js_porto_vars.slider_autoheight == '1' ? true : false,
207			autoplayTimeout: js_porto_vars.slider_speed ? js_porto_vars.slider_speed : 7000,
208			autoplayHoverPause: true,
209			lazyLoad: true,
210			nav: js_porto_vars.slider_nav == '1' ? true : false,
211			navText: ["", ""],
212			dots: js_porto_vars.slider_dots == '1' ? true : false,
213			stagePadding: ( js_porto_vars.slider_nav_hover != '1' && js_porto_vars.slider_margin == '1' ) ? 40 : 0,
214			animateOut: js_porto_vars.slider_animateout ? js_porto_vars.slider_animateout : '',
215			animateIn: js_porto_vars.slider_animatein ? js_porto_vars.slider_animatein : ''
216		},
217
218		sticky_nav_height: 0,
219
220		is_device_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( navigator.userAgent || navigator.vendor || window.opera ) || /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 )|
220sy(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( ( navigator.userAgent || navigator.vendor || window.opera ).substr( 0, 4 ) ),
221
222		getScrollbarWidth: function() {
223
224			if ( this.scrollbarSize === undefined ) {
225				this.scrollbarSize = window.innerWidth - document.documentElement.clientWidth;
226			}
227			return this.scrollbarSize;
228		},
229
230		isTablet: function() {
231			if ( window.innerWidth < 992 )
232				return true;
233			return false;
234		},
235
236		isMobile: function() {
237			if ( window.innerWidth <= 480 )
238				return true;
239			return false;
240		},
241
242		isIOS: function () {
243			return [
244				'iPad Simulator',
245				'iPhone Simulator',
246				'iPod Simulator',
247				'iPad',
248				'iPhone',
249				'iPod'
250			].includes(navigator.platform)
251				// iPad on iOS 13 detection
252				|| (navigator.userAgent.includes("Mac") && "ontouchend" in document);
253		},
254
255		refreshVCContent: function( $elements ) {
256			if ( $elements || $( document.body ).hasClass( 'elementor-page' ) ) {
257				$( window ).trigger( 'resize' );
258			}
259			theme.refreshStickySidebar( true );
260
261			if ( typeof window.vc_js == 'function' )
262				window.vc_js();
263
264			$( document.body ).trigger( 'porto_refresh_vc_content', [$elements] );
265		},
266
267		adminBarHeight: function() {
268			if ( theme.adminBarHeightNum || 0 === theme.adminBarHeightNum ) {
269				return theme.adminBarHeightNum;
270			}
271			var obj = document.getElementById( 'wpadminbar' ),
272				fixed_top = $( '.porto-scroll-progress.fixed-top' );
273			if ( fixed_top.length ) {
274				theme.adminBarHeightNum = fixed_top.height();
275			} else {
276				theme.adminBarHeightNum = 0;
277			}
278			if ( obj && obj.offsetHeight && window.innerWidth > 600 ) {
279				theme.adminBarHeightNum += obj.offsetHeight;
280			}
281
282			return theme.adminBarHeightNum;
283		},
284
285		refreshStickySidebar: function( timeout, $sticky_sidebar ) {
286			if ( typeof $sticky_sidebar == 'undefined' ) {
287				$sticky_sidebar = $( '.sidebar [data-plugin-sticky]' );
288			}
289			if ( $sticky_sidebar.get( 0 ) ) {
290				if ( timeout ) {
291					theme.requestTimeout( function() {
292						$sticky_sidebar.trigger( 'recalc.pin' );
293					}, 400 );
294				} else {
295					$sticky_sidebar.trigger( 'recalc.pin' );
296				}
297			}
298		},
299
300		scrolltoContainer: function( $container, timeout ) {
301			if ( $container.get( 0 ) ) {
302				if ( window.innerWidth < 992 ) {
303					$( '.sidebar-overlay' ).trigger( 'click' );
304				}
305				if ( !timeout ) {
306					timeout = 600;
307				}
308				$( 'html, body' ).stop().animate( {
309					scrollTop: $container.offset().top - theme.StickyHeader.sticky_height - theme.adminBarHeight() - theme.sticky_nav_height - 18
310				}, timeout, 'easeOutQuad' );
311			}
312		},
313
314		requestFrame: function( fn ) {
315			var handler = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
316			if ( !handler ) {
317				return setTimeout( fn, 1000 / 60 );
318			}
319			var rt = new Object()
320			rt.val = handler( fn );
321			return rt;
322		},
323
324		requestTimeout: function( fn, delay ) {
325			var handler = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
326			if ( !handler ) {
327				return setTimeout( fn, delay );
328			}
329			var start, rt = new Object();
330
331			function loop( timestamp ) {
332				if ( !start ) {
333					start = timestamp;
334				}
335				var progress = timestamp - start;
336				progress >= delay ? fn.call() : rt.val = handler( loop );
337			};
338
339			rt.val = handler( loop );
340			return rt;
341		},
342
343		deleteTimeout: function( timeoutID ) {
344			if ( !timeoutID ) {
345				return;
346			}
347			var handler = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame;
348			if ( !handler ) {
349				return clearTimeout( timeoutID );
350			}
351			if ( timeoutID.val ) {
352				return handler( timeoutID.val );
353			}
354		},
355
356		execPluginFunction: function( functionName, context ) {
357			var args = Array.prototype.slice.call( arguments, 2 );
358			var namespaces = functionName.split( "." );
359			var func = namespaces.pop();
360
361			for ( var i = 0; i < namespaces.length; i++ ) {
362				context = context[namespaces[i]];
363			}
364
365			return context[func].apply( context, args );
366		},
367
368		getOptions: function( opts ) {
369			if ( typeof ( opts ) == 'object' ) {
370				return opts;
371			} else if ( typeof ( opts ) == 'string' ) {
372				try {
373					return JSON.parse( opts.replace( /'/g, '"' ).replace( ';', '' ) );
374				} catch ( e ) {
375					return {};
376				}
377			} else {
378				return {};
379			}
380		},
381		mergeOptions: function( obj1, obj2 ) {
382			var obj3 = {};
383			for ( var attrname in obj1 ) { obj3[attrname] = obj1[attrname]; }
384			for ( var attrname in obj2 ) { obj3[attrname] = obj2[attrname]; }
385			return obj3;
386		},
387
388		intObs: function( selector, functionName, accY ) {
389			var $el;
390			if ( typeof selector == 'string' ) {
391				$el = document.querySelectorAll( selector );
392			} else {
393				$el = selector;
394			}
395			var intersectionObserverOptions = {
396				rootMargin: '200px'
397			}
398			if ( typeof accY != 'undefined' ) {
399				intersectionObserverOptions.rootMargin = '0px 0px ' + Number( accY ) + 'px 0px';
400			}
401
402			var observer = new IntersectionObserver( function( entries ) {
403				for ( var i = 0; i < entries.length; i++ ) {
404					var entry = entries[i];
405					if ( entry.intersectionRatio > 0 ) {
406						var $this = $( entry.target ),
407							opts;
408
409						if ( typeof functionName == 'string' ) {
410							var pluginOptions = theme.getOptions( $this.data( 'plugin-options' ) );
411							if ( pluginOptions )
412								opts = pluginOptions;
413
414							theme.execPluginFunction( functionName, $this, opts );
415						} else {
416							var callback = functionName;
417							callback.call( $this );
418						}
419
420						// Unobserve
421						observer.unobserve( entry.target );
422					}
423				}
424			}, intersectionObserverOptions );
425
426			Array.prototype.forEach.call( $el, function( obj ) {
427				observer.observe( obj );
428			} );
429		},
430
431		dynIntObsInit: function( selector, functionName, pluginDefaults ) {
432			var $el;
433			if ( typeof selector == 'string' ) {
434				$el = document.querySelectorAll( selector );
435			} else {
436				$el = selector;
437			}
438
439			Array.prototype.forEach.call( $el, function( obj ) {
440				var $this = $( obj ),
441					opts;
442				if ( $this.data( 'observer-init' ) ) {
443					return;
444				}
445
446				var pluginOptions = theme.getOptions( $this.data( 'plugin-options' ) );
447				if ( pluginOptions )
448					opts = pluginOptions;
449
450				var mergedPluginDefaults = theme.mergeOptions( pluginDefaults, opts )
451
452				var intersectionObserverOptions = {
453					rootMargin: '0px 0px 200px 0px',
454					thresholds: 0
455				}
456				if ( mergedPluginDefaults.accY ) {
457					intersectionObserverOptions.rootMargin = '0px 0px ' + Number( mergedPluginDefaults.accY ) + 'px 0px';
458				}
459
460				var observer = new IntersectionObserver( function( entries ) {
461					for ( var i = 0; i < entries.length; i++ ) {
462						var entry = entries[i];
463						if ( entry.intersectionRatio > 0 ) {
464							theme.execPluginFunction( functionName, $this, mergedPluginDefaults );
465
466							// Unobserve
467							observer.unobserve( entry.target );
468						}
469					}
470				}, intersectionObserverOptions );
471
472				observer.observe( obj );
473				$this.data( 'observer-init', true );
474			} );
475		}
476
477	} );
478
479	if ( theme.isIOS() ) {
480		document.body.classList.add( 'ios' );
481	}
482
483} ).apply( this, [window.theme, jQuery] );
484
485/**
486 * Copyright 2016 Google Inc. All Rights Reserved.
487 *
488 * Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE.
489 *
490 *  https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
491 *
492 */
493!function() { "use strict"; if ( "object" == typeof window ) if ( "IntersectionObserver" in window && "IntersectionObserverEntry" in window && "intersectionRatio" in window.IntersectionObserverEntry.prototype ) "isIntersecting" in window.IntersectionObserverEntry.prototype || Object.defineProperty( window.IntersectionObserverEntry.prototype, "isIntersecting", { get: function() { return this.intersectionRatio > 0 } } ); else { var t = function( t ) { for ( var e = window.document, o = i( e ); o; )o = i( e = o.ownerDocument ); return e }(), e = [], o = null, n = null; s.prototype.THROTTLE_TIMEOUT = 100, s.prototype.POLL_INTERVAL = null, s.prototype.USE_MUTATION_OBSERVER = !0, s._setupCrossOriginUpdater = function() { return o || ( o = function( t, o ) { n = t && o ? l( t, o ) : { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 }, e.forEach( function( t ) { t._checkForIntersections() } ) } ), o }, s._resetCrossOriginUpdater = function() { o = null, n = null }, s.prototype.observe = function( t ) { if ( !this._observationTargets.some( function( e ) { return e.element == t } ) ) { if ( !t || 1 != t.nodeType ) throw new Error( "target must be an Element" ); this._registerInstance(), this._observationTargets.push( { element: t, entry: null } ), this._monitorIntersections( t.ownerDocument ), this._checkForIntersections() } }, s.prototype.unobserve = function( t ) { this._observationTargets = this._observationTargets.filter( function( e ) { return e.element != t } ), this._unmonitorIntersections( t.ownerDocument ), 0 == this._observationTargets.length && this._unregisterInstance() }, s.prototype.disconnect = function() { this._observationTargets = [], this._unmonitorAllIntersections(), this._unregisterInstance() }, s.prototype.takeRecords = function() { var t = this._queuedEntries.slice(); return this._queuedEntries = [], t }, s.prototype._initThresholds = function( t ) { var e = t || [0]; return Array.isArray( e ) || ( e = [e] ), e.sort().filter( function( t, e, o ) { if ( "number" != typeof t || isNaN( t ) || t < 0 || t > 1 ) throw new Error( "threshold must be a number between 0 and 1 inclusively" ); return t !== o[e - 1] } ) }, s.prototype._parseRootMargin = function( t ) { var e = ( t || "0px" ).split( /\s+/ ).map( function( t ) { var e = /^(-?\d*\.?\d+)(px|%)$/.exec( t ); if ( !e ) throw new Error( "rootMargin must be specified in pixels or percent" ); return { value: parseFloat( e[1] ), unit: e[2] } } ); return e[1] = e[1] || e[0], e[2] = e[2] || e[0], e[3] = e[3] || e[1], e }, s.prototype._monitorIntersections = function( e ) { var o = e.defaultView; if ( o && -1 == this._monitoringDocuments.indexOf( e ) ) { var n = this._checkForIntersections, r = null, s = null; this.POLL_INTERVAL ? r = o.setInterval( n, this.POLL_INTERVAL ) : ( h( o, "resize", n, !0 ), h( e, "scroll", n, !0 ), this.USE_MUTATION_OBSERVER && "MutationObserver" in o && ( s = new o.MutationObserver( n ) ).observe( e, { attributes: !0, childList: !0, characterData: !0, subtree: !0 } ) ), this._monitoringDocuments.push( e ), this._monitoringUnsubscribes.push( function() { var t = e.defaultView; t && ( r && t.clearInterval( r ), c( t, "resize", n, !0 ) ), c( e, "scroll", n, !0 ), s && s.disconnect() } ); var u = this.root && ( this.root.ownerDocument || this.root ) || t; if ( e != u ) { var a = i( e ); a && this._monitorIntersections( a.ownerDocument ) } } }, s.prototype._unmonitorIntersections = function( e ) { var o = this._monitoringDocuments.indexOf( e ); if ( -1 != o ) { var n = this.root && ( this.root.ownerDocument || this.root ) || t; if ( !this._observationTargets.some( function( t ) { var o = t.element.ownerDocument; if ( o == e ) return !0; for ( ; o && o != n; ) { var r = i( o ); if ( ( o = r && r.ownerDocument ) == e ) return !0 } return !1 } ) ) { var r = this._monitoringUnsubscribes[o]; if ( this._monitoringDocuments.splice( o, 1 ), this._monitoringUnsubscribes.splice( o, 1 ), r(), e != n ) { var s = i( e ); s && this._unmonitorIntersections( s.ownerDocument ) } } } }, s.prototype._unmonitorAllIntersections = function() { var t = this._monitoringUnsubscribes.slice( 0 ); this._monitoringDocuments.length = 0, this._monitoringUnsubscribes.length = 0; for ( var e = 0; e < t.length; e++ )t[e]() }, s.prototype._checkForIntersections = function() { if ( this.root || !o || n ) { var t = this._rootIsInDom(), e = t ? this._getRootRect() : { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 };
vendor: 5,402 bytes, line 493
493 this._observationTargets.forEach( function( n ) { var i = n.element, s = u( i ), h = this._rootContainsTarget( i ), c = n.entry, a = t && h && this._computeTargetAndRootIntersection( i, s, e ), l = null; this._rootContainsTarget( i ) ? o && !this.root || ( l = e ) : l = { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 }; var f = n.entry = new r( { time: window.performance && performance.now && performance.now(), target: i, boundingClientRect: s, rootBounds: l, intersectionRect: a } ); c ? t && h ? this._hasCrossedThreshold( c, f ) && this._queuedEntries.push( f ) : c && c.isIntersecting && this._queuedEntries.push( f ) : this._queuedEntries.push( f ) }, this ), this._queuedEntries.length && this._callback( this.takeRecords(), this ) } }, s.prototype._computeTargetAndRootIntersection = function( e, i, r ) { if ( "none" != window.getComputedStyle( e ).display ) { for ( var s, h, c, a, f, d, g, m, v = i, _ = p( e ), b = !1; !b && _; ) { var w = null, y = 1 == _.nodeType ? window.getComputedStyle( _ ) : {}; if ( "none" == y.display ) return null; if ( _ == this.root || 9 == _.nodeType ) if ( b = !0, _ == this.root || _ == t ) o && !this.root ? !n || 0 == n.width && 0 == n.height ? ( _ = null, w = null, v = null ) : w = n : w = r; else { var I = p( _ ), E = I && u( I ), T = I && this._computeTargetAndRootIntersection( I, E, r ); E && T ? ( _ = I, w = l( E, T ) ) : ( _ = null, v = null ) } else { var R = _.ownerDocument; _ != R.body && _ != R.documentElement && "visible" != y.overflow && ( w = u( _ ) ) } if ( w && ( s = w, h = v, c = void 0, a = void 0, f = void 0, d = void 0, g = void 0, m = void 0, c = Math.max( s.top, h.top ), a = Math.min( s.bottom, h.bottom ), f = Math.max( s.left, h.left ), d = Math.min( s.right, h.right ), m = a - c, v = ( g = d - f ) >= 0 && m >= 0 && { top: c, bottom: a, left: f, right: d, width: g, height: m } || null ), !v ) break; _ = _ && p( _ ) } return v } }, s.prototype._getRootRect = function() { var e; if ( this.root && !d( this.root ) ) e = u( this.root ); else { var o = d( this.root ) ? this.root : t, n = o.documentElement, i = o.body; e = { top: 0, left: 0, right: n.clientWidth || i.clientWidth, width: n.clientWidth || i.clientWidth, bottom: n.clientHeight || i.clientHeight, height: n.clientHeight || i.clientHeight } } return this._expandRectByRootMargin( e ) }, s.prototype._expandRectByRootMargin = function( t ) { var e = this._rootMarginValues.map( function( e, o ) { return "px" == e.unit ? e.value : e.value * ( o % 2 ? t.width : t.height ) / 100 } ), o = { top: t.top - e[0], right: t.right + e[1], bottom: t.bottom + e[2], left: t.left - e[3] }; return o.width = o.right - o.left, o.height = o.bottom - o.top, o }, s.prototype._hasCrossedThreshold = function( t, e ) { var o = t && t.isIntersecting ? t.intersectionRatio || 0 : -1, n = e.isIntersecting ? e.intersectionRatio || 0 : -1; if ( o !== n ) for ( var i = 0; i < this.thresholds.length; i++ ) { var r = this.thresholds[i]; if ( r == o || r == n || r < o != r < n ) return !0 } }, s.prototype._rootIsInDom = function() { return !this.root || f( t, this.root ) }, s.prototype._rootContainsTarget = function( e ) { var o = this.root && ( this.root.ownerDocument || this.root ) || t; return f( o, e ) && ( !this.root || o == e.ownerDocument ) }, s.prototype._registerInstance = function() { e.indexOf( this ) < 0 && e.push( this ) }, s.prototype._unregisterInstance = function() { var t = e.indexOf( this ); -1 != t && e.splice( t, 1 ) }, window.IntersectionObserver = s, window.IntersectionObserverEntry = r } function i( t ) { try { return t.defaultView && t.defaultView.frameElement || null } catch ( t ) { return null } } function r( t ) { this.time = t.time, this.target = t.target, this.rootBounds = a( t.rootBounds ), this.boundingClientRect = a( t.boundingClientRect ), this.intersectionRect = a( t.intersectionRect || { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 } ), this.isIntersecting = !!t.intersectionRect; var e = this.boundingClientRect, o = e.width * e.height, n = this.intersectionRect, i = n.width * n.height; this.intersectionRatio = o ? Number( ( i / o ).toFixed( 4 ) ) : this.isIntersecting ? 1 : 0 } function s( t, e ) { var o, n, i, r = e || {}; if ( "function" != typeof t ) throw new Error( "callback must be a function" ); if ( r.root && 1 != r.root.nodeType && 9 != r.root.nodeType ) throw new Error( "root must be a Document or Element" ); this._checkForIntersections = ( o = this._checkForIntersections.bind( this ), n = this.THROTTLE_TIMEOUT, i = null, function() { i || ( i = setTimeout( function() { o(), i = null }, n ) ) } ), this._callback = t, this._observationTargets = [], this._queuedEntries = [], this._rootMarginValues = this._parseRootMargin( r.rootMargin ), this.thresholds = this._initThresholds( r.threshold ), this.root = r.root || null, this.rootMargin = this._rootMarginValues.map( function( t ) { return t.value + t.unit } ).join( " " ), this._monitoringDocuments = [], this._monitoringUnsubscribes = [] } function h( t, e, o, n ) { "function" == typeof t.addEventListener ? t.addEventListener( e, o, n || !1 ) : "function" == typeof t.attachEvent && t.attachEvent( "on" + e, o ) } function c( t, e, o, n ) { "function" == typeof t.removeEventListener ? t.removeEventListener( e, o, n || !1 ) : "function" == typeof t.detatchEvent && t.detatchEvent( "on" + e, o ) } function u( t ) { var e;
493 try { e = t.getBoundingClientRect() } catch ( t ) { } return e ? ( e.width && e.height || ( e = { top: e.top, right: e.right, bottom: e.bottom, left: e.left, width: e.right - e.left, height: e.bottom - e.top } ), e ) : { top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0 } } function a( t ) { return !t || "x" in t ? t : { top: t.top, y: t.top, bottom: t.bottom, left: t.left, x: t.left, right: t.right, width: t.width, height: t.height } } function l( t, e ) { var o = e.top - t.top, n = e.left - t.left; return { top: o, left: n, height: e.height, width: e.width, bottom: o + e.height, right: n + e.width } } function f( t, e ) { for ( var o = e; o; ) { if ( o == t ) return !0; o = p( o ) } return !1 } function p( e ) { var o = e.parentNode; return 9 == e.nodeType && e != t ? i( e ) : ( o && o.assignedSlot && ( o = o.assignedSlot.parentNode ), o && 11 == o.nodeType && o.host ? o.host : o ) } function d( t ) { return t && 9 === t.nodeType } }();
494
495/* browser select */
496( function( $ ) {
497	'use strict';
498	$.extend( {
499
500		browserSelector: function() {
501
502			// Touch
503			var hasTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;
504
505			var u = navigator.userAgent,
506				ua = u.toLowerCase(),
507				is = function( t ) {
508					return ua.indexOf( t ) > -1;
509				},
510				g = 'gecko',
511				w = 'webkit',
512				s = 'safari',
513				o = 'opera',
514				h = document.documentElement,
515				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'];
516
517			var c = b.join( ' ' );
518
519			if ( theme.is_device_mobile ) {
520				c += ' mobile';
521			}
522
523			if ( hasTouch ) {
524				c += ' touch';
525			}
526
527			h.className += ' ' + c;
528
529			// IE11 Detect
530			var isIE11 = !( window.ActiveXObject ) && "ActiveXObject" in window;
531
532			if ( isIE11 ) {
533				$( 'html' ).removeClass( 'gecko' ).addClass( 'ie ie11' );
534				return;
535			}
536		}
537
538	} );
539
540	$.browserSelector();
541
542} )( jQuery );
543
544// Accordion
545( function( theme, $ ) {
546	'use strict';
547
548	theme = theme || {};
549	var instanceName = '__accordion';
550	var Accordion = function( $el, opts ) {
551		return this.initialize( $el, opts );
552	};
553	Accordion.defaults = {
554	};
555	Accordion.prototype = {
556		initialize: function( $el, opts ) {
557			if ( $el.data( instanceName ) ) {
558				return this;
559			}
560
561			this.$el = $el;
562
563			this
564				.setData()
565				.setOptions( opts )
566				.build();
567
568			return this;
569		},
570
571		setData: function() {
572			this.$el.data( instanceName, this );
573			return this;
574		},
575
576		setOptions: function( opts ) {
577			this.options = $.extend( true, {}, Accordion.defaults, opts, {
578				wrapper: this.$el
579			} );
580
581			return this;
582		},
583
584		build: function() {
585			if ( !$.fn.collapse ) {
586				return this;
587			}
588
589			var $el = this.options.wrapper,
590				$collapse = $el.find( '.collapse' ),
591				collapsible = $el.data( 'collapsible' ),
592				active_num = $el.data( 'active-tab' );
593
594			if ( $collapse.length > 0 ) {
595				if ( $el.data( 'use-accordion' ) && 'yes' == $el.data( 'use-accordion' ) ) {
596					$el.find( '.collapse' ).attr( 'data-parent', '#' + $el.attr( 'id' ) );
597				}
598				if ( collapsible == 'yes' ) {
599					$collapse.collapse( { toggle: false, parent: '#' + $el.attr( 'id' ) } );
600				} else if ( !isNaN( active_num ) && active_num == parseInt( active_num ) && $el.find( '.collapse' ).length > active_num ) {
601					$el.find( '.collapse' ).collapse( { toggle: false, parent: '#' + $el.attr( 'id' ) } );
602					$el.find( '.collapse' ).eq( active_num - 1 ).collapse( 'toggle' );
603				} else {
604					$el.find( '.collapse' ).collapse( { parent: '#' + $el.attr( 'id' ) } );
605				}
606			}
607
608			return this;
609		}
610	};
611
612	// expose to scope
613	$.extend( theme, {
614		Accordion: Accordion
615	} );
616
617	// jquery plugin
618	$.fn.themeAccordion = function( opts ) {
619		return this.map( function() {
620			var $this = $( this );
621
622			if ( $this.data( instanceName ) ) {
623				return $this.data( instanceName );
624			} else {
625				return new theme.Accordion( $this, opts );
626			}
627
628		} );
629	};
630
631} ).apply( this, [window.theme, jQuery] );
632
633
634// Accordion Menu
635( function( theme, $ ) {
636
637	'use strict';
638
639	theme = theme || {};
640
641	var instanceName = '__accordionMenu';
642
643	var AccordionMenu = function( $el, opts ) {
644		return this.initialize( $el, opts );
645	};
646
647	AccordionMenu.defaults = {
648
649	};
650
651	AccordionMenu.prototype = {
652		initialize: function( $el, opts ) {
653			if ( $el.data( instanceName ) ) {
654				return this;
655			}
656
657			this.$el = $el;
658
659			this
660				.setData()
661				.setOptions( opts )
662				.build();
663
664			return this;
665		},
666
667		setData: function() {
668			this.$el.data( instanceName, this );
669
670			return this;
671		},
672
673		setOptions: function( opts ) {
674			this.options = $.extend( true, {}, AccordionMenu.defaults, opts, {
675				wrapper: this.$el
676			} );
677
678			return this;
679		},
680
681		build: function() {
682			var self = this,
683				$el = this.options.wrapper;
684
685			$el.find( 'li.menu-item.active' ).each( function() {
686				var $this = $( this );
687
688				if ( $this.find( '> .arrow' ).get( 0 ) )
689					$this.find( '> .arrow' ).trigger( 'click' );
690			} );
691
692			$el.on( 'click', '.arrow', function( e ) {
693				e.preventDefault();
694				e.stopPropagation();
695				var $this = $( this ),
696					$parent = $this.closest( 'li' );
697				if ( typeof self.options.open_one != 'undefined' ) {
698					$parent.siblings( '.open' ).children( '.arrow' ).next().hide();
699					$parent.siblings( '.open' ).removeClass( 'open' );
700					$this.next().stop().toggle();
701				} else {
702					$this.next().stop().slideToggle();
703				}
704				if ( $parent.hasClass( 'open' ) ) {
705					$parent.removeClass( 'open' );
706				} else {
707					$parent.addClass( 'open' );
708				}
709				return false;
710			} );
711
712			return this;
713		}
714	};
715
716	// expose to scope
717	$.extend( theme, {
718		AccordionMenu: AccordionMenu
719	} );
720
721	// jquery plugin
722	$.fn.themeAccordionMenu = function( opts ) {
723		return this.map( function() {
724			var $this = $( this );
725
726			if ( $this.data( instanceName ) ) {
727				return $this.data( instanceName );
728			} else {
729				return new theme.AccordionMenu( $this, opts );
730			}
731
732		} );
733	};
734
735} ).apply( this, [window.theme, jQuery] );
736
737// Lazyload Menu
738( function( theme, $ ) {
739
740	'use strict';
741
742	theme = theme || {};
743
744	// expose to scope
745	$.extend( theme, {
746		lazyload_menu: function( $el, menu_type, menu_id ) {
747			if ( !js_porto_vars.lazyload_menu && 'mobile_menu' != menu_type ) {
748				return;
749			}
750			if ( menu_type ) {
751				var reload_menu = false,
752					menu_args = {
753						action: 'porto_lazyload_menu',
754						menu_type: menu_type,
755						nonce: js_porto_vars.porto_nonce
756					};
757				if ( menu_id ) {
758					menu_args['menu_id'] = menu_id;
759				}
760				var menu_loaded_fn = function( data ) {
761					if ( !data ) {
762						return;
763					}
764					var $data = $( data );
765					if ( 'mobile_menu' != menu_type ) {
766						$el.each( function( i ) {
767							var $menu = $( this ),
768								$main_menu = $data.children( '.mega-menu, .sidebar-menu' ).eq( i );
769							if ( !$main_menu.length ) {
770								$main_menu = $data.find( '.mega-menu, .sidebar-menu' ).eq( i );
771							}
772							$menu.children( 'li.menu-item-has-children' ).each( function( index ) {
773								var popup = $main_menu.children( 'li.menu-item-has-children' ).eq( index ).children( '.popup, .sub-menu' );
774								if ( popup.hasClass( 'popup' ) ) {
775									popup = popup.children( '.inner' );
776								}
777								if ( popup.length ) {
778									if ( $( this ).children( '.popup' ).length ) {
779										$( this ).children( '.popup' ).children( '.inner' ).replaceWith( popup );
780									} else if ( $menu.hasClass( 'overlay' ) ) {
781										$( this ).children( '.sub-menu' ).remove();
782										$( this ).append( popup );
783									} else {
784										$( this ).children( '.sub-menu' ).replaceWith( popup );
785									}
786								}
787							} );
788							if ( $menu.hasClass( 'mega-menu' ) ) {
789								theme.MegaMenu.build( $menu );
790							} else {
791								if ( $menu.hasClass( 'side-menu-accordion' ) ) {
792									$menu.themeAccordionMenu( { 'open_one': true } );
793								} else {
794									theme.SidebarMenu.build( $menu );
795								}
796							}
797							$menu.addClass( 'sub-ready' ).trigger( 'sub-loaded' );
798						} );
799					}
800					if ( $data.find( '#nav-panel, #side-nav-panel' ).length || 'mobile_menu' == menu_type ) {
801						var lazyload_again = false;
802						if ( $( '#nav-panel' ).length ) {
803							var $menu_content = $data.find( '.mobile-nav-wrap > *' );
804							if ( $menu_content.length ) {
805								$( '#nav-panel .mobile-nav-wrap > *' ).replaceWith( $menu_content );
806								$( '#nav-panel .mobile-nav-wrap' ).removeClass( 'skeleton-body porto-ajax-loading' );
807								$( '#nav-panel .accordion-menu' ).themeAccordionMenu();
808							} else {
809								lazyload_again = true;
810							}
811						} else if ( $( '#side-nav-panel' ).length ) {
812							var $menu_content = $data.find( '.side-nav-panel-close' );
813							if ( $menu_content.length ) {
814								$( '#side-nav-panel' ).replaceWith( $menu_content.parent() );
815								$( '#side-nav-panel .accordion-menu' ).themeAccordionMenu();
816							} else {
817								lazyload_again = true;
818							}
819						}
820						if ( lazyload_again && !reload_menu ) {
821							reload_menu = true;
822							lazyload_again = false;
823							var menu_again_args = menu_args;
824							menu_again_args['porto_lazyload_menu_2'] = 1;
825							$.post( window.location.href, menu_again_args, menu_loaded_fn );
826						}
827					}
828					if ( typeof $el == 'object' && $el.length ) {
829						$el.find( '.porto-lazyload:not(.lazy-load-loaded)' ).themePluginLazyLoad( {} );
830						$el.find( '.porto-carousel' ).each( function() {
831							$( this ).themeCarousel( $( this ).data( 'plugin-options' ) );
832						} );
833						$el.find( '[data-appear-animation]' ).each( function() {
834							$( this ).themeAnimate( $( this ).data( 'plugin-options' ) );
835						} );
836					}
837				};
838				$.post( window.location.href, menu_args, menu_loaded_fn );
839			}
840		}
841	} );
842
843} ).apply( this, [window.theme, jQuery] );
844
845
846// Chart Circular
847( function( theme, $ ) {
848	'use strict';
849
850	theme = theme || {};
851
852	var instanceName = '__chartCircular';
853
854	var ChartCircular = function( $el, opts ) {
855		return this.initialize( $el, opts );
856	};
857
858	ChartCircular.defaults = {
859		accX: 0,
860		accY: -150,
861		delay: 1,
862		barColor: '#0088CC',
863		trackColor: '#f2f2f2',
864		scaleColor: false,
865		scaleLength: 5,
866		lineCap: 'round',
867		lineWidth: 13,
868		size: 175,
869		rotate: 0,
870		animate: ( {
871			duration: 2500,
872			enabled: true
873		} )
874	};
875
876	ChartCircular.prototype = {
877		initialize: function( $el, opts ) {
878			if ( $el.data( instanceName ) ) {
879				return this;
880			}
881
882			this.$el = $el;
883
884			this
885				.setData()
886				.setOptions( opts )
887				.build();
888
889			return this;
890		},
891
892		setData: function() {
893			this.$el.data( instanceName, this );
894
895			return this;
896		},
897
898		setOptions: function( opts ) {
899			this.options = $.extend( true, {}, ChartCircular.defaults, opts, {
900				wrapper: this.$el
901			} );
902
903			return this;
904		},
905
906		build: function() {
907			if ( !$.fn.easyPieChart ) {
908				return this;
909			}
910
911			var self = this,
912				$el = this.options.wrapper,
913				value = this.options.percentValue ? parseInt( this.options.percentValue ) : parseInt( $el.attr( 'data-percent' ), 10 ),
914				percentEl = $el.find( '.percent' );
915
916			if ( !value ) value = 1;
917			var labelValue = this.options.labelValue ? parseInt( this.options.labelValue, 10 ) : value;
918
919			$.extend( true, self.options, {
920				onStep: function( from, to, currentValue ) {
921					percentEl.html( parseInt( labelValue * currentValue / value ) );
922				}
923			} );
924
925			$el.attr( 'data-percent', 0 ).easyPieChart( self.options );
926
927			var handler;
928			if ( Number( self.options.delay ) <= 1000 / 60 ) {
929				handler = theme.requestFrame;
930			} else {
931				handler = theme.requestTimeout;
932			}
933
934			handler( function() {
935				if ( $el.data( 'easyPieChart' ) ) {
936					$el.data( 'easyPieChart' ).update( value );
937					$el.attr( 'data-percent', value );
938				}
939			}, self.options.delay );
940
941			return this;
942		}
943	};
944
945	// expose to scope
946	$.extend( theme, {
947		ChartCircular: ChartCircular
948	} );
949
950	// jquery plugin
951	$.fn.themeChartCircular = function( opts ) {
952		return this.map( function() {
953			var $this = $( this );
954
955			if ( $this.data( instanceName ) ) {
956				return $this.data( instanceName );
957			} else {
958				return new theme.ChartCircular( $this, opts );
959			}
960
961		} );
962	};
963
964} ).apply( this, [window.theme, jQuery] );
965
966
967// Fit Video
968( function( theme, $ ) {
969	'use strict';
970
971	theme = theme || {};
972
973	var instanceName = '__fitVideo';
974
975	var FitVideo = function( $el, opts ) {
976		return this.initialize( $el, opts );
977	};
978
979	FitVideo.defaults = {
980
981	};
982
983	FitVideo.prototype = {
984		initialize: function( $el, opts ) {
985			if ( $el.data( instanceName ) ) {
986				return this;
987			}
988
989			this.$el = $el;
990
991			this
992				.setData()
993				.setOptions( opts )
994				.build();
995
996			return this;
997		},
998
999		setData: function() {
1000			this.$el.data( instanceName, this );
1001
1002			return this;
1003		},
1004
1005		setOptions: function( opts ) {
1006			this.options = $.extend( true, {}, FitVideo.defaults, opts, {
1007				wrapper: this.$el
1008			} );
1009
1010			return this;
1011		},
1012
1013		build: function() {
1014			if ( !$.fn.fitVids ) {
1015				return this;
1016			}
1017
1018			var $el = this.options.wrapper;
1019
1020			$el.fitVids();
1021			$( window ).on( 'resize', function() {
1022				$el.fitVids();
1023			} );
1024
1025			return this;
1026		}
1027	};
1028
1029	// expose to scope
1030	$.extend( theme, {
1031		FitVideo: FitVideo
1032	} );
1033
1034	// jquery plugin
1035	$.fn.themeFitVideo = function( opts ) {
1036		return this.map( function() {
1037			var $this = $( this );
1038
1039			if ( $this.data( instanceName ) ) {
1040				return $this.data( instanceName );
1041			} else {
1042				return new theme.FitVideo( $this, opts );
1043			}
1044
1045		} );
1046	};
1047
1048} ).apply( this, [window.theme, jQuery] );
1049
1050/* Porto Video Background */
1051( function( theme, $ ) {
1052	'use strict';
1053
1054	theme = theme || {};
1055
1056	var instanceName = '__videobackground';
1057
1058	var PluginVideoBackground = function( $el, opts ) {
1059		return this.initialize( $el, opts );
1060	};
1061
1062	PluginVideoBackground.defaults = {
1063		overlay: true,
1064		volume: 1,
1065		playbackRate: 1,
1066		muted: true,
1067		loop: true,
1068		autoplay: true,
1069		position: '50% 50%',
1070		posterType: 'detect'
1071	};
1072
1073	PluginVideoBackground.prototype = {
1074		initialize: function( $el, opts ) {
1075			this.$el = $el;
1076
1077			this
1078				.setData()
1079				.setOptions( opts )
1080				.build();
1081
1082			return this;
1083		},
1084
1085		setData: function() {
1086			this.$el.data( instanceName, this );
1087
1088			return this;
1089		},
1090
1091		setOptions: function( opts ) {
1092			this.options = $.extend( true, {}, PluginVideoBackground.defaults, opts, {
1093				path: this.$el.data( 'video-path' ),
1094				wrapper: this.$el
1095			} );
1096
1097			return this;
1098		},
1099
1100		build: function() {
1101
1102			if ( !$.fn.vide || !this.options.path ) {
1103				return this;
1104			}
1105
1106			if ( this.options.overlay ) {
1107				this.options.wrapper.prepend(
1108					$( '<div />' ).addClass( 'video-overlay' )
1109				);
1110			}
1111
1112			this.options.wrapper.vide( this.options.path, this.options );
1113
1114			return this;
1115		}
1116	};
1117
1118	// expose to scope
1119	$.extend( theme, {
1120		PluginVideoBackground: PluginVideoBackground
1121	} );
1122
1123	// jquery plugin
1124	$.fn.themePluginVideoBackground = function( opts ) {
1125		return this.map( function() {
1126			var $this = $( this );
1127
1128			if ( $this.data( instanceName ) ) {
1129				return $this.data( instanceName );
1130			} else {
1131				return new PluginVideoBackground( $this, opts );
1132			}
1133
1134		} );
1135	};
1136
1137} ).apply( this, [window.theme, jQuery] );
1138
1139// Flickr Zoom
1140( function( theme, $ ) {
1141	'use strict';
1142
1143	theme = theme || {};
1144
1145	var instanceName = '__flickrZoom';
1146
1147	var FlickrZoom = function( $el, opts ) {
1148		return this.initialize( $el, opts );
1149	};
1150
1151	FlickrZoom.defaults = {
1152
1153	};
1154
1155	FlickrZoom.prototype = {
1156		initialize: function( $el, opts ) {
1157			if ( $el.data( instanceName ) ) {
1158				return this;
1159			}
1160
1161			this.$el = $el;
1162
1163			this
1164				.setData()
1165				.setOptions( opts )
1166				.build();
1167
1168			return this;
1169		},
1170
1171		setData: function() {
1172			this.$el.data( instanceName, this );
1173
1174			return this;
1175		},
1176
1177		setOptions: function( opts ) {
1178			this.options = $.extend( true, {}, FlickrZoom.defaults, opts, {
1179				wrapper: this.$el
1180			} );
1181
1182			return this;
1183		},
1184
1185		build: function() {
1186			var $el = this.options.wrapper,
1187				links = [],
1188				i = 0,
1189				$flickr_links = $el.find( '.flickr_badge_image > a' );
1190
1191			$flickr_links.each( function() {
1192				var slide = {},
1193					$image = $( this ).find( '> img' );
1194
1195				slide.src = $image.attr( 'src' ).replace( '_s.', '_b.' );
1196				slide.title = $image.attr( 'title' );
1197				links[i] = slide;
1198				i++;
1199			} );
1200
1201			$flickr_links.on( 'click', function( e ) {
1202				e.preventDefault();
1203				if ( $.fn.magnificPopup ) {
1204					$.magnificPopup.close();
1205					$.magnificPopup.open( $.extend( true, {}, theme.mfpConfig, {
1206						items: links,
1207						gallery: {
1208							enabled: true
1209						},
1210						type: 'image'
1211					} ), $flickr_links.index( $( this ) ) );
1212				}
1213			} );
1214
1215			return this;
1216		}
1217	};
1218
1219	// expose to scope
1220	$.extend( theme, {
1221		FlickrZoom: FlickrZoom
1222	} );
1223
1224	// jquery plugin
1225	$.fn.themeFlickrZoom = function( opts ) {
1226		return this.map( function() {
1227			var $this = $( this );
1228
1229			if ( $this.data( instanceName ) ) {
1230				return $this.data( instanceName );
1231			} else {
1232				return new theme.FlickrZoom( $this, opts );
1233			}
1234
1235		} );
1236	}
1237
1238} ).apply( this, [window.theme, jQuery] );
1239
1240// Lazy Load
1241( function( theme, $ ) {
1242	'use strict';
1243
1244	theme = theme || {};
1245
1246	var instanceName = '__lazyload';
1247
1248	var PluginLazyLoad = function( $el, opts ) {
1249		return this.initialize( $el, opts );
1250	};
1251
1252	PluginLazyLoad.defaults = {
1253		effect: 'show',
1254		appearEffect: '',
1255		appear: function( elements_left, settings ) {
1256
1257		},
1258		load: function( elements_left, settings ) {
1259			$( this ).addClass( 'lazy-load-loaded' );
1260		}
1261	};
1262
1263	PluginLazyLoad.prototype = {
1264		initialize: function( $el, opts ) {
1265			if ( !$el.length ) {
1266				return this;
1267			}
1268
1269			if ( !$.fn.lazyload ) {
1270				return this;
1271			}
1272
1273			var options = $.extend( true, {}, PluginLazyLoad.defaults, opts, {} );
1274			return lazyload( $el, options );
1275		}
1276	};
1277
1278	// expose to scope
1279	$.extend( theme, {
1280		PluginLazyLoad: PluginLazyLoad
1281	} );
1282
1283	// jquery plugin
1284	$.fn.themePluginLazyLoad = function( opts ) {
1285		var $this = $( this );
1286		if ( $this.data( instanceName ) ) {
1287			return this;
1288		} else {
1289			var ins = new PluginLazyLoad( $.makeArray( this ), opts );
1290			$this.data( instanceName, ins );
1291		}
1292		return this;
1293	}
1294
1295} ).apply( this, [window.theme, jQuery] );
1296
1297
1298// Loading Overlay
1299( function( theme, $ ) {
1300
1301	'use strict';
1302
1303	theme = theme || {};
1304
1305	var loadingOverlayTemplate = [
1306		'<div class="loading-overlay">',
1307		'<div class="loader"></div>',
1308		'</div>'
1309	].join( '' );
1310
1311	var LoadingOverlay = function( $wrapper, options ) {
1312		return this.initialize( $wrapper, options );
1313	};
1314
1315	LoadingOverlay.prototype = {
1316
1317		options: {
1318			css: {}
1319		},
1320
1321		initialize: function( $wrapper, options ) {
1322			this.$wrapper = $wrapper;
1323
1324			this
1325				.setVars()
1326				.setOptions( options )
1327				.build()
1328				.events();
1329
1330			this.$wrapper.data( 'loadingOverlay', this );
1331		},
1332
1333		setVars: function() {
1334			this.$overlay = this.$wrapper.find( '.loading-overlay' );
1335
1336			return this;
1337		},
1338
1339		setOptions: function( options ) {
1340			if ( !this.$overlay.get( 0 ) ) {
1341				this.matchProperties();
1342			}
1343			this.options = $.extend( true, {}, this.options, options );
1344			this.loaderClass = this.getLoaderClass( this.options.css.backgroundColor );
1345
1346			return this;
1347		},
1348
1349		build: function() {
1350			if ( !this.$overlay.closest( document.documentElement ).get( 0 ) ) {
1351				if ( !this.$cachedOverlay ) {
1352					this.$overlay = $( loadingOverlayTemplate ).clone();
1353
1354					if ( this.options.css ) {
1355						this.$overlay.css( this.options.css );
1356						this.$overlay.find( '.loader' ).addClass( this.loaderClass );
1357					}
1358				} else {
1359					this.$overlay = this.$cachedOverlay.clone();
1360				}
1361
1362				this.$wrapper.append( this.$overlay );
1363			}
1364
1365			if ( !this.$cachedOverlay ) {
1366				this.$cachedOverlay = this.$overlay.clone();
1367			}
1368
1369			return this;
1370		},
1371
1372		events: function() {
1373			var _self = this;
1374
1375			if ( this.options.startShowing ) {
1376				_self.show();
1377			}
1378
1379			if ( this.$wrapper.is( 'body' ) || this.options.hideOnWindowLoad ) {
1380				$( window ).on( 'load error', function() {
1381					_self.hide();
1382				} );
1383			}
1384
1385			if ( this.options.listenOn ) {
1386				$( this.options.listenOn )
1387					.on( 'loading-overlay:show beforeSend.ic', function( e ) {
1388						e.stopPropagation();
1389						_self.show();
1390					} )
1391					.on( 'loading-overlay:hide complete.ic', function( e ) {
1392						e.stopPropagation();
1393						_self.hide();
1394					} );
1395			}
1396
1397			this.$wrapper
1398				.on( 'loading-overlay:show beforeSend.ic', function( e ) {
1399					e.stopPropagation();
1400					_self.show();
1401				} )
1402				.on( 'loading-overlay:hide complete.ic', function( e ) {
1403					e.stopPropagation();
1404					_self.hide();
1405				} );
1406
1407			return this;
1408		},
1409
1410		show: function() {
1411			this.build();
1412
1413			this.position = this.$wrapper.css( 'position' ).toLowerCase();
1414			if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
1415				this.$wrapper.css( {
1416					position: 'relative'
1417				} );
1418			}
1419			this.$wrapper.addClass( 'loading-overlay-showing' );
1420		},
1421
1422		hide: function() {
1423			var _self = this;
1424
1425			this.$wrapper.removeClass( 'loading-overlay-showing' );
1426			setTimeout( function() {
1427				if ( this.position != 'relative' || this.position != 'absolute' || this.position != 'fixed' ) {
1428					_self.$wrapper.css( { position: '' } );
1429				}
1430			}, 500 );
1431		},
1432
1433		matchProperties: function() {
1434			var i,
1435				l,
1436				properties;
1437
1438			properties = [
1439				'backgroundColor',
1440				'borderRadius'
1441			];
1442
1443			l = properties.length;
1444
1445			for ( i = 0; i < l; i++ ) {
1446				var obj = {};
1447				obj[properties[i]] = this.$wrapper.css( properties[i] );
1448
1449				$.extend( this.options.css, obj );
1450			}
1451		},
1452
1453		getLoaderClass: function( backgroundColor ) {
1454			if ( !backgroundColor || backgroundColor === 'transparent' || backgroundColor === 'inherit' ) {
1455				return 'black';
1456			}
1457
1458			var hexColor,
1459				r,
1460				g,
1461				b,
1462				yiq;
1463
1464			var colorToHex = function( color ) {
1465				var hex,
1466					rgb;
1467
1468				if ( color.indexOf( '#' ) > - 1 ) {
1469					hex = color.replace( '#', '' );
1470				} else {
1471					rgb = color.match( /\d+/g );
1472					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 );
1473				}
1474
1475				if ( hex.length === 3 ) {
1476					hex = hex + hex;
1477				}
1478
1479				return hex;
1480			};
1481
1482			hexColor = colorToHex( backgroundColor );
1483
1484			r = parseInt( hexColor.substr( 0, 2 ), 16 );
1485			g = parseInt( hexColor.substr( 2, 2 ), 16 );
1486			b = parseInt( hexColor.substr( 4, 2 ), 16 );
1487			yiq = ( ( r * 299 ) + ( g * 587 ) + ( b * 114 ) ) / 1000;
1488
1489			return ( yiq >= 128 ) ? 'black' : 'white';
1490		}
1491
1492	};
1493
1494	// expose to scope
1495	$.extend( theme, {
1496		LoadingOverlay: LoadingOverlay
1497	} );
1498
1499	// expose as a jquery plugin
1500	$.fn.loadingOverlay = function( opts ) {
1501		return this.each( function() {
1502			var $this = $( this );
1503
1504			var loadingOverlay = $this.data( 'loadingOverlay' );
1505			if ( loadingOverlay ) {
1506				return loadingOverlay;
1507			} else {
1508				var options = opts || $this.data( 'loading-overlay-options' ) || {};
1509				return new LoadingOverlay( $this, options );
1510			}
1511		} );
1512	}
1513
1514	// auto init
1515	//$( function () {
1516	$( 'body.loading-overlay-showing, [data-loading-overlay]' ).loadingOverlay();
1517	//} );
1518
1519} ).apply( this, [window.theme, jQuery] );
1520
1521
1522// Masonry
1523( function( theme, $ ) {
1524	'use strict';
1525
1526	theme = theme || {};
1527
1528	var instanceName = '__masonry';
1529
1530	var Masonry = function( $el, opts ) {
1531		return this.initialize( $el, opts );
1532	};
1533
1534	Masonry.defaults = {
1535		itemSelector: 'li',
1536		isOriginLeft: !theme.rtl
1537	};
1538
1539	Masonry.prototype = {
1540		initialize: function( $el, opts ) {
1541			if ( $el.data( instanceName ) ) {
1542				return this;
1543			}
1544
1545			this.$el = $el;
1546
1547			this
1548				.setData()
1549				.setOptions( opts )
1550				.build();
1551
1552			return this;
1553		},
1554
1555		setData: function() {
1556			this.$el.data( instanceName, this );
1557
1558			return this;
1559		},
1560
1561		setOptions: function( opts ) {
1562			this.options = $.extend( true, {}, Masonry.defaults, opts, {
1563				wrapper: this.$el
1564			} );
1565
1566			return this;
1567		},
1568
1569		build: function() {
1570			if ( !$.fn.isotope ) {
1571				return this;
1572			}
1573
1574			var self = this,
1575				$el = this.options.wrapper,
1576				trigger_timer = null;
1577			$el.isotope( this.options );
1578			$el.isotope( 'on', 'layoutComplete', function() {
1579				if ( typeof this.options.callback == 'function' ) {
1580					this.options.callback.call();
1581				}
1582
1583				if ( $el.find( '.porto-lazyload:not(.lazy-load-loaded):visible' ).length ) {
1584					$( window ).trigger( 'scroll' );
1585				}
1586			} );
1587			$el.isotope( 'layout' );
1588			self.resize();
1589			$( window ).smartresize( function() {
1590				self.resize()
1591			} );
1592
1593			return this;
1594		},
1595
1596		resize: function() {
1597			var self = this,
1598				$el = this.options.wrapper;
1599
1600			if ( self.resizeTimer ) {
1601				theme.deleteTimeout( self.resizeTimer );
1602			}
1603
1604			self.resizeTimer = theme.requestTimeout( function() {
1605				if ( $el.data( 'isotope' ) ) {
1606					$el.isotope( 'layout' );
1607				}
1608				delete self.resizeTimer;
1609			}, 600 );
1610		}
1611	};
1612
1613	// expose to scope
1614	$.extend( theme, {
1615		Masonry: Masonry
1616	} );
1617
1618	// jquery plugin
1619	$.fn.themeMasonry = function( opts ) {
1620		return this.map( function() {
1621			var $this = $( this );
1622			imagesLoaded( this, function() {
1623				if ( $this.data( instanceName ) ) {
1624					return $this.data( instanceName );
1625				} else {
1626					return new theme.Masonry( $this, opts );
1627				}
1628			} );
1629
1630		} );
1631	}
1632
1633} ).apply( this, [window.theme, jQuery] );
1634
1635
1636// Preview Image
1637( function( theme, $ ) {
1638	'use strict';
1639
1640	theme = theme || {};
1641
1642	var instanceName = '__previewImage';
1643
1644	var PreviewImage = function( $el, opts ) {
1645		return this.initialize( $el, opts );
1646	};
1647
1648	PreviewImage.defaults = {
1649
1650	};
1651
1652	PreviewImage.prototype = {
1653		initialize: function( $el, opts ) {
1654			if ( $el.data( instanceName ) ) {
1655				return this;
1656			}
1657
1658			this.$el = $el;
1659
1660			this
1661				.setData()
1662				.setOptions( opts )
1663				.build();
1664
1665			return this;
1666		},
1667
1668		setData: function() {
1669			this.$el.data( instanceName, this );
1670
1671			return this;
1672		},
1673
1674		setOptions: function( opts ) {
1675			this.options = $.extend( true, {}, PreviewImage.defaults, opts, {
1676				wrapper: this.$el
1677			} );
1678
1679			return this;
1680		},
1681
1682		build: function() {
1683			var $el = this.options.wrapper,
1684				image = $el.data( 'image' );
1685
1686			if ( image ) {
1687				$el.css( 'background-image', 'url(' + image + ')' );
1688			}
1689
1690			return this;
1691		}
1692	};
1693
1694	// expose to scope
1695	$.extend( theme, {
1696		PreviewImage: PreviewImage
1697	} );
1698
1699	// jquery plugin
1700	$.fn.themePreviewImage = function( opts ) {
1701		return this.map( function() {
1702			var $this = $( this );
1703
1704			if ( $this.data( instanceName ) ) {
1705				return $this.data( instanceName );
1706			} else {
1707				return new theme.PreviewImage( $this, opts );
1708			}
1709
1710		} );
1711	}
1712
1713} ).apply( this, [window.theme, jQuery] );
1714
1715
1716// Toggle
1717( function( theme, $ ) {
1718	'use strict';
1719
1720	theme = theme || {};
1721
1722	var instanceName = '__toggle';
1723
1724	var Toggle = function( $el, opts ) {
1725		return this.initialize( $el, opts );
1726	};
1727
1728	Toggle.defaults = {
1729
1730	};
1731
1732	Toggle.prototype = {
1733		initialize: function( $el, opts ) {
1734			if ( $el.data( instanceName ) ) {
1735				return this;
1736			}
1737
1738			this.$el = $el;
1739
1740			this
1741				.setData()
1742				.setOptions( opts )
1743				.build();
1744
1745			return this;
1746		},
1747
1748		setData: function() {
1749			this.$el.data( instanceName, this );
1750
1751			return this;
1752		},
1753
1754		setOptions: function( opts ) {
1755			this.options = $.extend( true, {}, Toggle.defaults, opts, {
1756				wrapper: this.$el
1757			} );
1758
1759			return this;
1760		},
1761
1762		build: function() {
1763			var $el = this.options.wrapper;
1764
1765			if ( $el.hasClass( 'active' ) )
1766				$el.find( "> div.toggle-content" ).stop().slideDown( 350, function() {
1767					$( this ).attr( 'style', '' ).show();
1768				} );
1769
1770			$el.on( 'click', "> label", function( e ) {
1771				var parentSection = $( this ).parent(),
1772					parentWrapper = $( this ).closest( "div.toogle" ),
1773					parentToggles = $( this ).closest( ".porto-toggles" ),
1774					isAccordion = parentWrapper.hasClass( "toogle-accordion" ),
1775					toggleContent = parentSection.find( "> div.toggle-content" );
1776
1777				if ( isAccordion && typeof ( e.originalEvent ) != "undefined" ) {
1778					parentWrapper.find( "section.toggle.active > label" ).trigger( "click" );
1779				}
1780
1781				// Preview Paragraph
1782				if ( !parentSection.hasClass( "active" ) ) {
1783					if ( parentToggles.length ) {
1784						if ( parentToggles.data( 'view' ) == 'one-toggle' ) {
1785							parentToggles.find( '.toggle' ).each( function() {
1786								$( this ).removeClass( 'active' );
1787								$( this ).find( "> div.toggle-content" ).stop().slideUp( 350, function() {
1788									$( this ).attr( 'style', '' ).hide();
1789								} );
1790							} );
1791						}
1792					}
1793					toggleContent.stop().slideDown( 350, function() {
1794						$( this ).attr( 'style', '' ).show();
1795						theme.refreshVCContent( toggleContent );
1796					} );
1797					parentSection.addClass( "active" );
1798				} else {
1799					if ( !parentToggles.length || parentToggles.data( 'view' ) != 'one-toggle' ) {
1800						toggleContent.stop().slideUp( 350, function() {
1801							$( this ).attr( 'style', '' ).hide();
1802						} );
1803						parentSection.removeClass( "active" );
1804					}
1805				}
1806			} );
1807
1808			return this;
1809		}
1810	};
1811
1812	// expose to scope
1813	$.extend( theme, {
1814		Toggle: Toggle
1815	} );
1816
1817	// jquery plugin
1818	$.fn.themeToggle = function( opts ) {
1819		return this.map( function() {
1820			var $this = $( this );
1821
1822			if ( $this.data( instanceName ) ) {
1823				return $this.data( instanceName );
1824			} else {
1825				return new theme.Toggle( $this, opts );
1826			}
1827
1828		} );
1829	}
1830
1831} ).apply( this, [window.theme, jQuery] );
1832
1833
1834// Parallax
1835( function( theme, $ ) {
1836	'use strict';
1837
1838	theme = theme || {};
1839
1840	var instanceName = '__parallax';
1841
1842	var Parallax = function( $el, opts ) {
1843		return this.initialize( $el, opts );
1844	};
1845
1846	Parallax.defaults = {
1847		speed: 1.5,
1848		horizontalPosition: '50%',
1849		offset: 0,
1850		scale: false,
1851		startOffset: 7,
1852		scaleInvert: false,
1853	};
1854
1855	Parallax.prototype = {
1856		initialize: function( $el, opts ) {
1857			if ( $el.data( instanceName ) ) {
1858				return this;
1859			}
1860
1861			this.$el = $el;
1862
1863			this
1864				.setData()
1865				.setOptions( opts )
1866				.build();
1867
1868			return this;
1869		},
1870
1871		setData: function() {
1872			this.$el.data( instanceName, this );
1873
1874			return this;
1875		},
1876
1877		setOptions: function( opts ) {
1878			this.options = $.extend( true, {}, Parallax.defaults, opts, {
1879				wrapper: this.$el
1880			} );
1881
1882			return this;
1883		},
1884
1885		build: function() {
1886			var self = this,
1887				$window = $( window ),
1888				offset,
1889				yPos,
1890				bgpos,
1891				background;
1892
1893			// Create Parallax Element
1894			background = $( '<div class="parallax-background"></div>' );
1895
1896			// Set Style for Parallax Element
1897			var bg = self.options.wrapper.data( 'image-src' ) ? 'url(' + self.options.wrapper.data( 'image-src' ) + ')' : self.options.wrapper.css( 'background-image' );
1898			background.css( {
1899				'background-image': bg,
1900				'background-size': 'cover',
1901				'background-position': '50% 0%',
1902				'position': 'absolute',
1903				'top': 0,
1904				'left': 0,
1905				'width': '100%',
1906				'height': self.options.speed * 100 + '%'
1907			} );
1908
1909			// Add Parallax Element on DOM
1910			self.options.wrapper.prepend( background );
1911
1912			// Set Overlfow Hidden and Position Relative to Parallax Wrapper
1913			self.options.wrapper.css( {
1914				'position': 'relative',
1915				'overflow': 'hidden'
1916			} );
1917
1918			if ( self.options.wrapper.attr( 'data-parallax-type' ) ) { // horizontal
1919				self.options.parallaxType = 'horizontal';
1920				background.css( {
1921					'background-position': '0% 50%',
1922					'width': self.options.speed * 100 + '%',
1923					'height': '100%',
1924				} );
1925			}
1926
1927			// Scroll Scale
1928			if ( self.options.scale ) {
1929				background.wrap( '<div class="parallax-scale-wrapper"></div>' );
1930				background.css( {
1931					'transition': 'transform 500ms ease-out'
1932				} );
1933				this.scaleParallaxFunc = this.scaleParallax.bind( this );
1934				this.scaleParallaxFunc();
1935				window.addEventListener( 'scroll', this.scaleParallaxFunc );
1936				window.addEventListener( 'resize', this.scaleParallaxFunc );
1937			}
1938			// Parallax Effect on Scroll & Resize
1939			var parallaxEffectOnScrolResize = function() {
1940				var skrollr_size = 100 * self.options.speed,
1941					skrollr_start = -( skrollr_size - 100 );
1942				if ( !self.options.parallaxType ) {
1943					background.attr( "data-bottom-top", "top: " + skrollr_start + "%;" ).attr( "data-top-bottom", "top: 0%;" );
1944				} else {
1945					skrollr_start /= 9.8;
1946					background.attr( "data-bottom-top", "left: " + skrollr_start + "%;" ).attr( "data-top-bottom", "left: 0%;" );
1947				}
1948			}
1949
1950			if ( !theme.is_device_mobile ) {
1951				parallaxEffectOnScrolResize();
1952			} else {
1953				if ( self.options.enableOnMobile == true ) {
1954					parallaxEffectOnScrolResize();
1955				} else {
1956					self.options.wrapper.addClass( 'parallax-disabled' );
1957				}
1958			}
1959
1960			return this;
1961		},
1962
1963		scaleParallax: function() {
1964			var self = this,
1965				$window = $( window ),
1966				scrollTop = $window.scrollTop(),
1967				$background = self.options.wrapper.find( '.parallax-background' ),
1968				elementOffset = self.options.wrapper.offset().top,
1969				currentElementOffset = ( elementOffset - scrollTop ),
1970				scrollPercent = Math.abs( +( currentElementOffset - $window.height() ) / ( self.options.startOffset ? self.options.startOffset : 7 ) );
1971			scrollPercent = parseInt( ( scrollPercent >= 100 ) ? 100 : scrollPercent );
1972			var currentScale = ( scrollPercent / 100 ) * 50;
1973			if ( !self.options.scaleInvert ) {
1974				$background.css( {
1975					'transform': 'scale(1.' + String( currentScale ).padStart( 2, '0' ) + ', 1.' + String( currentScale ).padStart( 2, '0' ) + ')'
1976				} );
1977			} else {
1978				$background.css( {
1979					'transform': 'scale(1.' + String( 50 - currentScale ).padStart( 2, '0' ) + ', 1.' + String( 50 - currentScale ).padStart( 2, '0' ) + ')'
1980				} );
1981			}
1982		},
1983
1984		disable: function() {
1985			var self = this;
1986			if ( self.options.scale ) {
1987				window.removeEventListener( 'scroll', this.scaleParallaxFunc );
1988				window.removeEventListener( 'resize', this.scaleParallaxFunc );
1989			}
1990		}
1991	};
1992
1993	// expose to scope
1994	$.extend( theme, {
1995		Parallax: Parallax
1996	} );
1997
1998	// jquery plugin
1999	$.fn.themeParallax = function( opts ) {
2000		if ( typeof skrollr == 'undefined' ) {
2001			return this;
2002		}
2003		var obj = this.map( function() {
2004			var $this = $( this );
2005
2006			if ( $this.data( instanceName ) ) {
2007				return $this.data( instanceName );
2008			} else {
2009				return new theme.Parallax( $this, opts );
2010			}
2011
2012		} );
2013		if ( theme.portoSkrollr ) {
2014			theme.portoSkrollr.refresh();
2015		} else if ( !theme.is_device_mobile ) {
2016			theme.portoSkrollr = skrollr.init( { forceHeight: false, smoothScrolling: false, mobileCheck: function() { return theme.is_device_mobile } } );
2017		}
2018		return obj;
2019	}
2020
2021} ).apply( this, [window.theme, jQuery] );
2022
2023// In Viewport Style
2024!function( o, e ) { "object" == typeof exports && "undefined" != typeof module ? e( exports ) : "function" == typeof define && define.amd ? define( ["exports"], e ) : e( o.observeElementInViewport = {} ) }( this, function( o ) { function e( o, e, t, r ) { if ( void 0 === t && ( t = function() { } ), void 0 === r && ( r = {} ), !o ) throw new Error( "Target element to observe should be a valid DOM Node" ); var n = Object.assign( {}, { viewport: null, modTop: "0px", modRight: "0px", modBottom: "0px", modLeft: "0px", threshold: [0] }, r ), i = n.viewport, f = n.modTop, s = n.modLeft, u = n.modBottom, a = n.modRight, d = n.threshold; if ( !Array.isArray( d ) && "number" != typeof d ) throw new Error( "threshold should be a number or an array of numbers" ); var p = Array.isArray( d ) ? d.map( function( o ) { return Math.floor( o % 101 ) / 100 } ) : [Math.floor( d ? d % 101 : 0 ) / 100], c = Math.min.apply( Math, p ), m = { root: i instanceof Node ? i : null, rootMargin: f + " " + a + " " + u + " " + s, threshold: p }, h = new IntersectionObserver( function( r, n ) { var i = r.filter( function( e ) { return e.target === o } )[0], f = function() { return n.unobserve( o ) }; i && ( i.isInViewport = i.isIntersecting && i.intersectionRatio >= c, i.isInViewport ? e( i, f, o ) : t( i, f, o ) ) }, m ); return h.observe( o ), function() { return h.unobserve( o ) } } o.observeElementInViewport = e, o.isInViewport = function( o, t ) { return void 0 === t && ( t = {}
2024 ), new Promise( function( r, n ) { try { e( o, function( o, e ) { e(), r( !0 ) }, function( o, e ) { e(), r( !1 ) }, t ) } catch ( o ) { n( o ) } } ) } } );
2025//# sourceMappingURL=index.umd.js.map
2026( function( theme, $ ) {
2027
2028	theme = theme || {};
2029
2030	var instanceName = '__inviewportstyle';
2031
2032	var PluginInViewportStyle = function( $el, opts ) {
2033		return this.initialize( $el, opts );
2034	};
2035
2036	PluginInViewportStyle.defaults = {
2037		viewport: window,
2038		scroll_bg_scale: false,
2039		scale_extra_class: '',
2040		set_round: '',
2041		scale_bg: '#08c',
2042		threshold: [0],
2043		modTop: '-200px',
2044		modBottom: '-200px',
2045		style: { 'transition': 'all 1s ease-in-out' },
2046		styleIn: { 'background-color': '#08c' },
2047		styleOut: { 'background-color': '#fff' },
2048	};
2049
2050	PluginInViewportStyle.prototype = {
2051		initialize: function( $el, opts ) {
2052			if ( $el.data( instanceName ) ) {
2053				return this;
2054			}
2055
2056			this.$el = $el;
2057
2058			this
2059				.setData()
2060				.setOptions( opts )
2061				.build();
2062
2063			return this;
2064		},
2065
2066		setData: function() {
2067			this.$el.data( instanceName, this );
2068
2069			return this;
2070		},
2071
2072		setOptions: function( opts ) {
2073			this.options = $.extend( true, {}, PluginInViewportStyle.defaults, opts, {} );
2074
2075			return this;
2076		},
2077
2078		build: function() {
2079			var self = this,
2080				el = self.$el.get( 0 );
2081
2082			if ( self.options.scroll_bg_scale && 'undefined' != typeof gsap ) {
2083				self.$scaleObject = $( '<div class="scale-expand position-absolute"></div>' ).addClass( self.options.scale_extra_class );
2084				self.$el.addClass( 'view-scale-wrapper' ).append( self.$scaleObject );
2085				self.$scaleObject.css( 'background-color', self.options.scale_bg );
2086				self.scale = true;
2087				self.scaleEventFunc = self.scaleEvent.bind( this );
2088				self.scaleEventFunc();
2089				$( window ).on( 'scroll', self.scaleEventFunc );
2090			} else {
2091				self.$el.css( self.options.style );
2092				if ( typeof window.IntersectionObserver === 'function' ) {
2093					self.viewPort = observeElementInViewport.observeElementInViewport(
2094						el, function() {
2095							self.$el.css( self.options.styleIn );
2096						}, function() {
2097							self.$el.css( self.options.styleOut );
2098						}, {
2099						viewport: self.options.viewport,
2100						threshold: self.options.threshold,
2101						modTop: self.options.modTop,
2102						modBottom: self.options.modBottom
2103					}
2104					)
2105				};
2106			}
2107
2108			return this;
2109		},
2110		scaleEvent: function() {
2111			var self = this,
2112				position = self.$el[0].getBoundingClientRect();
2113
2114			if ( self.scale && position.top < window.innerHeight && position.bottom >= 0 ) {
2115				gsap.set( self.$scaleObject[0], {
2116					width: "150vmax",
2117					height: "150vmax",
2118					xPercent: -50,
2119					yPercent: -50,
2120					top: "50%",
2121					left: "50%"
2122				} );
2123
2124				var scaleGsap = gsap.timeline( {
2125					scrollTrigger: {
2126						trigger: self.$el[0],
2127						start: "-50%",
2128						end: "0%",
2129						scrub: 2,
2130						invalidateOnRefresh: true,
2131					},
2132					defaults: {
2133						ease: "none"
2134					}
2135				} );
2136
2137				scaleGsap.fromTo( self.$scaleObject[0], {
2138					scale: 0
2139				}, {
2140					x: 0,
2141					y: 0,
2142					ease: "power3.in",
2143					scale: 1
2144				} );
2145				self.scale = false;
2146			}
2147		},
2148		disable: function() {
2149			var self = this;
2150			if ( self.options.scroll_bg_scale ) {
2151				self.$el.find( '.scale-expand' ).remove();
2152				self.$el.removeClass( 'view-scale-wrapper' )
2153			} else {
2154				self.$el.css( { 'background-color': '', 'transition': '' } );
2155				self.viewPort();
2156			}
2157		}
2158	};
2159
2160	// expose to scope
2161	$.extend( theme, {
2162		PluginInViewportStyle: PluginInViewportStyle
2163	} );
2164
2165	// jquery plugin
2166	$.fn.themePluginInViewportStyle = function( opts ) {
2167		return this.map( function() {
2168			var $this = $( this );
2169
2170			if ( $this.data( instanceName ) ) {
2171				return $this.data( instanceName );
2172			} else {
2173				return new PluginInViewportStyle( $this, opts );
2174			}
2175
2176		} );
2177	}
2178} ).apply( this, [window.theme, jQuery] );
2179
2180// Sticky
2181( function( theme, $ ) {
2182	'use strict';
2183
2184	// jQuery Pin plugin
2185	$.fn.themePin = function( options ) {
2186		var scrollY = 0, lastScrollY = 0, elements = [], disabled = false, $window = $( window ), fixedSideTop = [], fixedSideBottom = [], prevDataTo 
2186= [];
2187
2188		options = options || {};
2189
2190		var recalculateLimits = function() {
2191			for ( var i = 0, len = elements.length; i < len; i++ ) {
2192				var $this = elements[i];
2193				if ( options.minWidth && window.innerWidth < options.minWidth ) {
2194					if ( $this.parent().hasClass( "pin-wrapper" ) ) { $this.unwrap(); }
2195					$this.css( { width: "", left: "", top: "", position: "" } );
2196					if ( options.activeClass ) { $this.removeClass( options.activeClass ); }
2197					$this.removeClass( 'sticky-transition' );
2198					$this.removeClass( 'sticky-absolute' );
2199					disabled = true;
2200					continue;
2201				} else {
2202					disabled = false;
2203				}
2204
2205				var $container = options.containerSelector ? ( $this.closest( options.containerSelector ).length ? $this.closest( options.containerSelector ) : $( options.containerSelector ) ) : $( document.body ),
2206					offset = $this.offset(),
2207					containerOffset = $container.offset();
2208
2209				if ( typeof containerOffset == 'undefined' ) {
2210					continue;
2211				}
2212
2213				var parentOffset = $this.parent().offset();
2214
2215				if ( !$this.parent().hasClass( "pin-wrapper" ) ) {
2216					$this.wrap( "<div class='pin-wrapper'>" );
2217					if ( $this.hasClass( 'elementor-element-populated' ) ) {
2218						var $el_cont = $this.closest( '.elementor-container' );
2219						if ( $el_cont.length ) {
2220							var matches = $el_cont.attr( 'class' ).match( /elementor-column-gap-([a-z]*)/g );
2221							if ( matches && matches.length ) {
2222								var gap = matches[0].replace( 'elementor-column-gap-', '' );
2223								$this.addClass( 'porto-gap-' + gap );
2224							}
2225						}
2226					}
2227				}
2228
2229				var pad = $.extend( {
2230					top: 0,
2231					bottom: 0
2232				}, options.padding || {} );
2233
2234				var $pin = $this.parent(),
2235					pt = parseInt( $pin.parent().css( 'padding-top' ) ), pb = parseInt( $pin.parent().css( 'padding-bottom' ) );
2236
2237				if ( options.autoInit ) {
2238					if ( $( '#header' ).hasClass( 'header-side' ) ) {
2239						pad.top = theme.adminBarHeight();
2240						/*if ($('.page-top.fixed-pos').length) {
2241							pad.top += $('.page-top.fixed-pos').height();
2242						}*/
2243					} else {
2244						pad.top = theme.adminBarHeight();
2245						if ( $( '#header > .main-menu-wrap' ).length || !$( '#header' ).hasClass( 'sticky-menu-header' ) ) {
2246							pad.top += theme.StickyHeader.sticky_height;
2247						}
2248					}
2249					if ( typeof options.paddingOffsetTop != 'undefined' ) {
2250						pad.top += parseInt( options.paddingOffsetTop, 10 );
2251					} else {
2252						pad.top += 18;
2253					}
2254					if ( typeof options.paddingOffsetBottom != 'undefined' ) {
2255						pad.bottom = parseInt( options.paddingOffsetBottom, 10 );
2256					} else {
2257						pad.bottom = 0;
2258					}
2259				}
2260
2261				var bb = $this.css( 'border-bottom' ), h = $this.outerHeight();
2262				$this.css( 'border-bottom', '1px solid transparent' );
2263				var o_h = $this.outerHeight() - h - 1;
2264				$this.css( 'border-bottom', bb );
2265				$this.css( { width: $this.outerWidth() <= $pin.width() ? $this.outerWidth() : $pin.width() } );
2266				$pin.css( "height", $this.outerHeight() + o_h );
2267
2268				if ( ( !options.autoFit && !options.fitToBottom ) || $this.outerHeight() <= $window.height() ) {
2269					$this.data( "themePin", {
2270						pad: pad,
2271						from: ( options.containerSelector ? containerOffset.top : offset.top ) - pad.top + pt,
2272						pb: pb,
2273						parentTop: parentOffset.top - pt,
2274						offset: o_h
2275					} );
2276				} else {
2277					$this.data( "themePin", {
2278						pad: pad,
2279						fromFitTop: ( options.containerSelector ? containerOffset.top : offset.top ) - pad.top + pt,
2280						from: ( options.containerSelector ? containerOffset.top : offset.top ) + $this.outerHeight() - window.innerHeight + pt,
2281						pb: pb,
2282						parentTop: parentOffset.top - pt,
2283						offset: o_h
2284					} );
2285				}
2286			}
2287		};
2288
2289		var onScroll = function() {
2290			if ( disabled ) { return; }
2291
2292			scrollY = $window.scrollTop();
2293
2294			var window_height = window.innerHeight || $window.height();
2295
2296			for ( var i = 0, len = elements.length; i < len; i++ ) {
2297				var $this = $( elements[i] ),
2298					data = $this.data( "themePin" ),
2299					sidebarTop;
2300
2301				let contentWrap = $this.closest( '.porto-products-filter-body' );
2302				let sidebarWrap = $this.closest( '.sidebar' );
2303				if ( contentWrap.length && sidebarWrap.length ) {
2304					if ( $.contains( contentWrap[0], sidebarWrap[0] ) && !contentWrap.hasClass( 'opened' ) ) {
2305						continue;
2306					}
2307				}
2308
2309				if ( !data || typeof data.pad == 'undefined' ) { // Removed element
2310					continue;
2311				}
2312
2313				var $container = options.containerSelector ? ( $this.closest( options.containerSelector ).length ? $this.closest( options.containerSelector ) : $( options.containerSelector ) ) : $( document.body ),
2314					isFitToTop = ( !options.autoFit && !options.fitToBottom ) || ( $this.outerHeight() + data.pad.top ) <= window_height;
2315				data.end = $container.offset().top + $container.height();
2316				if ( isFitToTop ) {
2317					data.to = $container.offset().top + $container.height() - $this.outerHeight() - data.pad.bottom - data.pb;
2318				} else {
2319					data.to = $container.offset().top + $container.height() - window_height - data.pb;
2320					data.to2 = $container.height() - $this.outerHeight() - data.pad.bottom - data.pb;
2321				}
2322
2323				if ( prevDataTo[i] === 0 ) {
2324					prevDataTo[i] = data.to;
2325				}
2326
2327				if ( isFitToTop ) {
2328					var from = data.from - data.pad.bottom,
2329						to = data.to - data.pad.top - data.offset,
2330						$parent = $this.closest( '.sticky-nav-wrapper' ),
2331						widgetTop;
2332
2333					// Sticky Navigation
2334					if ( $parent.length ) {
2335						widgetTop = $parent.offset().top - data.pad.top;
2336						if ( widgetTop > from ) {
2337							from = widgetTop;
2338						}
2339					}
2340
2341					if ( typeof data.fromFitTop != 'undefined' && data.fromFitTop ) {
2342						from = data.fromFitTop - data.pad.bottom;
2343					}
2344
2345					if ( from + $this.outerHeight() > data.end || from >= to ) {
2346						$this.css( { position: "", top: "", left: "" } );
2347						if ( options.activeClass ) { $this.removeClass( options.activeClass ); }
2348						$this.removeClass( 'sticky-transition' );
2349						$this.removeClass( 'sticky-absolute' );
2350						continue;
2351					}
2352					if ( scrollY > from && scrollY < to ) {
2353						!( $this.css( "position" ) == "fixed" ) && $this.css( {
2354							left: $this.offset().left,
2355							top: data.pad.top
2356						} ).css( "position", "fixed" );
2357						if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2358						$this.removeClass( 'sticky-transition' );
2359						$this.removeClass( 'sticky-absolute' );
2360					} else if ( scrollY >= to ) {
2361						$this.css( {
2362							left: "",
2363							top: to - data.parentTop + data.pad.top
2364						} ).css( "position", "absolute" );
2365						if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2366						if ( $this.hasClass( 'sticky-absolute' ) ) $this.addClass( 'sticky-transition' );
2367						$this.addClass( 'sticky-absolute' );
2368					} else {
2369						$this.css( { position: "", top: "", left: "" } );
2370						if ( options.activeClass ) { $this.removeClass( options.activeClass ); }
2371						$this.removeClass( 'sticky-transition' );
2372						$this.removeClass( 'sticky-absolute' );
2373					}
2374				} else if ( options.fitToBottom ) {
2375					var from = data.from,
2376						to = data.to;
2377					if ( data.from + window_height > data.end || data.from >= to ) {
2378						$this.css( { position: "", top: "", bottom: "", left: "" } );
2379						if ( options.activeClass ) { $this.removeClass( options.activeClass ); }
2380						$this.removeClass( 'sticky-transition' );
2381						$this.removeClass( 'sticky-absolute' );
2382						continue;
2383					}
2384					if ( scrollY > from && scrollY < to ) {
2385						!( $this.css( "position" ) == "fixed" ) && $this.css( {
2386							left: $this.offset().left,
2387							bottom: data.pad.bottom,
2388							top: ""
2389						} ).css( "position", "fixed" );
2390						if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2391						$this.removeClass( 'sticky-transition' );
2392						$this.removeClass( 'sticky-absolute' );
2393					} else if ( scrollY >= to ) {
2394						$this.css( {
2395							left: "",
2396							top: data.to2,
2397							bottom: ""
2398						} ).css( "position", "absolute" );
2399						if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2400						if ( $this.hasClass( 'sticky-absolute' ) ) $this.addClass( 'sticky-transition' );
2401						$this.addClass( 'sticky-absolute' );
2402					} else {
2403						$this.css( { position: "", top: "", bottom: "", left: "" } );
2404						if ( options.activeClass ) { $this.removeClass( options.activeClass ); }
2405						$this.removeClass( 'sticky-transition' );
2406						$this.removeClass( 'sticky-absolute' );
2407					}
2408				} else { // auto fit
2409					var this_height = $this.outerHeight()
2410					if ( prevDataTo[i] != data.to ) {
2411						if ( fixedSideBottom[i] && this_height + $this.offset().top + data.pad.bottom < scrollY + window_height ) {
2412							fixedSideBottom[i] = false;
2413						}
2414					}
2415					if ( ( this_height + data.pad.top + data.pad.bottom ) > window_height || fixedSideTop[i] || fixedSideBottom[i] ) {
2416						var padTop = parseInt( $this.parent().parent().css( 'padding-top' ) );
2417						// Reset the sideSortables style when scrolling to the top.
2418						if ( scrollY + data.pad.top - padTop <= data.parentTop ) {
2419							$this.css( { position: "", top: "", bottom: "", left: "" } );
2420							fixedSideTop[i] = fixedSideBottom[i] = false;
2421							if ( options.activeClass ) { $this.removeClass( options.activeClass ); }
2422						} else if ( scrollY >= data.to ) {
2423							$this.css( {
2424								left: "",
2425								top: data.to2,
2426								bottom: ""
2427							} ).css( "position", "absolute" );
2428							if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2429						} else {
2430
2431							// When scrolling down.
2432							if ( scrollY >= lastScrollY ) {
2433								if ( fixedSideTop[i] ) {
2434
2435									// Let it scroll.
2436									fixedSideTop[i] = false;
2437									sidebarTop = $this.offset().top - data.parentTop;
2438
2439									$this.css( {
2440										left: "",
2441										top: sidebarTop,
2442										bottom: ""
2443									} ).css( "position", "absolute" );
2444									if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2445								} else if ( !fixedSideBottom[i] && this_height + $this.offset().top + data.pad.bottom < scrollY + window_height ) {
2446									// Pin the bottom.
2447									fixedSideBottom[i] = true;
2448
2449									!( $this.css( "position" ) == "fixed" ) && $this.css( {
2450										left: $this.offset().left,
2451										bottom: data.pad.bottom,
2452										top: ""
2453									} ).css( "position", "fixed" );
2454									if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2455								}
2456
2457								// When scrolling up.
2458							} else if ( scrollY < lastScrollY ) {
2459								if ( fixedSideBottom[i] ) {
2460									// Let it scroll.
2461									fixedSideBottom[i] = false;
2462									sidebarTop = $this.offset().top - data.parentTop;
2463
2464									/*if ($this.css('position') == 'absolute' && sidebarTop > data.to2) {
2465										sidebarTop = data.to2;
2466									}*/
2467									$this.css( {
2468										left: "",
2469										top: sidebarTop,
2470										bottom: ""
2471									} ).css( "position", "absolute" );
2472									if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2473								} else if ( !fixedSideTop[i] && $this.offset().top >= scrollY + data.pad.top ) {
2474									// Pin the top.
2475									fixedSideTop[i] = true;
2476
2477									!( $this.css( "position" ) == "fixed" ) && $this.css( {
2478										left: $this.offset().left,
2479										top: data.pad.top,
2480										bottom: ''
2481									} ).css( "position", "fixed" );
2482									if ( options.activeClass ) { $this.addClass( options.activeClass ); }
2483								} else if ( !fixedSideBottom[i] && fixedSideTop[i] && $this.css( 'position' ) == 'absolute' && $this.offset().top >= scrollY + data.pad.top ) {
2484									fixedSideTop[i] = false;
2485								}
2486							}
2487						}
2488					} else {
2489						// If the sidebar container is smaller than the viewport, then pin/unpin the top when scrolling.
2490						if ( scrollY >= ( data.parentTop - data.pad.top ) ) {
2491							$this.css( {
2492								position: 'fixed',
2493								top: data.pad.top
2494							} );
2495						} else {
2496							$this.css( { position: "", top: "", bottom: "", left: "" } );
2497							if ( options.activeClass ) { $this.removeClass( options.activeClass ); }
2498						}
2499
2500						fixedSideTop[i] = fixedSideBottom[i] = false;
2501					}
2502				}
2503
2504				prevDataTo[i] = data.to;
2505			}
2506
2507			lastScrollY = scrollY;
2508		};
2509
2510		var update = function() { recalculateLimits(); onScroll(); },
2511			r_timer = null;
2512
2513		this.each( function() {
2514			var $this = $( this ),
2515				data = $this.data( 'themePin' ) || {};
2516
2517			if ( data && data.update ) { return; }
2518			elements.push( $this );
2519			$( "img", this ).one( "load", function() {
2520				if ( r_timer ) {
2521					theme.deleteTimeout( r_timer );
2522				}
2523				r_timer = theme.requestFrame( recalculateLimits );
2524			} );
2525			data.update = update;
2526			$this.data( 'themePin', data );
2527			fixedSideTop.push( false );
2528			fixedSideBottom.push( false );
2529			prevDataTo.push( 0 );
2530		} );
2531
2532		//$window.on( 'touchmove', onScroll );
2533		window.addEventListener( 'touchmove', onScroll, { passive: true } );
2534		window.addEventListener( 'scroll', onScroll, { passive: true } );
2535		recalculateLimits();
2536
2537		if ( !theme.isLoaded ) {
2538			$window.on( 'load', update );
2539		} else {
2540			update();
2541		}
2542
2543		$( this ).on( 'recalc.pin', function() {
2544			recalculateLimits();
2545			onScroll();
2546		} );
2547
2548		return this;
2549	};
2550
2551	theme = theme || {};
2552
2553	var instanceName = '__sticky';
2554
2555	var Sticky = function( $el, opts ) {
2556		return this.initialize( $el, opts );
2557	};
2558
2559	Sticky.defaults = {
2560		autoInit: false,
2561		minWidth: 767,
2562		activeClass: 'sticky-active',
2563		padding: {
2564			top: 0,
2565			bottom: 0
2566		},
2567		offsetTop: 0,
2568		offsetBottom: 0,
2569		autoFit: false,
2570		fitToBottom: false
2571	};
2572
2573	Sticky.prototype = {
2574		initialize: function( $el, opts ) {
2575			if ( $el.data( instanceName ) ) {
2576				return this;
2577			}
2578
2579			this.$el = $el;
2580
2581			this
2582				.setData()
2583				.setOptions( opts )
2584				.build();
2585
2586			return this;
2587		},
2588
2589		setData: function() {
2590			this.$el.data( instanceName, this );
2591
2592			return this;
2593		},
2594
2595		setOptions: function( opts ) {
2596			this.options = $.extend( true, {}, Sticky.defaults, opts, {
2597				wrapper: this.$el
2598			} );
2599
2600			return this;
2601		},
2602
2603		build: function() {
2604			if ( !$.fn.themePin ) {
2605				return this;
2606			}
2607
2608			var self = this,
2609				$el = this.options.wrapper,
2610				stickyResizeTrigger;
2611
2612			if ( $el.hasClass( 'porto-sticky-nav' ) ) {
2613				this.options.padding.top = theme.StickyHeader.sticky_height + theme.adminBarHeight();
2614				this.options.activeClass = 'sticky-active';
2615				this.options.containerSelector = '.main-content-wrap';
2616				theme.sticky_nav_height = $el.outerHeight();
2617				if ( this.options.minWidth > window.innerWidth )
2618					theme.sticky_nav_height = 0;
2619			}
2620
2621			$el.themePin( this.options );
2622
2623			$( window ).smartresize( function() {
2624				if ( stickyResizeTrigger ) {
2625					clearTimeout( stickyResizeTrigger );
2626				}
2627				stickyResizeTrigger = setTimeout( function() {
2628					$el.trigger( 'recalc.pin' );
2629				}, 800 );
2630
2631				var $parent = $el.parent();
2632
2633				$el.outerWidth( $parent.width() );
2634				if ( $el.css( 'position' ) == 'fixed' ) {
2635					$el.css( 'left', $parent.offset().left );
2636				}
2637
2638				if ( $el.hasClass( 'porto-sticky-nav' ) ) {
2639					theme.sticky_nav_height = $el.outerHeight();
2640					if ( self.options.minWidth > window.innerWidth )
2641						theme.sticky_nav_height = 0;
2642				}
2643			} );
2644
2645			return this;
2646		}
2647	};
2648
2649	// expose to scope
2650	$.extend( theme, {
2651		Sticky: Sticky
2652	} );
2653
2654	// jquery plugin
2655	$.fn.themeSticky = function( opts ) {
2656		return this.map( function() {
2657			var $this = $( this );
2658			if ( $this.data( instanceName ) ) {
2659				$this.trigger( 'recalc.pin' );
2660				setTimeout( function() {
2661					$this.trigger( 'recalc.pin' );
2662				}, 800 );
2663
2664				return $this.data( instanceName );
2665			} else {
2666				return new theme.Sticky( $this, opts );
2667			}
2668
2669		} );
2670	}
2671
2672} ).apply( this, [window.theme, jQuery] );
2673
2674
2675// Mobile Panel
2676( function( theme, $ ) {
2677	'use strict';
2678
2679	$( function() {
2680		$( document.body ).on( 'click', '.mobile-toggle', function( e ) {
2681			var $nav_panel = $( '#nav-panel' );
2682			if ( $nav_panel.length > 0 ) {
2683				if ( $( this ).closest( '.header-main' ).length && $nav_panel.closest( '.header-builder-p' ).length && !$nav_panel.parent( '.header-main' ).length ) {
2684					$nav_panel.appendTo( $( this ).closest( '.header-main' ) );
2685				} else if ( $( this ).closest( '.header-main' ).length && $nav_panel.closest( '.wp-block-template-part' ).length ) {
2686					$nav_panel.insertAfter( $( this ).closest( '.header-main' ) );
2687				}
2688
2689				if ( $nav_panel.is( ':visible' ) && $( '#header' ).hasClass( 'sticky-header' ) ) {
2690					var h_h = $( '#header' ).height(), p_h = $nav_panel.outerHeight();
2691					if ( h_h > p_h + 30 ) {
2692						$( '#header' ).css( 'height', h_h - p_h );
2693					}
2694				}
2695				$nav_panel.stop().slideToggle();
2696			} else if ( $( '#side-nav-panel' ).length > 0 ) {
2697				$( 'html' ).toggleClass( 'panel-opened' );
2698				$( '.panel-overlay' ).toggleClass( 'active' );
2699			}
2700			if ( $( '#nav-panel .skeleton-body, #side-nav-panel .skeleton-body' ).length ) {
2701				theme.lazyload_menu( 1, 'mobile_menu' );
2702			}
2703			e.preventDefault();
2704		} );
2705
2706		$( document.body ).on( 'click', '.panel-overlay', function() {
2707			$( 'html' ).css( 'transition', 'margin .3s' ).removeClass( 'panel-opened' );
2708			theme.requestTimeout( function() {
2709				$( 'html' ).css( 'transition', '' );
2710			}, 260 );
2711			$( this ).removeClass( 'active' );
2712		} );
2713
2714		$( document.body ).on( 'click', '#side-nav-panel .side-nav-panel-close', function( e ) {
2715			e.preventDefault();
2716			$( '.panel-overlay' ).trigger( 'click' );
2717		} );
2718
2719		$( document.body ).on( 'click', '#side-nav-panel .mobile-tab-items .nav-item', function( e ) {
2720			e.preventDefault();
2721			var $this = $( this ),
2722				$id = $this.attr('pane-id'),
2723				$parent = $this.closest('.mobile-tabs');
2724			
2725			if ( $id ) {
2726				$parent.find('.active').removeClass( 'active' );
2727				$this.addClass('active');
2728				$parent.find('.mobile-tab-content [tab-id="' + $id + '"]').addClass( 'active' );
2729			}
2730		} );
2731
2732		$( window ).on( 'resize', function() {
2733			if ( window.innerWidth > 991 ) {
2734				$( '#nav-panel' ).hide();
2735				if ( $( 'html' ).hasClass( 'panel-opened' ) ) {
2736					$( '.panel-overlay' ).trigger( 'click' );
2737				}
2738			}
2739		} );
2740	} );
2741
2742} ).apply( this, [window.theme, jQuery] );
2743
2744
2745// Blog / Portfolio Like
2746( function( theme, $ ) {
2747	'use strict';
2748
2749	$( function() {
2750		$( document ).on( 'click', '.blog-like, .portfolio-like', function( e ) {
2751			e.preventDefault();
2752			var $this = $( this ),
2753				parentObj = this.parentNode,
2754				item_id = $this.attr( 'data-id' ),
2755				is_blog = $this.hasClass( 'blog-like' ),
2756				sendData = { nonce: js_porto_vars.porto_nonce };
2757			if ( is_blog ) {
2758				if ( $this.hasClass( 'updating' ) ) {
2759					return false;
2760				}
2761				$this.addClass( 'updating' ).text( '...' );
2762				sendData.blog_id = item_id;
2763				sendData.action = 'porto_blog-like';
2764			} else {
2765				sendData.portfolio_id = item_id;
2766				sendData.action = 'porto_portfolio-like';
2767			}
2768			$.post(
2769				theme.ajax_url,
2770				sendData,
2771				function( data ) {
2772					if ( data ) {
2773						$this.remove();
2774						parentObj.innerHTML = data;
2775						if ( typeof bootstrap != 'undefined' ) {
2776							var tooltipTriggerList = [].slice.call( parentObj.querySelectorAll( '[data-bs-tooltip]' ) );
2777							tooltipTriggerList.map( function( tooltipTriggerEl ) {
2778								return new bootstrap.Tooltip( tooltipTriggerEl )
2779							} );
2780						}
2781					}
2782				}
2783			);
2784			return false;
2785		} );
2786	} );
2787
2788} ).apply( this, [window.theme, jQuery] );
2789
2790// Scroll to Top
2791
2792//** jQuery Scroll to Top Control script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com.
2793//** Available/ usage terms at http://www.dynamicdrive.com (March 30th, 09')
2794//** v1.1 (April 7th, 09'):
2795//** 1) Adds ability to scroll to an absolute position (from top of page) or specific element on the page instead.
2796//** 2) Fixes scroll animation not working in Opera. 
2797
2798
2799var scrolltotop = {
2800	//startline: Integer. Number of pixels from top of doc scrollbar is scrolled before showing control
2801	//scrollto: Keyword (Integer, or "Scroll_to_Element_ID"). How far to scroll document up when control is clicked on (0=top).
2802	setting: { startline: 100, scrollto: 0, scrollduration: 1000, fadeduration: [500, 100] },
2803	controlHTML: '<img src="assets/img/up.png" style="width:40px; height:40px" />
2803', //HTML for control, which is auto wrapped in DIV w/ ID="topcontrol"
2804	controlattrs: { offsetx: 10, offsety: 10 }, //offset of control relative to right/ bottom of window corner
2805	anchorkeyword: '#top', //Enter href value of HTML anchors on the page that should also act as "Scroll Up" links
2806
2807	state: { isvisible: false, shouldvisible: false },
2808
2809	scrollup: function() {
2810		if ( !this.cssfixedsupport ) //if control is positioned using JavaScript
2811			this.$control.css( { opacity: 0 } ); //hide control immediately after clicking it
2812		var dest = isNaN( this.setting.scrollto ) ? this.setting.scrollto : parseInt( this.setting.scrollto );
2813		if ( typeof dest == "string" && jQuery( '#' + dest ).length == 1 ) //check element set by string exists
2814			dest = jQuery( '#' + dest ).offset().top;
2815		else
2816			dest = 0;
2817		this.$body.stop().animate( { scrollTop: dest }, this.setting.scrollduration );
2818	},
2819
2820	keepfixed: function() {
2821		var $window = jQuery( window );
2822		var controlx = $window.scrollLeft() + $window.width() - this.$control.width() - this.controlattrs.offsetx;
2823		var controly = $window.scrollTop() + $window.height() - this.$control.height() - this.controlattrs.offsety;
2824		this.$control.css( { left: controlx + 'px', top: controly + 'px' } );
2825	},
2826
2827	togglecontrol: function() {
2828		var scrolltop = jQuery( window ).scrollTop();
2829		if ( !this.cssfixedsupport )
2830			this.keepfixed();
2831		this.state.shouldvisible = ( scrolltop >= this.setting.startline ) ? true : false;
2832		if ( this.state.shouldvisible && !this.state.isvisible ) {
2833			this.$control.stop().animate( { opacity: 1 }, this.setting.fadeduration[0] );
2834			this.state.isvisible = true;
2835		}
2836		else if ( this.state.shouldvisible == false && this.state.isvisible ) {
2837			this.$control.stop().animate( { opacity: 0 }, this.setting.fadeduration[1] );
2838			this.state.isvisible = false;
2839		}
2840	},
2841
2842	init: function() {
2843		jQuery( document ).ready( function( $ ) {
2844			var mainobj = scrolltotop;
2845			var iebrws = document.all;
2846			mainobj.cssfixedsupport = !iebrws || iebrws && document.compatMode == "CSS1Compat" && window.XMLHttpRequest //not IE or IE7+ browsers in standards mode
2847			mainobj.$body = ( window.opera ) ? ( document.compatMode == "CSS1Compat" ? $( 'html' ) : $( 'body' ) ) : $( 'html,body' );
2848			mainobj.$control = $( '<div id="topcontrol">' + mainobj.controlHTML + '</div>' )
2849				.css( { position: mainobj.cssfixedsupport ? 'fixed' : 'absolute', bottom: mainobj.controlattrs.offsety, opacity: 0, cursor: 'pointer' } )
2850				.attr( { title: '' } )
2851				.on( 'click', function() { mainobj.scrollup(); return false; } )
2852				.appendTo( 'body' );
2853			if ( document.all && !window.XMLHttpRequest && mainobj.$control.text() != '' ) //loose check for IE6 and below, plus whether control contains any text
2854				mainobj.$control.css( { width: mainobj.$control.width() } ); //IE6- seems to require an explicit width on a DIV containing text
2855			mainobj.togglecontrol();
2856			$( 'a[href="' + mainobj.anchorkeyword + '"]' ).on( 'click', function() {
2857				mainobj.scrollup();
2858				return false;
2859			} );
2860			$( window ).on( 'scroll resize', function( e ) {
2861				mainobj.togglecontrol();
2862			} );
2863		} );
2864	}
2865};
2866
2867//scrolltotop.init()
2868
2869( function( theme, $ ) {
2870	'use strict';
2871	theme = theme || {};
2872
2873	$.extend( theme, {
2874
2875		ScrollToTop: {
2876
2877			defaults: {
2878				html: '<i class="fas fa-chevron-up"></i>',
2879				offsetx: 10,
2880				offsety: 0
2881			},
2882
2883			initialize: function( html, offsetx, offsety ) {
2884				if ( $( '#topcontrol' ).length ) {
2885					return this;
2886				}
2887				this.html = ( html || this.defaults.html );
2888				this.offsetx = ( offsetx || this.defaults.offsetx );
2889				this.offsety = ( offsety || this.defaults.offsety );
2890
2891				this.build();
2892
2893				return this;
2894			},
2895
2896			build: function() {
2897				var self = this;
2898
2899				if ( typeof scrolltotop !== 'undefined' ) {
2900					// scroll top control
2901					scrolltotop.controlHTML = self.html;
2902					scrolltotop.controlattrs = { offsetx: self.offsetx, offsety: self.offsety };
2903					scrolltotop.init();
2904				}
2905
2906				return self;
2907			}
2908		}
2909
2910	} );
2911
2912} ).apply( this, [window.theme, jQuery] );
2913
2914
2915// Mega Menu
2916( function( theme, $ ) {
2917	'use strict';
2918
2919	theme = theme || {};
2920
2921	$.extend( theme, {
2922
2923		MegaMenu: {
2924
2925			defaults: {
2926				menu: $( '.mega-menu' )
2927			},
2928
2929			initialize: function( $menu ) {
2930				this.$menu = ( $menu || this.defaults.menu );
2931
2932				this.build()
2933					.events();
2934
2935				return this;
2936			},
2937
2938			popupWidth: function() {
2939				var winWidth = window.innerWidth,
2940					popupWidth = theme.bodyWidth - theme.grid_gutter_width * 2;
2941				if ( !$( 'body' ).hasClass( 'wide' ) ) {
2942					if ( winWidth >= theme.container_width + theme.grid_gutter_width - 1 )
2943						popupWidth = theme.container_width - theme.grid_gutter_width;
2944					else if ( winWidth >= 992 )
2945						popupWidth = 960 - theme.grid_gutter_width;
2946					else if ( winWidth >= 768 )
2947						popupWidth = 720 - theme.grid_gutter_width;
2948				}
2949				return popupWidth;
2950			},
2951
2952			calcMenuPosition: function( menu_obj ) {
2953				var menu = menu_obj,
2954					$header_container = $( '#header .header-main' ).hasClass( 'elementor-section' ) ? $( '#header .header-main > .elementor-container' ) : ( $( "#header .header-main .container-fluid" ).length ? $( "#header .header-main .container-fluid" ) : ( $( "#header .header-main .container" ).length ? $( "#header .header-main .container" ) : null ) );
2955				if ( null === $header_container || !$header_container.length ) {
2956					return;
2957				}
2958				var menuContainerWidth = $header_container.outerWidth() - parseInt( $header_container.css( 'padding-left' ) ) - parseInt( $header_container.css( 'padding-right' ) );
2959				if ( menuContainerWidth < 900 ) return;
2960				if ( menu.parent().hasClass( 'pos-fullwidth' ) ) {
2961					menu.get( 0 ).style.width = menuContainerWidth + 'px';
2962				}
2963				var browserWidth = theme.bodyWidth,
2964					menuLeftPos = menu.offset().left - ( browserWidth - menuContainerWidth ) / 2;
2965				if ( window.theme.rtl ) {
2966					menuLeftPos = theme.bodyWidth - ( menu.offset().left + menu.outerWidth() ) - ( browserWidth - menuContainerWidth ) / 2;
2967				}
2968				var menuWidth = menu.width(),
2969					remainWidth = menuContainerWidth - ( menuLeftPos + menuWidth ),
2970					l = false;
2971				if ( menuLeftPos > remainWidth && menuLeftPos < menuWidth ) {
2972					l = ( menuLeftPos + remainWidth ) / 3;
2973				}
2974				if ( remainWidth < 0 ) {
2975					l = -remainWidth;
2976				}
2977				return l;
2978			},
2979
2980			build: function( $menu ) {
2981				var self = this;
2982				if ( !$menu ) {
2983					$menu = self.$menu;
2984				}
2985
2986				$menu.each( function() {
2987					var $menu = $( this ),
2988						$menu_container = $menu.closest( '.container' ),
2989						container_width = self.popupWidth();
2990					if ( $menu.closest( '.porto-popup-menu' ).length ) {
2991						return false;
2992					}
2993
2994					var $menu_items = $menu.children( 'li.has-sub' );
2995
2996					$menu_items.each( function() {
2997						var $menu_item = $( this ),
2998							$popup = $menu_item.children( '.popup' );
2999						if ( $popup.length ) {
3000							var popup_obj = $popup.get( 0 );
3001							popup_obj.style.display = 'block';
3002							if ( $menu_item.hasClass( 'wide' ) ) {
3003								popup_obj.style.left = 0;
3004								var padding = parseInt( $popup.css( 'padding-left' ) ) + parseInt( $popup.css( 'padding-right' ) ) +
3005									parseInt( $popup.find( '> .inner' ).css( 'padding-left' ) ) + parseInt( $popup.find( '> .inner' ).css( 'padding-right' ) );
3006
3007								var row_number = 4;
3008
3009								if ( $menu_item.hasClass( 'col-2' ) ) row_number = 2;
3010								if ( $menu_item.hasClass( 'col-3' ) ) row_number = 3;
3011								if ( $menu_item.hasClass( 'col-4' ) ) row_number = 4;
3012								if ( $menu_item.hasClass( 'col-5' ) ) row_number = 5;
3013								if ( $menu_item.hasClass( 'col-6' ) ) row_number = 6;
3014
3015								if ( window.innerWidth < 992 )
3016									row_number = 1;
3017
3018								var col_length = 0;
3019								$popup.find( '> .inner > ul > li' ).each( function() {
3020									var cols = parseFloat( $( this ).attr( 'data-cols' ) );
3021									if ( cols <= 0 || !cols )
3022										cols = 1;
3023
3024									if ( cols > row_number )
3025										cols = row_number;
3026
3027									col_length += cols;
3028								} );
3029
3030								if ( col_length > row_number ) col_length = row_number;
3031
3032								var popup_max_width = $popup.data( 'popup-mw' ) ? $popup.data( 'popup-mw' ) : $popup.find( '.inner' ).css( 'max-width' ),
3033									col_width = container_width / row_number;
3034								if ( 'none' !== popup_max_width && popup_max_width < container_width ) {
3035									col_width = parseInt( popup_max_width ) / row_number;
3036								}
3037
3038								$popup.find( '> .inner > ul > li' ).each( function() {
3039									var cols = parseFloat( $( this ).data( 'cols' ) );
3040									if ( cols <= 0 )
3041										cols = 1;
3042
3043									if ( cols > row_number )
3044										cols = row_number;
3045
3046									if ( $menu_item.hasClass( 'pos-center' ) || $menu_item.hasClass( 'pos-left' ) || $menu_item.hasClass( 'pos-right' ) )
3047										this.style.width = ( 100 / col_length * cols ) + '%';
3048									else
3049										this.style.width = ( 100 / row_number * cols ) + '%';
3050								} );
3051
3052								if ( $menu_item.hasClass( 'pos-center' ) ) { // position center
3053									$popup.find( '> .inner > ul' ).get( 0 ).style.width = ( col_width * col_length - padding ) + 'px';
3054									var left_position = $popup.offset().left - ( theme.bodyWidth - col_width * col_length ) / 2;
3055									popup_obj.style.left = '-' + left_position + 'px';
3056								} else if ( $menu_item.hasClass( 'pos-left' ) ) { // position left
3057									$popup.find( '> .inner > ul' ).get( 0 ).style.width = ( col_width * col_length - padding ) + 'px';
3058									popup_obj.style.left = '-15px';
3059								} else if ( $menu_item.hasClass( 'pos-right' ) ) { // position right
3060									$popup.find( '> .inner > ul' ).get( 0 ).style.width = ( col_width * col_length - padding ) + 'px';
3061									popup_obj.style.right = '-15px';
3062									popup_obj.style.left = 'auto';
3063								} else { // position justify
3064									if ( !$menu_item.hasClass( 'pos-fullwidth' ) ) {
3065										$popup.find( '> .inner > ul' ).get( 0 ).style.width = ( container_width - padding ) + 'px';
3066									}
3067									if ( theme.rtl ) {
3068										popup_obj.style.right = 0;
3069										popup_obj.style.left = 'auto';
3070									}
3071									setTimeout( () => {
3072										var left_position = self.calcMenuPosition( $popup );
3073										if ( theme.rtl ) {
3074											popup_obj.style.right = '-15px';
3075											popup_obj.style.left = 'auto';
3076											if ( left_position ) {
3077												popup_obj.style.right = '-' + left_position + 'px';
3078											}
3079										} else {
3080											popup_obj.style.left = '-15px';
3081											popup_obj.style.right = 'auto';
3082											if ( left_position ) {
3083												popup_obj.style.left = '-' + left_position + 'px';
3084											}
3085										}
3086									} );
3087
3088								}
3089							} else { // auto position
3090								if ( $menu_item.hasClass( 'pos-center' ) ) { // position center
3091
3092								} else if ( $menu_item.hasClass( 'pos-left' ) ) { // position left
3093
3094								} else if ( $menu_item.hasClass( 'pos-right' ) ) { // position right
3095
3096								} else { // position justify
3097									if ( $popup.offset().left + $popup.width() > window.innerWidth ) {
3098										$menu_item.addClass( 'pos-right' );
3099									} else if ( $popup.find( '> .inner > ul' ).length ) {
3100										var $sub_menu = $popup.find( '> .inner > ul' ).eq( 0 );
3101										if ( $sub_menu.offset().left + $sub_menu.width() + 200 > window.innerWidth ) {
3102											$sub_menu.addClass( 'pos-left' );
3103										}
3104									}
3105								}
3106							}
3107							$menu_item.addClass( 'sub-ready' );
3108						}
3109					} );
3110				} );
3111
3112				return self;
3113			},
3114
3115			events: function() {
3116				var self = this;
3117
3118				$( window ).smartresize( function() {
3119					self.build();
3120				} );
3121
3122				if ( theme.isLoaded ) {
3123					theme.requestFrame( function() {
3124						self.build();
3125					} );
3126				} else {
3127					$( window ).on( 'load', function() {
3128						theme.requestFrame( function() {
3129							self.build();
3130						} );
3131					} );
3132				}
3133
3134				return self;
3135			}
3136		}
3137
3138	} );
3139
3140} ).apply( this, [window.theme, jQuery] );
3141
3142
3143// Sidebar Menu
3144( function( theme, $ ) {
3145	'use strict';
3146
3147	theme = theme || {};
3148
3149	$.extend( theme, {
3150
3151		SidebarMenu: {
3152
3153			defaults: {
3154				menu: $( '.sidebar-menu:not(.side-menu-accordion)' ),
3155				toggle: $( '.widget_sidebar_menu .widget-title .toggle' ),
3156				menu_toggle: $( '#main-toggle-menu .menu-title' )
3157			},
3158
3159			rtl: theme.rtl,
3160
3161			initialize: function( $menu, $toggle, $menu_toggle ) {
3162				if ( this.$menu && this.$menu.length && $menu && $menu.length ) {
3163					this.$menu = $.uniqueSort( $.merge( this.$menu, $menu ) );
3164					this.build();
3165					return this;
3166				}
3167				this.$menu = ( $menu || this.defaults.menu );
3168				if ( !this.$menu.length ) {
3169					return this;
3170				}
3171				this.$toggle = ( $toggle || this.defaults.toggle );
3172				this.$menu_toggle = ( $menu_toggle || this.defaults.menu_toggle );
3173
3174				this.build()
3175					.events();
3176
3177				return this;
3178			},
3179
3180			isRightSidebar: function( $menu ) {
3181				var flag = false;
3182				if ( this.rtl ) {
3183					flag = !( $( '#main' ).hasClass( 'column2-right-sidebar' ) || $( '#main' ).hasClass( 'column2-wide-right-sidebar' ) );
3184				} else {
3185					flag = $( '#main' ).hasClass( 'column2-right-sidebar' ) || $( '#main' ).hasClass( 'column2-wide-right-sidebar' );
3186				}
3187
3188				if ( $menu.closest( '#main-toggle-menu' ).length ) {
3189					if ( this.rtl ) {
3190						flag = true;
3191					} else {
3192						flag = false;
3193					}
3194				}
3195
3196				var $header_wrapper = $menu.closest( '.header-wrapper' );
3197				if ( $header_wrapper.length && $header_wrapper.hasClass( 'header-side-nav' ) ) {
3198					if ( this.rtl ) {
3199						flag = true;
3200					} else {
3201						flag = false;
3202					}
3203					if ( $( '.page-wrapper' ).hasClass( 'side-nav-right' ) ) {
3204						if ( this.rtl ) {
3205							flag = false;
3206						} else {
3207							flag = true;
3208						}
3209					}
3210				}
3211
3212				return flag;
3213			},
3214
3215			popupWidth: function() {
3216				var winWidth = window.innerWidth,
3217					popupWidth = theme.bodyWidth - theme.grid_gutter_width * 2;
3218				if ( !$( 'body' ).hasClass( 'wide' ) ) {
3219					if ( winWidth >= theme.container_width + theme.grid_gutter_width - 1 )
3220						popupWidth = theme.container_width - theme.grid_gutter_width;
3221					else if ( winWidth >= 992 )
3222						popupWidth = 960 - theme.grid_gutter_width;
3223					else if ( winWidth >= 768 )
3224						popupWidth = 720 - theme.grid_gutter_width;
3225				}
3226				return popupWidth;
3227			},
3228
3229			build: function( $menus ) {
3230				var self = this;
3231				if ( !$menus ) {
3232					$menus = self.$menu;
3233				}
3234				if ( !$menus.length ) {
3235					return;
3236				}
3237
3238				var $parent_toggle_wrap = $menus.parent( '.toggle-menu-wrap' ),
3239					parent_toogle_wrap = null;
3240				if ( $parent_toggle_wrap.length && $parent_toggle_wrap.is( ':hidden' ) ) {
3241					parent_toogle_wrap = $parent_toggle_wrap.get( 0 );
3242					parent_toogle_wrap.style.display = 'block';
3243					parent_toogle_wrap.style.visibility = 'hidden';
3244				}
3245
3246				$menus.each( function() {
3247					var menuobj = this, $menu = $( this ), container_width;
3248					if ( menuobj.classList.contains( 'side-menu-slide' ) ) {
3249						return;
3250					}
3251					if ( window.innerWidth < 992 )
3252						container_width = self.popupWidth();
3253					else {
3254						var menu_width = this.offsetWidth ? this.offsetWidth : $menu.width();
3255						container_width = self.popupWidth() - menu_width - 45;
3256					}
3257
3258					var is_right_sidebar = self.isRightSidebar( $menu ),
3259						$menu_items = $menu.children( 'li' );
3260
3261					$menu_items.each( function() {
3262						var $menu_item = $( this ),
3263							$popup = $menu_item.children( '.popup' );
3264
3265						if ( $popup.length ) {
3266							var popup_obj = $popup.get( 0 ),
3267								is_opened = false;
3268							if ( $popup.is( ':visible' ) ) {
3269								is_opened = true;
3270							} else {
3271								popup_obj.style.display = 'block';
3272							}
3273							if ( $menu_item.hasClass( 'wide' ) ) {
3274								if ( !$menu.hasClass( 'side-menu-columns' ) ) {
3275									popup_obj.style.left = 0;
3276								}
3277								var row_number = 4;
3278
3279								if ( $menu_item.hasClass( 'col-2' ) ) row_number = 2;
3280								if ( $menu_item.hasClass( 'col-3' ) ) row_number = 3;
3281								if ( $menu_item.hasClass( 'col-4' ) ) row_number = 4;
3282								if ( $menu_item.hasClass( 'col-5' ) ) row_number = 5;
3283								if ( $menu_item.hasClass( 'col-6' ) ) row_number = 6;
3284
3285								if ( window.innerWidth < 992 )
3286									row_number = 1;
3287
3288								var col_length = 0;
3289								$popup.find( '> .inner > ul > li' ).each( function() {
3290									var cols = parseFloat( $( this ).data( 'cols' ) );
3291									if ( !cols || cols <= 0 )
3292										cols = 1;
3293
3294									if ( cols > row_number )
3295										cols = row_number;
3296
3297									col_length += cols;
3298								} );
3299
3300								if ( col_length > row_number ) col_length = row_number;
3301
3302								var popup_max_width = $popup.data( 'popup-mw' ) ? $popup.data( 'popup-mw' ) : $popup.find( '.inner' ).css( 'max-width' ),
3303									col_width = container_width / row_number;
3304								if ( 'none' !== popup_max_width && popup_max_width < container_width ) {
3305									col_width = parseInt( popup_max_width ) / row_number;
3306								}
3307
3308								$popup.find( '> .inner > ul > li' ).each( function() {
3309									var cols = parseFloat( $( this ).data( 'cols' ) );
3310									if ( cols <= 0 )
3311										cols = 1;
3312
3313									if ( cols > row_number )
3314										cols = row_number;
3315
3316									if ( $menu_item.hasClass( 'pos-center' ) || $menu_item.hasClass( 'pos-left' ) || $menu_item.hasClass( 'pos-right' ) )
3317										this.style.width = ( 100 / col_length * cols ) + '%';
3318									else
3319										this.style.width = ( 100 / row_number * cols ) + '%';
3320								} );
3321
3322								popup_obj.children[0].children[0].style.width = col_width * col_length + 1 + 'px';
3323
3324								if ( !$menu.hasClass( 'side-menu-columns' ) ) {
3325									if ( is_right_sidebar ) {
3326										popup_obj.style.left = 'auto';
3327										popup_obj.style.right = ( this.offsetWidth ? this.offsetWidth : $( this ).width() ) + 'px';
3328									} else {
3329										popup_obj.style.left = ( this.offsetWidth ? this.offsetWidth : $( this ).width() ) + 'px';
3330										popup_obj.style.right = 'auto';
3331									}
3332								}
3333							}
3334
3335							if ( !is_opened ) {
3336								popup_obj.style.display = 'none';
3337							}
3338							if ( menuobj.classList.contains( 'side-menu-accordion' ) ) {
3339
3340							} else if ( menuobj.classList.contains( 'side-menu-slide' ) ) {
3341
3342							} else if ( !$menu_item.hasClass( 'sub-ready' ) ) {
3343								if ( !( 'ontouchstart' in document ) && window.innerWidth > 991 ) {
3344									$menu_item.on( 'mouseenter', function() {
3345										$menu_items.find( '.popup' ).hide();
3346										$popup.show();
3347										$popup.parent().addClass( 'open' );
3348										//$( document.body ).trigger( 'appear_refresh' );
3349									} ).on( 'mouseleave', function() {
3350										$popup.hide();
3351										$popup.parent().removeClass( 'open' );
3352									} );
3353								} else {
3354									$menu_item.on( 'click', '.arrow', function() {
3355										$popup.slideToggle();
3356										$popup.parent().toggleClass( 'open' );
3357										//$( document.body ).trigger( 'appear_refresh' );
3358									} );
3359								}
3360								$menu_item.addClass( 'sub-ready' );
3361							}
3362						}
3363					} );
3364				} );
3365
3366				// slide menu
3367				if ( $menus.hasClass( 'side-menu-slide' ) ) {
3368					var slideNavigation = {
3369						$mainNav: $menus,
3370						$mainNavItem: $menus.find( 'li' ),
3371
3372						build: function() {
3373							var self = this;
3374
3375							self.menuNav();
3376						},
3377						initSub: function( $obj ) {
3378							var currentMenu = $obj.closest( 'ul' ),
3379								nextMenu = $obj.parent().find( 'ul' ).first();
3380
3381							if ( nextMenu.children( '.menu-item' ).children( '.go-back' ).length < 1 ) {
3382								nextMenu.prepend( '<li class="menu-item"><a class="go-back" href="#">
3382' + js_porto_vars.submenu_back + '</a></li>' );
3383							}
3384
3385							var nextMenuHeightDiff = nextMenu.find( '> li' ).length * nextMenu.find( '> li' ).outerHeight() - nextMenu.outerHeight();
3386
3387							currentMenu.addClass( 'next-menu' );
3388
3389							nextMenu.addClass( 'visible' );
3390							currentMenu.css( {
3391								overflow: 'visible',
3392								'overflow-y': 'visible'
3393							} );
3394
3395							if ( nextMenuHeightDiff > 0 ) {
3396								nextMenu.css( {
3397									overflow: 'hidden',
3398									'overflow-y': 'scroll'
3399								} );
3400							}
3401
3402							//for (i = 0; i < nextMenu.find('> li').length; i++) {
3403							if ( nextMenu.outerHeight() < ( nextMenu.closest( '.header-main' ).outerHeight() - 100 ) ) {
3404								nextMenu.css( {
3405									height: nextMenu.outerHeight() + nextMenu.find( '> li' ).outerHeight()
3406								} );
3407							}
3408							// }
3409
3410							nextMenu.css( {
3411								'padding-top': nextMenuHeightDiff + 'px'
3412							} );
3413						},
3414						menuNav: function() {
3415							var self = this;
3416
3417							self.$mainNav.find( '.menu-item-has-children > a.nolink' ).removeClass( 'nolink' ).attr( 'href', '' );
3418
3419							self.$mainNav.find( '.menu-item-has-children > a:not(.go-back)' ).off( 'click' ).on( 'click', function( e ) {
3420								e.stopImmediatePropagation();
3421								e.preventDefault();
3422								var $this = $( this );
3423								if ( js_porto_vars.lazyload_menu && !self.$mainNav.hasClass( 'sub-ready' ) ) {
3424									self.initSub( $this );
3425									self.$mainNav.on( 'sub-loaded', function() {
3426										self.initSub( $this );
3427									} );
3428								} else {
3429									self.initSub( $this );
3430								}
3431							} );
3432						}
3433					};
3434
3435					slideNavigation.build();
3436				}
3437
3438				if ( parent_toogle_wrap ) {
3439					parent_toogle_wrap.style.display = '';
3440					parent_toogle_wrap.style.visibility = '';
3441				}
3442
3443				return self;
3444			},
3445
3446			events: function() {
3447				var self = this;
3448
3449				self.$toggle.on( 'click', function() {
3450					var $widget = $( this ).parent().parent();
3451					var $this = $( this );
3452					if ( $this.hasClass( 'closed' ) ) {
3453						$this.removeClass( 'closed' );
3454						$widget.removeClass( 'closed' );
3455						$widget.find( '.sidebar-menu-wrap' ).stop().slideDown( 400, function() {
3456							$( this ).attr( 'style', '' ).show();
3457							self.build();
3458						} );
3459					} else {
3460						$this.addClass( 'closed' );
3461						$widget.addClass( 'closed' );
3462						$widget.find( '.sidebar-menu-wrap' ).stop().slideUp( 400, function() {
3463							$( this ).attr( 'style', '' ).hide();
3464						} );
3465					}
3466				} );
3467
3468				this.$menu_toggle.on( 'click', function() {
3469					var $toggle_menu = $( this ).parent();
3470					if ( $toggle_menu.hasClass( 'show-always' ) || $toggle_menu.hasClass( 'show-hover' ) ) {
3471						return;
3472					}
3473					var $this = $( this );
3474					if ( $this.hasClass( 'closed' ) ) {
3475						$this.removeClass( 'closed' );
3476						$toggle_menu.removeClass( 'closed' );
3477						$toggle_menu.find( '.toggle-menu-wrap' ).stop().slideDown( 400, function() {
3478							$( this ).attr( 'style', '' ).show();
3479						} );
3480
3481						self.build();
3482
3483					} else {
3484						$this.addClass( 'closed' );
3485						$toggle_menu.addClass( 'closed' );
3486						$toggle_menu.find( '.toggle-menu-wrap' ).stop().slideUp( 400, function() {
3487							$( this ).attr( 'style', '' ).hide();
3488						} );
3489					}
3490				} );
3491
3492				if ( self.$menu.hasClass( 'side-menu-slide' ) ) {
3493					self.$menu.on( 'click', '.go-back', function( e ) {
3494						e.preventDefault();
3495						var prevMenu = $( this ).closest( '.next-menu' ),
3496							prevMenuHeightDiff = 0;
3497						if ( prevMenu.length && prevMenu.find( '> li' ).length ) {
3498							prevMenuHeightDiff = prevMenu.find( '> li' ).length * prevMenu.find( '> li' ).outerHeight() - prevMenu.outerHeight();
3499						}
3500
3501
3502
3503
3504						prevMenu.removeClass( 'next-menu' );
3505						$( this ).closest( 'ul' ).removeClass( 'visible' );
3506
3507						if ( prevMenuHeightDiff > 0 ) {
3508							prevMenu.css( {
3509								overflow: 'hidden',
3510								'overflow-y': 'scroll'
3511							} );
3512						}
3513					} );
3514				}
3515
3516				if ( $( '.sidebar-menu:not(.side-menu-accordion)' ).closest( '[data-plugin-sticky]' ).length ) {
3517					var sidebarRefreshTimer;
3518					$( window ).smartresize( function() {
3519						if ( sidebarRefreshTimer ) {
3520							clearTimeout( sidebarRefreshTimer );
3521						}
3522						sidebarRefreshTimer = setTimeout( function() {
3523							self.build();
3524						}, 800 );
3525					} );
3526				} else {
3527					$( window ).smartresize( function() {
3528						self.build();
3529					} );
3530				}
3531
3532				setTimeout( function() {
3533					self.build();
3534				}, 400 );
3535
3536				return self;
3537			}
3538		}
3539
3540	} );
3541
3542} ).apply( this, [window.theme, jQuery] );
3543
3544// Sticky Header
3545( function( theme, $ ) {
3546	'use strict';
3547
3548	theme = theme || {};
3549
3550	$.extend( theme, {
3551
3552		StickyHeader: {
3553
3554			defaults: {
3555				header: $( '#header' )
3556			},
3557
3558			initialize: function( $header ) {
3559				this.$header = ( $header || this.defaults.header );
3560				this.sticky_height = 0;
3561				this.sticky_pos = 0;
3562				this.change_logo = theme.change_logo;
3563
3564				if ( !theme.show_sticky_header || !this.$header.length || $( '.side-header-narrow-bar' ).length )
3565					return this;
3566
3567				var self = this;
3568
3569				var $menu_wrap = self.$header.find( '> .main-menu-wrap' );
3570				if ( $menu_wrap.length ) {
3571					self.$menu_wrap = $menu_wrap;
3572					self.menu_height = $menu_wrap.height();
3573				} else {
3574					self.$menu_wrap = false;
3575				}
3576
3577				self.$header_main = self.$header.find( '.header-main' );
3578
3579				// fix compatibility issue with Elementor pro header builder
3580				if ( !self.$header_main.length && self.$header.children( '.elementor-location-header' ).length ) {
3581					self.$header_main = self.$header.children( '.elementor-location-header' ).last().addClass( 'header-main' );
3582				}
3583
3584				if ( !self.$header_main.length ) {
3585					return this;
3586				}
3587
3588				self.reveal = self.$header.parents( '.header-wrapper' ).hasClass( 'header-reveal' );
3589
3590				self.is_sticky = false;
3591
3592				self.reset()
3593					.build()
3594					.events();
3595
3596				return self;
3597			},
3598
3599			build: function() {
3600				var self = this;
3601
3602				if ( !self.is_sticky && ( window.innerHeight + self.header_height + theme.adminBarHeight() + parseInt( self.$header.css( 'border-top-width' ) ) >= $( document ).height() ) ) {
3603					return self;
3604				}
3605
3606				if ( window.innerHeight > $( document.body ).height() )
3607					window.scrollTo( 0, 0 );
3608
3609				var scroll_top = $( window ).scrollTop();
3610
3611				if ( self.$menu_wrap && !theme.isTablet() ) {
3612
3613					self.$header_main.stop().css( 'top', 0 );
3614
3615					if ( self.$header.parent().hasClass( 'fixed-header' ) )
3616						self.$header.parent().attr( 'style', '' );
3617
3618					if ( scroll_top > self.sticky_pos ) {
3619						if ( !self.$header.hasClass( 'sticky-header' ) ) {
3620							var header_height = self.$header.outerHeight();
3621							self.$header.addClass( 'sticky-header' ).css( 'height', header_height );
3622							self.$menu_wrap.stop().css( 'top', theme.adminBarHeight() );
3623
3624							var selectric = self.$header.find( '.header-main .searchform select' ).data( 'selectric' );
3625							if ( selectric && typeof selectric.close != 'undefined' )
3626								selectric.close();
3627
3628							if ( self.$header.parent().hasClass( 'fixed-header' ) ) {
3629								self.$header_main.hide();
3630								self.$header.css( 'height', '' );
3631							}
3632
3633							if ( !self.init_toggle_menu ) {
3634								self.init_toggle_menu = true;
3635								theme.MegaMenu.build();
3636								if ( $( '#main-toggle-menu' ).length ) {
3637									if ( $( '#main-toggle-menu' ).hasClass( 'show-always' ) ) {
3638										$( '#main-toggle-menu' ).data( 'show-always', true );
3639										$( '#main-toggle-menu' ).removeClass( 'show-always' );
3640									}
3641									$( '#main-toggle-menu' ).addClass( 'closed' );
3642									$( '#main-toggle-menu .menu-title' ).addClass( 'closed' );
3643									$( '#main-toggle-menu .toggle-menu-wrap' ).attr( 'style', '' );
3644								}
3645							}
3646							self.is_sticky = true;
3647						}
3648					} else {
3649						if ( self.$header.hasClass( 'sticky-header' ) ) {
3650							self.$header.removeClass( 'sticky-header' );
3651							self.$header.css( 'height', '' );
3652							self.$menu_wrap.stop().css( 'top', 0 );
3653							self.$header_main.show();
3654
3655							var selectric = self.$header.find( '.main-menu-wrap .searchform select' ).data( 'selectric' );
3656							if ( selectric && typeof selectric.close != 'undefined' )
3657								selectric.close();
3658
3659							if ( self.init_toggle_menu ) {
3660								self.init_toggle_menu = false;
3661								theme.MegaMenu.build();
3662								if ( $( '#main-toggle-menu' ).length ) {
3663									if ( $( '#main-toggle-menu' ).data( 'show-always' ) ) {
3664										$( '#main-toggle-menu' ).addClass( 'show-always' );
3665										$( '#main-toggle-menu' ).removeClass( 'closed' );
3666										$( '#main-toggle-menu .menu-title' ).removeClass( 'closed' );
3667										$( '#main-toggle-menu .toggle-menu-wrap' ).attr( 'style', '' );
3668									}
3669								}
3670							}
3671							self.is_sticky = false;
3672						}
3673					}
3674				} else {
3675					self.$header_main.show();
3676					if ( self.$header.parent().hasClass( 'fixed-header' ) && $( '#wpadminbar' ).length && $( '#wpadminbar' ).css( 'position' ) == 'absolute' ) {
3677						self.$header.parent().css( 'top', ( $( '#wpadminbar' ).height() - scroll_top ) < 0 ? -$( '#wpadminbar' ).height() : -scroll_top );
3678					} else if ( self.$header.parent().hasClass( 'fixed-header' ) ) {
3679						self.$header.parent().attr( 'style', '' );
3680					} else {
3681						if ( self.$header.parent().hasClass( 'fixed-header' ) )
3682							self.$header.parent().attr( 'style', '' );
3683					}
3684					if ( self.$header.hasClass( 'sticky-menu-header' ) && !theme.isTablet() ) {
3685						self.$header_main.stop().css( 'top', 0 );
3686						if ( self.change_logo ) self.$header_main.removeClass( 'change-logo' );
3687						self.$header_main.removeClass( 'sticky' );
3688						self.$header.removeClass( 'sticky-header' );
3689						self.is_sticky = false;
3690						self.sticky_height = 0;
3691					} else {
3692						if ( self.$menu_wrap )
3693							self.$menu_wrap.stop().css( 'top', 0 );
3694						if ( scroll_top > self.sticky_pos && ( !theme.isTablet() || ( theme.isTablet() && ( !theme.isMobile() && theme.show_sticky_header_tablet ) || ( theme.isMobile() && theme.show_sticky_header_tablet && theme.show_sticky_header_mobile ) ) ) ) {
3695							if ( !self.$header.hasClass( 'sticky-header' ) ) {
3696								var header_height = self.$header.outerHeight();
3697								self.$header.addClass( 'sticky-header' ).css( 'height', header_height );
3698								self.$header_main.addClass( 'sticky' );
3699								if ( self.change_logo ) self.$header_main.addClass( 'change-logo' );
3700								self.$header_main.stop().css( 'top', theme.adminBarHeight() );
3701
3702								if ( !self.init_toggle_menu ) {
3703									self.init_toggle_menu = true;
3704									theme.MegaMenu.build();
3705									if ( $( '#main-toggle-menu' ).length ) {
3706										if ( $( '#main-toggle-menu' ).hasClass( 'show-always' ) ) {
3707											$( '#main-toggle-menu' ).data( 'show-always', true );
3708											$( '#main-toggle-menu' ).removeClass( 'show-always' );
3709										}
3710										$( '#main-toggle-menu' ).addClass( 'closed' );
3711										$( '#main-toggle-menu .menu-title' ).addClass( 'closed' );
3712										$( '#main-toggle-menu .toggle-menu-wrap' ).attr( 'style', '' );
3713									}
3714								}
3715								self.is_sticky = true;
3716							}
3717						} else {
3718							if ( self.$header.hasClass( 'sticky-header' ) ) {
3719								if ( self.change_logo ) self.$header_main.removeClass( 'change-logo' );
3720								self.$header_main.removeClass( 'sticky' );
3721								self.$header.removeClass( 'sticky-header' );
3722								self.$header.css( 'height', '' );
3723								self.$header_main.stop().css( 'top', 0 );
3724
3725								if ( self.init_toggle_menu ) {
3726									self.init_toggle_menu = false;
3727									theme.MegaMenu.build();
3728									if ( $( '#main-toggle-menu' ).length ) {
3729										if ( $( '#main-toggle-menu' ).data( 'show-always' ) ) {
3730											$( '#main-toggle-menu' ).addClass( 'show-always' );
3731											$( '#main-toggle-menu' ).removeClass( 'closed' );
3732											$( '#main-toggle-menu .menu-title' ).removeClass( 'closed' );
3733											$( '#main-toggle-menu .toggle-menu-wrap' ).attr( 'style', '' );
3734										}
3735									}
3736								}
3737								self.is_sticky = false;
3738							}
3739						}
3740					}
3741				}
3742
3743				if ( !self.$header.hasClass( 'header-loaded' ) )
3744					self.$header.addClass( 'header-loaded' );
3745
3746				if ( !self.$header.find( '.logo' ).hasClass( 'logo-transition' ) )
3747					self.$header.find( '.logo' ).addClass( 'logo-transition' );
3748
3749				if ( self.$header.find( '.overlay-logo' ).get( 0 ) && !self.$header.find( '.overlay-logo' ).hasClass( 'overlay-logo-transition' ) )
3750					self.$header.find( '.overlay-logo' ).addClass( 'overlay-logo-transition' );
3751
3752				return self;
3753			},
3754
3755			reset: function() {
3756				var self = this;
3757
3758				if ( self.$header.find( '.logo' ).hasClass( 'logo-transition' ) )
3759					self.$header.find( '.logo' ).removeClass( 'logo-transition' );
3760
3761				if ( self.$header.find( '.overlay-logo' ).get( 0 ) && self.$header.find( '.overlay-logo' ).hasClass( 'overlay-logo-transition' ) )
3762					self.$header.find( '.overlay-logo' ).removeClass( 'overlay-logo-transition' );
3763
3764				if ( self.$menu_wrap && !theme.isTablet() ) {
3765					// show main menu
3766					self.$header.addClass( 'sticky-header sticky-header-calc' );
3767					self.$header_main.addClass( 'sticky' );
3768					if ( self.change_logo ) self.$header_main.addClass( 'change-logo' );
3769
3770					self.sticky_height = self.$menu_wrap.height() + parseInt( self.$menu_wrap.css( 'padding-top' ) ) + parseInt( self.$menu_wrap.css( 'padding-bottom' ) );
3771
3772					if ( self.change_logo ) self.$header_main.removeClass( 'change-logo' );
3773					self.$header_main.removeClass( 'sticky' );
3774					self.$header.removeClass( 'sticky-header sticky-header-calc' );
3775					self.header_height = self.$header.height() + parseInt( self.$header.css( 'margin-top' ) );
3776					self.menu_height = self.$menu_wrap.height() + parseInt( self.$menu_wrap.css( 'padding-top' ) ) + parseInt( self.$menu_wrap.css( 'padding-bottom' ) );
3777
3778					self.sticky_pos = ( self.header_height - self.sticky_height ) + parseInt( $( 'body' ).css( 'padding-top' ) ) + parseInt( self.$header.css( 'border-top-width' ) );
3779					if ( $( '.banner-before-header' ).length ) {
3780						self.sticky_pos += $( '.banner-before-header' ).height();
3781					}
3782					if ( $( '.porto-block-html-top' ).length ) {
3783						self.sticky_pos += $( '.porto-block-html-top' ).height();
3784					}
3785				} else {
3786					// show header main
3787					self.$header.addClass( 'sticky-header sticky-header-calc' );
3788					self.$header_main.addClass( 'sticky' );
3789					if ( self.change_logo ) self.$header_main.addClass( 'change-logo' );
3790					self.sticky_height = self.$header_main.outerHeight();
3791
3792					if ( self.change_logo ) self.$header_main.removeClass( 'change-logo' );
3793					self.$header_main.removeClass( 'sticky' );
3794					self.$header.removeClass( 'sticky-header sticky-header-calc' );
3795					self.header_height = self.$header.height() + parseInt( self.$header.css( 'margin-top' ) );
3796					self.main_height = self.$header_main.height();
3797
3798					if ( !( !theme.isTablet() || ( theme.isTablet() && !theme.isMobile() && theme.show_sticky_header_tablet ) || ( theme.isMobile() && theme.show_sticky_header_tablet && theme.show_sticky_header_mobile ) ) ) {
3799						self.sticky_height = 0;
3800					}
3801
3802					/*if (self.$header_main.length && self.$header.length) {
3803						self.sticky_pos = self.$header_main.offset().top - self.$header.offset().top + $('.banner-before-header').height() + parseInt($('body').css('padding-top')) + parseInt(self.$header.css('border-top-width'));
3804					} else {
3805						self.sticky_pos = $('.banner-before-header').height() + parseInt($('body').css('padding-top')) + parseInt(self.$header.css('border-top-width'));
3806					}
3807					if (theme.adminBarHeight() && self.$header.offset().top > theme.adminBarHeight()) {
3808						self.sticky_pos -= theme.adminBarHeight();
3809					}
3810					self.sticky_pos = (self.header_height - self.sticky_height) + $('.banner-before-header').height() + $('.porto-block-html-top').height() + parseInt($('body').css('padding-top')) + parseInt(self.$header.css('border-top-width'));*/
3811					self.sticky_pos = self.$header.offset().top + self.header_height - self.sticky_height - theme.adminBarHeight() + parseInt( self.$header.css( 'border-top-width' ) );
3812				}
3813
3814				if ( self.reveal ) {
3815					if ( self.menu_height ) {
3816						self.sticky_pos += self.menu_height + 30;
3817					} else {
3818						self.sticky_pos += 30;
3819					}
3820				}
3821
3822				if ( self.sticky_pos < 0 ) {
3823					self.sticky_pos = 0;
3824				}
3825
3826				self.init_toggle_menu = false;
3827
3828				self.$header_main.removeAttr( 'style' );
3829				if ( !theme.isTablet() && self.$header.hasClass( 'header-side' ) && typeof self.$header.attr( 'data-
3829plugin-sticky' ) != 'undefined' ) {
3830					self.$header.css( 'height', '' );
3831				} else {
3832					self.$header.removeAttr( 'style' );
3833				}
3834				return self;
3835			},
3836
3837			events: function() {
3838				var self = this, win_width = 0;
3839
3840				$( window ).smartresize( function() {
3841					if ( win_width != window.innerWidth ) {
3842						self.reset().build();
3843						win_width = window.innerWidth;
3844					}
3845				} );
3846
3847				window.addEventListener( 'scroll', function() {
3848					theme.requestFrame( function() {
3849						self.build();
3850					} );
3851				}, { passive: true } );
3852
3853				return self;
3854			}
3855		}
3856
3857	} );
3858
3859} ).apply( this, [window.theme, jQuery] );
3860
3861// Side Nav
3862( function( theme, $ ) {
3863	'use strict';
3864
3865	theme = theme || {};
3866
3867	$.extend( theme, {
3868
3869		SideNav: {
3870
3871			defaults: {
3872				side_nav: $( '.header-side-nav #header' )
3873			},
3874
3875			bc_pos_top: 0,
3876
3877			initialize: function( $side_nav ) {
3878				this.$side_nav = ( $side_nav || this.defaults.side_nav );
3879
3880				if ( !this.$side_nav.length )
3881					return this;
3882
3883				var self = this;
3884
3885				self.$side_nav.addClass( 'initialize' );
3886
3887				self.reset()
3888					.build()
3889					.events();
3890
3891				return self;
3892			},
3893
3894			build: function() {
3895				var self = this;
3896
3897				var $page_top = $( '.page-top' ),
3898					$main = $( '#main' );
3899
3900				if ( theme.isTablet() ) {
3901					//self.$side_nav.removeClass("fixed-bottom");
3902					$page_top.removeClass( "fixed-pos" );
3903					$page_top.attr( 'style', '' );
3904					$main.attr( 'style', '' );
3905				} else {
3906					//var side_height = self.$side_nav.innerHeight();
3907					//var window_height = window.innerHeight;
3908					var scroll_top = $( window ).scrollTop();
3909
3910					/*if (side_height - window_height + theme.adminBarHeight() < scroll_top) {
3911						if (!self.$side_nav.hasClass("fixed-bottom"))
3912							self.$side_nav.addClass("fixed-bottom");
3913					} else {
3914						if (self.$side_nav.hasClass("fixed-bottom"))
3915							self.$side_nav.removeClass("fixed-bottom");
3916					}*/
3917
3918					if ( $page_top.length && $page_top.outerHeight() < 100 && !$( '.side-header-narrow-bar-top' ).length ) {
3919						if ( self.page_top_offset == theme.adminBarHeight() || self.page_top_offset <= scroll_top ) {
3920							if ( !$page_top.hasClass( "fixed-pos" ) ) {
3921								$page_top.addClass( "fixed-pos" );
3922								$page_top.css( 'top', theme.adminBarHeight() );
3923								$main.css( 'padding-top', $page_top.outerHeight() );
3924							}
3925						} else {
3926							if ( $page_top.hasClass( "fixed-pos" ) ) {
3927								$page_top.removeClass( "fixed-pos" );
3928								$page_top.attr( 'style', '' );
3929								$main.attr( 'style', '' );
3930							}
3931						}
3932					}
3933					$main.css( 'min-height', window.innerHeight - theme.adminBarHeight() - $( '.page-top:not(.fixed-pos)' ).height() - $( '.footer-wrapper' ).height() );
3934				}
3935
3936				return self;
3937			},
3938
3939			reset: function() {
3940				var self = this;
3941
3942				if ( theme.isTablet() ) {
3943
3944					self.$side_nav.attr( 'style', '' );
3945
3946				} else {
3947
3948					var w_h = window.innerHeight,
3949						$side_bottom = self.$side_nav.find( '.side-bottom' );
3950
3951					self.$side_nav.css( {
3952						'min-height': w_h - theme.adminBarHeight(),
3953						'padding-bottom': $side_bottom.length ? $side_bottom.height() + parseInt( $side_bottom.css( 'margin-top' ) ) + parseInt( $side_bottom.css( 'margin-bottom' ) ) : ''
3954					} );
3955
3956					var appVersion = navigator.appVersion;
3957					var webkitVersion_positionStart = appVersion.indexOf( "AppleWebKit/" ) + 12;
3958					var webkitVersion_positionEnd = webkitVersion_positionStart + 3;
3959					var webkitVersion = appVersion.slice( webkitVersion_positionStart, webkitVersion_positionEnd );
3960					if ( webkitVersion < 537 ) {
3961						self.$side_nav.css( '-webkit-backface-visibility', 'hidden' );
3962						self.$side_nav.css( '-webkit-perspective', '1000' );
3963					}
3964				}
3965
3966				var $page_top = $( '.page-top' ),
3967					$main = $( '#main' );
3968
3969				if ( $page_top.length ) {
3970					$page_top.removeClass( "fixed-pos" );
3971					$page_top.attr( 'style', '' );
3972					$main.attr( 'style', '' );
3973					self.page_top_offset = $page_top.offset().top;
3974				}
3975
3976				return self;
3977			},
3978
3979			events: function() {
3980				var self = this;
3981
3982				$( window ).on( 'resize', function() {
3983					self.reset()
3984						.build();
3985				} );
3986
3987				window.addEventListener( 'scroll', function() {
3988					self.build();
3989				}, { passive: true } );
3990
3991				if ( $( '.side-header-narrow-bar-top' ).length ) {
3992					if ( $( window ).scrollTop() > theme.adminBarHeight() + $( '.side-header-narrow-bar-top' ).height() ) {
3993						$( '.side-header-narrow-bar-top' ).addClass( 'side-header-narrow-bar-sticky' );
3994					}
3995					window.addEventListener( 'scroll', function() {
3996						var scroll_top = $( this ).scrollTop();
3997						if ( scroll_top > theme.adminBarHeight() + $( '.side-header-narrow-bar-top' ).height() ) {
3998							$( '.side-header-narrow-bar-top' ).addClass( 'side-header-narrow-bar-sticky' );
3999						} else {
4000							$( '.side-header-narrow-bar-top' ).removeClass( 'side-header-narrow-bar-sticky' );
4001						}
4002					}, { passive: true } );
4003				}
4004
4005				// Side Narrow Bar
4006				$( '.side-header-narrow-bar .hamburguer-btn' ).on( 'click', function() {
4007					$( this ).toggleClass( 'active' );
4008					$( '#header' ).toggleClass( 'side-header-visible' );
4009					if ( $( this ).closest( '.side-header-narrow-bar-top' ).length && !$( '#header > .hamburguer-btn' ).length ) {
4010						$( this ).closest( '.side-header-narrow-bar-top' ).toggle();
4011					}
4012				} );
4013				$( '.hamburguer-close' ).on( 'click', function() {
4014					$( '.side-header-narrow-bar .hamburguer-btn' ).trigger( 'click' );
4015				} );
4016
4017				return self;
4018			}
4019		}
4020
4021	} );
4022
4023} ).apply( this, [window.theme, jQuery] );
4024
4025
4026// Search
4027( function( theme, $ ) {
4028	'use strict';
4029
4030	theme = theme || {};
4031
4032	$.extend( theme, {
4033
4034		Search: {
4035
4036			defaults: {
4037				popup: $( '.searchform-popup' ),
4038				form: $( '.searchform' )
4039			},
4040
4041			initialize: function( $popup, $form ) {
4042				this.$popup = ( $popup || this.defaults.popup );
4043				this.$form = ( $form || this.defaults.form );
4044
4045				this.build()
4046					.events();
4047
4048				return this;
4049			},
4050
4051			build: function() {
4052				var self = this;
4053
4054				/* Change search form values */
4055				var $search_form_texts = self.$form.find( '.text input' ),
4056					$search_form_cats = self.$form.find( '.cat' );
4057
4058				if ( $( '.searchform .cat' ).get( 0 ) && $.fn.selectric ) {
4059					$( '.searchform .cat' ).selectric( {
4060						arrowButtonMarkup: '',
4061						expandToItemText: true,
4062						maxHeight: 240
4063					} );
4064				}
4065
4066				$search_form_texts.on( 'change', function() {
4067					var $this = $( this ),
4068						val = $this.val();
4069
4070					$search_form_texts.each( function() {
4071						if ( $this != $( this ) ) $( this ).val( val );
4072					} );
4073				} );
4074
4075				$search_form_cats.on( 'change', function() {
4076					var $this = $( this ),
4077						val = $this.val();
4078
4079					$search_form_cats.each( function() {
4080						if ( $this != $( this ) ) $( this ).val( val );
4081					} );
4082				} );
4083
4084				return this;
4085			},
4086
4087			events: function() {
4088				var self = this;
4089
4090				self.$popup.on( 'click', function( e ) {
4091					e.stopPropagation();
4092				} );
4093				self.$popup.find( '.search-toggle' ).on( 'click', function( e ) {
4094					e.preventDefault();
4095					$( this ).toggleClass( 'opened' );
4096					$( this ).next().toggle();
4097					if ( $( this ).hasClass( 'opened' ) ) {
4098						$( '#mini-cart.open' ).removeClass( 'open' );
4099						$( this ).next().find( 'input[type="text"]' ).focus();
4100						if ( self.$popup.find( '.btn-close-search-form' ).length ) {
4101							self.$popup.parent().addClass( 'position-static' );
4102						}
4103					}
4104					e.preventDefault();
4105					e.stopPropagation();
4106				} );
4107
4108				$( 'html,body' ).on( 'click', function() {
4109					self.removeFormStyle();
4110				} );
4111
4112				if ( !( 'ontouchstart' in document ) ) {
4113
4114					$( window ).on( 'resize', function() {
4115						self.removeFormStyle();
4116					} );
4117				}
4118
4119				$( '.btn-close-search-form' ).on( 'click', function( e ) {
4120					e.preventDefault();
4121					self.removeFormStyle();
4122				} );
4123
4124				return self;
4125			},
4126
4127			removeFormStyle: function() {
4128				this.$form.removeAttr( 'style' );
4129				this.$popup.find( '.search-toggle' ).removeClass( 'opened' );
4130				if ( this.$popup.find( '.btn-close-search-form' ).length ) {
4131					this.$popup.parent().removeClass( 'position-static' );
4132				}
4133			}
4134		}
4135
4136	} );
4137
4138} ).apply( this, [window.theme, jQuery] );
4139
4140
4141// Hash Scroll
4142( function( theme, $ ) {
4143	'use strict';
4144
4145	theme = theme || {};
4146
4147	$.extend( theme, {
4148
4149		HashScroll: {
4150
4151			initialize: function() {
4152
4153				this.build()
4154					.events();
4155
4156				return this;
4157			},
4158
4159			build: function() {
4160				var self = this;
4161
4162				try {
4163					var hash = window.location.hash;
4164					var target = $( hash );
4165					if ( target.length && !( hash == '#review_form' || hash == '#reviews' || hash.indexOf( '#comment-' ) != -1 ) ) {
4166						$( 'html, body' ).delay( 600 ).stop().animate( {
4167							scrollTop: target.offset().top - theme.StickyHeader.sticky_height - theme.adminBarHeight() - theme.sticky_nav_height + 1
4168						}, 600, 'easeOutQuad' );
4169					}
4170
4171					return self;
4172				} catch ( err ) {
4173					return self;
4174				}
4175			},
4176
4177			getTarget: function( href ) {
4178				if ( '#' == href || href.endsWith( '#' ) ) {
4179					return false;
4180				}
4181				var target;
4182
4183				if ( href.indexOf( '#' ) == 0 ) {
4184					target = $( href );
4185				} else {
4186					var url = window.location.href;
4187					url = url.substring( url.indexOf( '://' ) + 3 );
4188					if ( url.indexOf( '#' ) != -1 )
4189						url = url.substring( 0, url.indexOf( '#' ) );
4190					href = href.substring( href.indexOf( '://' ) + 3 );
4191					href = href.substring( href.indexOf( url ) + url.length );
4192					if ( href.indexOf( '#' ) == 0 ) {
4193						target = $( href );
4194					}
4195				}
4196				return target;
4197			},
4198
4199			activeMenuItem: function() {
4200				var self = this;
4201
4202				var scroll_pos = $( window ).scrollTop();
4203
4204				var $menu_items = $( '.menu-item > a[href*="#"], .porto-sticky-nav .nav > li > a[href*="#"]' );
4205				if ( $menu_items.length ) {
4206					$menu_items.each( function() {
4207						var $this = $( this ),
4208							href = $this.attr( 'href' ),
4209							target = self.getTarget( href );
4210						if ( target && target.get( 0 ) ) {
4211							if ( $this.parent().is( ':last-child' ) && scroll_pos + window.innerHeight >= target.offset().top + target.outerHeight() ) {
4212								$this.parent().siblings().removeClass( 'active' );
4213								$this.parent().addClass( 'active' );
4214							} else {
4215								var scroll_to = target.offset().top - theme.StickyHeader.sticky_height - theme.adminBarHeight() - theme.sticky_nav_height + 1,
4216									$parent = $this.parent();
4217								//if (scroll_to <= theme.StickyHeader.sticky_pos + theme.sticky_nav_height) {
4218								//scroll_to = theme.StickyHeader.sticky_pos + theme.sticky_nav_height + 1;
4219								//}
4220								if ( scroll_to <= scroll_pos + 5 ) {
4221									$parent.siblings().removeClass( 'active' );
4222									$parent.addClass( 'active' );
4223									if ( $parent.closest( '.secondary-menu' ).length ) {
4224										$parent.closest( '#header' ).find( '.main-menu' ).eq( 0 ).children( '.menu-item.active' ).removeClass( 'active' );
4225									}
4226								} else {
4227									$parent.removeClass( 'active' );
4228								}
4229							}
4230						}
4231					} );
4232				}
4233
4234				return self;
4235			},
4236
4237			events: function() {
4238				var self = this;
4239
4240				$( '.menu-item > a[href*="#"], .porto-sticky-nav .nav > li > a[href*="#"], a[href*="#"].hash-scroll, .hash-scroll-wrap a[href*="#"]' ).on( 'click', function( e ) {
4241					e.preventDefault();
4242
4243					var $this = $( this ),
4244						href = $this.attr( 'href' ),
4245						target = self.getTarget( href );
4246
4247					if ( target && target.get( 0 ) ) {
4248						var $parent = $this.parent();
4249
4250						var scroll_to = target.offset().top - theme.StickyHeader.sticky_height - theme.adminBarHeight() - theme.sticky_nav_height + 1;
4251						//                        if (scroll_to <= theme.StickyHeader.sticky_pos + theme.sticky_nav_height) {
4252						//                            scroll_to = theme.StickyHeader.sticky_pos + theme.sticky_nav_height + 1;
4253						//                        }
4254						$( 'html, body' ).stop().animate( {
4255							scrollTop: scroll_to
4256						}, 600, 'easeOutQuad', function() {
4257							//self.activeMenuItem();
4258							$parent.siblings().removeClass( 'active' );
4259							$parent.addClass( 'active' );
4260						} );
4261						if ( $this.closest( '.porto-popup-menu.opened' ).length ) {
4262							$this.closest( '.porto-popup-menu.opened' ).children( '.hamburguer-btn' ).trigger( 'click' );
4263						}
4264					} else if ( ( '#' != href || !$this.closest( '.porto-popup-menu.opened' ).length ) && !$this.hasClass( 'nolink' ) ) {
4265						window.location.href = $this.attr( 'href' );
4266					}
4267				} );
4268
4269				/*window.addEventListener( 'scroll', function () {
4270					self.activeMenuItem();
4271				}, { passive: true } );*/
4272				var $menu_items = $( '.menu-item > a[href*="#"], .porto-sticky-nav .nav > li > a[href*="#"]' );
4273				$menu_items.each( function() {
4274					var rootMargin = '-20% 0px -79.9% 0px',
4275						isLast = $( this ).parent().is( ':last-child' );
4276					if ( isLast ) {
4277						var obj = document.getElementById( this.hash.replace( '#', '' ) );
4278						if ( obj && document.body.offsetHeight - obj.offsetTop < window.innerHeight ) {
4279							var ratio = ( window.innerHeight - document.body.offsetHeight + obj.offsetTop ) / window.innerHeight * 0.8;
4280							ratio = Math.round( ratio * 100 );
4281							rootMargin = '-' + ( 20 + ratio ) + '% 0px -' + ( 79.9 - ratio ) + '% 0px';
4282						}
4283					}
4284					var callback = function() {
4285						if ( this && typeof this[0] != 'undefined' && this[0].id ) {
4286							$( '.menu-item > a[href*="#' + this[0].id + '"], .porto-sticky-nav .nav > li > a[href*="#' + this[0].id + '"]' ).parent().addClass( 'active' ).siblings().removeClass( 'active' );
4287						}
4288					};
4289					self.scrollSpyIntObs( this.hash, callback, {
4290						rootMargin: rootMargin,
4291						thresholds: 0
4292					}, true, isLast, true, $menu_items, $( this ).parent().index() );
4293				} );
4294
4295				//self.activeMenuItem();
4296
4297				return self;
4298			},
4299
4300			scrollSpyIntObs: function( selector, functionName, intObsOptions, al
4300waysObserve, isLast, firstLoad, $allItems, index ) {
4301				if ( typeof IntersectionObserver == 'undefined' ) {
4302					return this;
4303				}
4304				var obj = document.getElementById( selector.replace( '#', '' ) );
4305				if ( !obj ) {
4306					return this;
4307				}
4308
4309				var self = this;
4310
4311				var intersectionObserverOptions = {
4312					rootMargin: '0px 0px 200px 0px'
4313				}
4314
4315				if ( Object.keys( intObsOptions ).length ) {
4316					intersectionObserverOptions = $.extend( intersectionObserverOptions, intObsOptions );
4317				}
4318
4319				var observer = new IntersectionObserver( function( entries ) {
4320
4321					for ( var i = 0; i < entries.length; i++ ) {
4322						var entry = entries[i];
4323						if ( entry.intersectionRatio > 0 ) {
4324							if ( typeof functionName === 'string' ) {
4325								var func = Function( 'return ' + functionName )();
4326							} else {
4327								var callback = functionName;
4328
4329								callback.call( $( entry.target ) );
4330							}
4331						} else {
4332							if ( firstLoad == false ) {
4333								if ( isLast && ! $allItems.closest('.porto-sticky-nav').length ) {
4334									$allItems.filter( '[href*="' + entry.target.id + '"]' ).parent().prev().addClass( 'active' ).siblings().removeClass( 'active' );
4335								}
4336							}
4337							firstLoad = false;
4338
4339						}
4340					}
4341				}, intersectionObserverOptions );
4342
4343				observer.observe( obj );
4344
4345				return this;
4346			}
4347		}
4348
4349	} );
4350
4351} ).apply( this, [window.theme, jQuery] );
4352
4353
4354// Sort Filter
4355( function( theme, $ ) {
4356	'use strict';
4357
4358	theme = theme || {};
4359
4360	$.extend( theme, {
4361
4362		SortFilter: {
4363
4364			defaults: {
4365				filters: '.porto-sort-filters ul',
4366				elements: '.porto-sort-container .row'
4367			},
4368
4369			initialize: function( $elements, $filters ) {
4370				this.$elements = ( $elements || $( this.defaults.elements ) );
4371				this.$filters = ( $filters || $( this.defaults.filters ) );
4372
4373				this.build();
4374
4375				return this;
4376			},
4377
4378			build: function() {
4379				var self = this;
4380
4381				self.$elements.each( function() {
4382					var $this = $( this );
4383					$this.isotope( {
4384						itemSelector: '.porto-sort-item',
4385						layoutMode: 'masonry',
4386						getSortData: {
4387							popular: '[data-popular] parseInt'
4388						},
4389						sortBy: 'popular',
4390						isOriginLeft: !theme.rtl
4391					} );
4392					/*$this.isotope( 'on', 'layoutComplete', function () {
4393						$this.find( '.porto-lazyload:not(.lazy-load-loaded)' ).trigger( 'appear' );
4394					} );*/
4395					imagesLoaded( this, function() {
4396						if ( $this.data( 'isotope' ) ) {
4397							$this.isotope( 'layout' );
4398						}
4399					} );
4400				} );
4401
4402				self.$filters.each( function() {
4403					var $this = $( this );
4404					var id = $this.attr( 'data-sort-id' );
4405					var $container = $( '#' + id );
4406					if ( $container.length ) {
4407						$this.on( 'click', 'li', function( e ) {
4408							e.preventDefault();
4409
4410							var $that = $( this );
4411							$this.find( 'li' ).removeClass( 'active' );
4412							$that.addClass( "active" );
4413
4414							var sortByValue = $that.attr( 'data-sort-by' );
4415							$container.isotope( { sortBy: sortByValue } );
4416
4417							var filterByValue = $that.attr( 'data-filter-by' );
4418							if ( filterByValue ) {
4419								$container.isotope( { filter: filterByValue } );
4420							} else {
4421								$container.isotope( { filter: '.porto-sort-item' } );
4422							}
4423							theme.refreshVCContent();
4424						} );
4425
4426						$this.find( 'li[data-active]' ).trigger( 'click' );
4427					}
4428				} );
4429
4430				return self;
4431			}
4432		}
4433
4434	} );
4435
4436} ).apply( this, [window.theme, jQuery] );
4437
4438/*
4439* Footer Reveal
4440*/
4441
4442( function( $ ) {
4443	var $footerReveal = {
4444
4445		$wrapper: $( '.footer-reveal' ),
4446		init: function() {
4447			var self = this;
4448
4449			self.build();
4450			self.events();
4451		},
4452
4453		build: function() {
4454			var self = this,
4455				footer_height = self.$wrapper.outerHeight( true ),
4456				window_height = window.innerHeight - theme.adminBarHeight();
4457			if ( $( '#header .header-main' ).length ) {
4458				window_height -= $( '#header .header-main' ).height();
4459			}
4460
4461			if ( footer_height > window_height ) {
4462				$( '.footer-wrapper' ).removeClass( 'footer-reveal' );
4463				$( '.page-wrapper' ).css( 'margin-bottom', 0 );
4464			} else {
4465				$( '.footer-wrapper' ).addClass( 'footer-reveal' );
4466				$( '.page-wrapper' ).css( 'margin-bottom', footer_height );
4467				if ( document.body.offsetHeight < window.innerHeight ) {
4468					document.body.style.paddingBottom = '0.1px';
4469				}
4470			}
4471
4472		},
4473
4474		events: function() {
4475			var self = this,
4476				$window = $( window );
4477
4478			$window.smartresize( function() {
4479				self.build();
4480			} );
4481		}
4482	}
4483
4484	if ( $( '.footer-reveal' ).get( 0 ) ) {
4485		$footerReveal.init();
4486	}
4487
4488} )( jQuery );
4489
4490// Float Element
4491( function( theme, $ ) {
4492
4493	'use strict';
4494
4495	theme = theme || {};
4496
4497	var instanceName = '__floatElement';
4498
4499	var PluginFloatElement = function( $el, opts ) {
4500		return this.initialize( $el, opts );
4501	};
4502
4503	PluginFloatElement.defaults = {
4504		startPos: 'top',
4505		speed: 3,
4506		horizontal: false,
4507		circle: false,
4508		transition: false,
4509		transitionDelay: 0,
4510		transitionDuration: 500
4511	};
4512
4513	PluginFloatElement.prototype = {
4514		initialize: function( $el, opts ) {
4515			if ( $el.data( instanceName ) ) {
4516				return this;
4517			}
4518
4519			this.$el = $el;
4520
4521			this
4522				.setData()
4523				.setOptions( opts )
4524				.build();
4525
4526			return this;
4527		},
4528
4529		setData: function() {
4530			this.$el.data( instanceName, this );
4531
4532			return this;
4533		},
4534
4535		setOptions: function( opts ) {
4536			this.options = $.extend( true, {}, PluginFloatElement.defaults, opts, {
4537				wrapper: this.$el
4538			} );
4539
4540			return this;
4541		},
4542
4543		build: function() {
4544			var self = this,
4545				$el = this.options.wrapper,
4546				$window = $( window ),
4547				minus;
4548
4549			if ( self.options.style ) {
4550				$el.attr( 'style', self.options.style );
4551			}
4552
4553			if ( self.options.circle ) {
4554				// Set Transition
4555				if ( self.options.transition ) {
4556					$el.css( {
4557						transition: 'ease-out transform ' + self.options.transitionDuration + 'ms ' + self.options.transitionDelay + 'ms'
4558					} );
4559				}
4560				// Scroll
4561				window.addEventListener( 'scroll', function() {
4562					self.movement( minus );
4563				}, { passive: true } );
4564
4565			} else if ( $window.width() > 767 ) {
4566				// Set Start Position
4567				if ( self.options.startPos == 'none' ) {
4568					minus = '';
4569				} else if ( self.options.startPos == 'top' ) {
4570					$el.css( {
4571						top: 0
4572					} );
4573					minus = '';
4574				} else {
4575					$el.css( {
4576						bottom: 0
4577					} );
4578					minus = '-';
4579				}
4580
4581				// Set Transition
4582				if ( self.options.transition ) {
4583					$el.css( {
4584						transition: 'ease-out transform ' + self.options.transitionDuration + 'ms ' + self.options.transitionDelay + 'ms'
4585					} );
4586				}
4587
4588				// First Load
4589				self.movement( minus );
4590				// Scroll
4591				window.addEventListener( 'scroll', function() {
4592					self.movement( minus );
4593				}, { passive: true } );
4594			}
4595
4596			return this;
4597		},
4598
4599		movement: function( minus ) {
4600			var self = this,
4601				$el = this.options.wrapper,
4602				$window = $( window ),
4603				scrollTop = $window.scrollTop(),
4604				elementOffset = $el.offset().top,
4605				currentElementOffset = ( elementOffset - scrollTop );
4606
4607			if ( self.options.circle ) {
4608				$el.css( {
4609					transform: 'rotate(' + ( scrollTop * 0.25 ) + 'deg)'
4610				} );
4611			} else {
4612				var scrollPercent = 100 * currentElementOffset / ( $window.height() );
4613
4614				if ( elementOffset + $el.height() >= scrollTop && elementOffset <= scrollTop + window.innerHeight ) {
4615
4616					if ( !self.options.horizontal ) {
4617
4618						$el.css( {
4619							transform: 'translate3d(0, ' + minus + scrollPercent / self.options.speed + '%, 0)'
4620						} );
4621
4622					} else {
4623
4624						$el.css( {
4625							transform: 'translate3d(' + minus + scrollPercent / self.options.speed + '%, 0, 0)'
4626						} );
4627
4628					}
4629				}
4630			}
4631		}
4632	};
4633
4634	// expose to scope
4635	$.extend( theme, {
4636		PluginFloatElement: PluginFloatElement
4637	} );
4638
4639	// jquery plugin
4640	$.fn.themePluginFloatElement = function( opts ) {
4641		return this.map( function() {
4642			var $this = $( this );
4643
4644			if ( $this.data( instanceName ) ) {
4645				return $this.data( instanceName );
4646			} else {
4647				return new PluginFloatElement( $this, opts );
4648			}
4649
4650		} );
4651	}
4652
4653} ).apply( this, [window.theme, jQuery] );
4654
4655
4656// Init Theme
4657function porto_init( $wrap ) {
4658	'use strict';
4659	jQuery( window ).on( 'touchstart', function() { } );
4660	if ( !$wrap ) {
4661		$wrap = jQuery( document.body );
4662	}
4663	var wrapObj = $wrap.get( 0 );
4664	$wrap.trigger( 'porto_init_start', [wrapObj] );
4665
4666	( function( $ ) {
4667		// Accordion
4668		if ( $.fn.themeAccordion ) {
4669
4670			$( function() {
4671				$wrap.find( '.accordion:not(.manual)' ).each( function() {
4672					var $this = $( this ),
4673						opts;
4674
4675					var pluginOptions = $this.data( 'plugin-options' );
4676					if ( pluginOptions )
4677						opts = pluginOptions;
4678
4679					$this.themeAccordion( opts );
4680				} );
4681			} );
4682		}
4683
4684		// Accordion Menu
4685		if ( $.fn.themeAccordionMenu ) {
4686
4687			$( function() {
4688				$wrap.find( '.accordion-menu:not(.manual)' ).each( function() {
4689					var $this = $( this ),
4690						opts;
4691
4692					var pluginOptions = $this.data( 'plugin-options' );
4693					if ( pluginOptions )
4694						opts = pluginOptions;
4695
4696					$this.themeAccordionMenu( opts );
4697				} );
4698			} );
4699
4700		}
4701
4702		// Chart.Circular
4703		if ( $.fn.themeChartCircular ) {
4704			var $objects = wrapObj.querySelectorAll( '[data-plugin-chart-circular]:not(.manual), .circular-bar-chart:not(.manual)' );
4705			if ( $objects.length ) {
4706				theme.dynIntObsInit( $objects, 'themeChartCircular', theme.ChartCircular.defaults );
4707			}
4708
4709		}
4710
4711		// Fit Video
4712		if ( $.fn.themeFitVideo ) {
4713
4714			$( function() {
4715				$wrap.find( '.fit-video:not(.manual)' ).each( function() {
4716					var $this = $( this ),
4717						opts;
4718
4719					var pluginOptions = $this.data( 'plugin-options' );
4720					if ( pluginOptions )
4721						opts = pluginOptions;
4722
4723					$this.themeFitVideo( opts );
4724				} );
4725			} );
4726
4727		}
4728
4729		// Video Background
4730		if ( $.fn.themePluginVideoBackground ) {
4731
4732			$( function() {
4733				$wrap.find( '[data-plugin-video-background]:not(.manual)' ).each( function() {
4734					var $this = $( this ),
4735						opts;
4736
4737					var pluginOptions = theme.getOptions( $this.data( 'plugin-options' ) );
4738					if ( pluginOptions )
4739						opts = pluginOptions;
4740
4741					$this.themePluginVideoBackground( opts );
4742				} );
4743			} );
4744
4745		}
4746
4747		// Flickr Zoom
4748		if ( $.fn.themeFlickrZoom ) {
4749
4750			$( function() {
4751				$wrap.find( '.wpb_flickr_widget:not(.manual)' ).each( function() {
4752					var $this = $( this ),
4753						opts;
4754
4755					var pluginOptions = $this.data( 'plugin-options' );
4756					if ( pluginOptions )
4757						opts = pluginOptions;
4758
4759					$this.themeFlickrZoom( opts );
4760				} );
4761			} );
4762
4763		}
4764
4765		// Lazy Load
4766		if ( $.fn.themePluginLazyLoad ) {
4767
4768			$( function() {
4769				$wrap.find( '[data-plugin-lazyload]:not(.manual)' ).each( function() {
4770					var $this = $( this ),
4771						opts;
4772
4773					var pluginOptions = $this.data( 'plugin-options' );
4774					if ( pluginOptions )
4775						opts = pluginOptions;
4776					$this.themePluginLazyLoad( opts );
4777				} );
4778
4779				if ( $wrap.find( '.porto-lazyload' ).length ) {
4780					$wrap.find( '.porto-lazyload' ).filter( function() {
4781						if ( $( this ).data( '__lazyload' ) || ( $( this ).closest( '.owl-carousel' ).length && $( this ).closest( '.owl-carousel' ).find( '.owl-item.cloned' ).length ) ) {
4782							return false;
4783						}
4784						return true;
4785					} ).themePluginLazyLoad( { effect: 'fadeIn', effect_speed: 400 } );
4786					if ( $wrap.find( '.porto-lazyload' ).closest( '.nivoSlider' ).length ) {
4787						theme.requestTimeout( function() {
4788							$wrap.find( '.nivoSlider' ).each( function() {
4789								if ( $( this ).find( '.porto-lazyload' ).length ) {
4790									$( this ).closest( '.nivoSlider' ).find( '.nivo-main-image' ).attr( 'src', $( this ).closest( '.nivoSlider' ).find( '.porto-lazyload' ).eq( 0 ).attr( 'src' ) );
4791								}
4792							} );
4793						}, 100 );
4794					}
4795					if ( $wrap.find( '.porto-lazyload' ).closest( '.porto-carousel-wrapper' ).length ) {
4796						theme.requestTimeout( function() {
4797							$wrap.find( '.porto-carousel-wrapper' ).each( function() {
4798								if ( $( this ).find( '.porto-lazyload:not(.lazy-load-loaded)' ).length ) {
4799									$( this ).find( '.slick-list' ).css( 'height', 'auto' );
4800									//$( this ).find( '.porto-lazyload:not(.lazy-load-loaded)' ).trigger( 'appear' );
4801								}
4802							} );
4803						}, 100 );
4804					}
4805				}
4806			} );
4807
4808		}
4809
4810		// Masonry
4811		if ( $.fn.themeMasonry ) {
4812
4813			$( function() {
4814				$wrap.find( '[data-plugin-masonry]:not(.manual)' ).each( function() {
4815					var $this = $( this ),
4816						opts;
4817					if ( $this.hasClass( 'elementor-row' ) ) {
4818						$this.children( '.elementor-column' ).addClass( 'porto-grid-item' );
4819					}
4820					var pluginOptions = $this.data( 'plugin-options' );
4821					if ( pluginOptions )
4822						opts = pluginOptions;
4823					$this.themeMasonry( opts );
4824				} );
4825				$wrap.find( '.posts-masonry .posts-container:not(.manual)' ).each( function() {
4826					var pluginOptions = $( this ).data( 'plugin-options' );
4827					if ( !pluginOptions ) {
4828						pluginOptions = {};
4829					}
4830					pluginOptions.itemSelector = '.post';
4831					$( this ).themeMasonry( pluginOptions );
4832				} );
4833				$wrap.find( '.page-portfolios .portfolio-row:not(.manual)' ).each( function() {
4834					if ( $( this ).closest( '.porto-grid-container' ).length > 0 || typeof $( this ).attr( 'data-plugin-masonry' ) != 'undefined' ) {
4835						return;
4836					}
4837					var $parent = $( this ).parent(), layoutMode = 'masonry', options, columnWidth = '.portfolio:not(.w2)', timer = null;
4838
4839					if ( $parent.hasClass( 'portfolios-grid' ) ) {
4840						//layoutMode = 'fitRows';
4841					} else if ( $parent.hasClass( 'portfolios-masonry' ) ) {
4842						if ( !$parent.children( '.bounce-loader' ).length ) {
4843							$parent.append( '<div class="bounce-loader"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>' );
4844						}
4845					}
4846
4847					options = {
4848						itemSelector: '.portfolio',
4849						layoutMode: layoutMode,
4850						callback: function() {
4851							timer && clearTimeout( timer );
4852							timer = setTimeout( function() {
4853								if ( typeof theme.FilterZoom !== 'undefined' ) {
4854									theme.FilterZoom.initialize( $( '.page-portfolios' ) );
4855								}
4856								$parent.addClass( 'portfolio-iso-active' );
4857							}, 400 );
4858						}
4859					};
4860					if ( layoutMode == 'masonry' ) {
4861						if ( !$parent.find( '.portfolio:not(.w2)' ).length )
4862							columnWidth = '.portfolio';
4863						options = $.extend( true, {}, options, {
4864							masonry: { columnWidth: columnWidth }
4865						} );
4866					}
4867
4868					$( this ).themeMasonry( options );
4869
4870				} );
4871				$wrap.find( '.page-members .member-row:not(.manual)' ).each( function() {
4872					$( this ).themeMasonry( {
4873						itemSelector: '.member',
4874						//layoutMode: 'fitRows',
4875						callback: function() {
4876							setTimeout( function() {
4877								if ( typeof theme.FilterZoom !== 'undefined' ) {
4878									theme.FilterZoom.initialize( $( '.page-members' ) );
4879								}
4880							}, 400 );
4881						}
4882					} );
4883				} );
4884			} );
4885
4886		}
4887
4888		// Preview Image
4889		if ( $.fn.themePreviewImage ) {
4890
4891			$( function() {
4892				$wrap.find( '.thumb-info-preview .thumb-info-image:not(.manual)' ).each( function() {
4893					var $this = $( this ),
4894						opts;
4895
4896					var pluginOptions = $this.data( 'plugin-options' );
4897					if ( pluginOptions )
4898						opts = pluginOptions;
4899
4900					$this.themePreviewImage( opts );
4901				} );
4902			} );
4903
4904		}
4905
4906		// Toggle
4907		if ( $.fn.themeToggle ) {
4908
4909			$( function() {
4910				$wrap.find( 'section.toggle:not(.manual)' ).each( function() {
4911					var $this = $( this ),
4912						opts;
4913
4914					var pluginOptions = $this.data( 'plugin-options' );
4915					if ( pluginOptions )
4916						opts = pluginOptions;
4917
4918					$this.themeToggle( opts );
4919				} );
4920			} );
4921
4922		}
4923
4924		// Parallax
4925		if ( $.fn.themeParallax ) {
4926
4927			$( function() {
4928				$wrap.find( '[data-plugin-parallax]:not(.manual)' ).each( function() {
4929					var $this = $( this ),
4930						opts;
4931					var pluginOptions = $this.data( 'plugin-options' ),
4932						parallaxScale = $this.attr( 'data-parallax-scale' );
4933					if ( pluginOptions )
4934						opts = pluginOptions;
4935
4936					if ( typeof parallaxScale !== 'undefined' ) {
4937						opts['scale'] = true;
4938						if ( parallaxScale == 'invert' ) {
4939							opts['scaleInvert'] = true;
4940						}
4941					}
4942					$this.themeParallax( opts );
4943				} );
4944			} );
4945		}
4946
4947		// Scroll InViewPort
4948		if ( $.fn.themePluginInViewportStyle ) {
4949			$( function() {
4950				$wrap.find( '[data-inviewport-style]:not(.manual)' ).each( function() {
4951					var $this = $( this ),
4952						opts = $this.data( 'plugin-options' );
4953
4954					$this.themePluginInViewportStyle( opts );
4955				} );
4956			} );
4957		}
4958
4959		// Sticky
4960		if ( $.fn.themeSticky ) {
4961
4962			$( function() {
4963				$wrap.find( '[data-plugin-sticky]:not(.manual), .porto-sticky:not(.manual), .porto-sticky-nav:not(.manual)' ).each( function() {
4964					var $this = $( this ),
4965						opts;
4966
4967					var pluginOptions = $this.data( 'plugin-options' );
4968					if ( pluginOptions )
4969						opts = pluginOptions;
4970					if ( $this.is( ':visible' ) ) {
4971						$this.themeSticky( opts );
4972					}
4973				} );
4974			} );
4975		}
4976
4977		// Float Element
4978		if ( $.fn['themePluginFloatElement'] ) {
4979
4980			$( function() {
4981				$wrap.find( '[data-plugin-float-element]:not(.manual)' ).each( function() {
4982					var $this = $( this ),
4983						opts;
4984
4985					var pluginOptions = theme.getOptions( $this.data( 'plugin-options' ) );
4986					if ( pluginOptions )
4987						opts = pluginOptions;
4988
4989					$this.themePluginFloatElement( opts );
4990				} );
4991			} );
4992		}
4993
4994		/* Common */
4995
4996		if ( typeof bootstrap != 'undefined' ) {
4997			// Tooltip
4998			var tooltipTriggerList = [].slice.call( wrapObj.querySelectorAll( "[data-bs-tooltip]:not(.manual), [data-toggle='tooltip']:not(.manual), .star-rating:not(.manual)" ) );
4999			tooltipTriggerList.map( function( tooltipTriggerEl ) {
5000				return new bootstrap.Tooltip( tooltipTriggerEl )
5001			} );
5002
5003			// bootstrap popover
5004			var popoverTriggerList = [].slice.call( wrapObj.querySelectorAll( "[data-toggle='popover']" ) );
5005			popoverTriggerList.map( function( popoverTriggerEl ) {
5006				return new bootstrap.Popover( popoverTriggerEl )
5007			} );
5008		}
5009		// Tabs
5010		$wrap.find( 'a[data-bs-toggle="tab"]' ).off( 'shown.bs.tab' ).on( 'shown.bs.tab', function( e ) {
5011			$( this ).parents( '.nav-tabs' ).find( '.active' ).removeClass( 'active' );
5012			$( this ).addClass( 'active' ).parent().addClass( 'active' );
5013		} );
5014
5015		if ( $.fn.vcwaypoint ) {
5016			// Progress bar tooltip
5017			$wrap.find( '.vc_progress_bar' ).each( function() {
5018				var $this = $( this );
5019				if ( !$this.find( '.progress-bar-tooltip' ).length ) {
5020					return;
5021				}
5022				$this.vcwaypoint( function() {
5023					var $tooltips = $this.find( '.progress-bar-tooltip' ),
5024						index = 0,
5025						count = $tooltips.length;
5026					function loop() {
5027						theme.requestTimeout( function() {
5028							$tooltips.animate( {
5029								opacity: 1
5030							} );
5031						}, 200 );
5032						index++;
5033						if ( index < count ) {
5034							loop();
5035						}
5036					}
5037					loop();
5038				}, {
5039					offset: '85%'
5040				} );
5041			} );
5042		}
5043
5044		// call async functions
5045		if ( typeof theme.initAsync == 'function' ) {
5046			theme.initAsync( $wrap, wrapObj );
5047		} else {
5048			$( document.body ).on( 'porto_async_init', function() {
5049				theme.initAsync( $wrap, wrapObj );
5050			} );
5051		}
5052
5053	} )( jQuery );
5054
5055
5056	jQuery( document.body ).trigger( 'porto_init', [$wrap] );
5057}
5058
5059( function( theme, $ ) {
5060
5061	'use strict';
5062
5063	$( document ).ready( function() {
5064		// update adminbar height
5065		var win_width = 0;
5066		$( window ).smartresize( function() {
5067			if ( win_width != window.innerWidth ) {
5068				theme.adminBarHeightNum = null;
5069				win_width = window.innerWidth;
5070			}
5071		} );
5072
5073		// Scroll to Top
5074		if ( typeof theme.ScrollToTop !== 'undefined' ) {
5075			theme.ScrollToTop.initialize();
5076		}
5077		setTimeout( function() {
5078			// Init Porto Theme
5079			porto_init();
5080		}, 0 );
5081
5082		( function() {
5083			theme.bodyWidth = theme.bodyWidth || document.body.offsetWidth;
5084			// Mega Menu
5085			if ( typeof theme.MegaMenu !== 'undefined' ) {
5086				theme.MegaMenu.initialize();
5087			}
5088			// Sidebar Menu
5089			if ( typeof theme.SidebarMenu !== 'undefined' ) {
5090				theme.SidebarMenu.initialize();
5091
5092				$( '.sidebar-menu.side-menu-accordion' ).themeAccordionMenu( { 'open_one': true } );
5093			}
5094		} )();
5095		( function() {
5096			// Overlay Menu
5097			if ( $( '.porto-popup-menu' ).length ) {
5098				$( '.porto-popup-menu .hamburguer-btn' ).on( 'click', function( e ) {
5099					e.preventDefault();
5100					var $this = $( this );
5101					if ( $( '.porto-popup-menu-spacer' ).length ) {
5102						$( '.porto-popup-menu-spacer' ).remove();
5103					} else {
5104						$( '<div class="porto-popup-menu-spacer"></div>' ).insertBefore( $this.parent() );
5105						$( '.porto-popup-menu-spacer' ).width( $this.parent().width() );
5106					}
5107					$this.parent().toggleClass( 'opened' );
5108					theme.requestFrame( function() {
5109						$this.toggleClass( 'active' );
5110					} );
5111				} );
5112				$( '.porto-popup-menu .main-menu' ).scrollbar();
5113				$( '.porto-popup-menu' ).on( 'click', 'li.menu-item-has-children > a', function( e ) {
5114					e.preventDefault();
5115					$( this ).parent().siblings( 'li.menu-item-has-children.opened' ).removeClass( 'opened' );
5116					$( this ).parent().toggleClass( 'opened' );
5117				} );
5118			}
5119			// Lazy load Menu
5120			if ( js_porto_vars.lazyload_menu ) {
5121				var menu_type, $menu_obj;
5122				if ( $( '.secondary-menu.mega-menu' ).length ) {
5123					menu_type = 'secondary_menu';
5124					$menu_obj = $( '.secondary-menu.mega-menu' );
5125					menu_lazyload( $menu_obj, menu_type );
5126				}
5127				if ( $( '.mega-menu.main-menu:not(.scroll-wrapper):not(.secondary-menu)' ).length ) {
5128					menu_type = 'main_menu';
5129					$menu_obj = $( '.mega-menu.main-menu:not(.scroll-wrapper):not(.secondary-menu)' );
5130					menu_lazyload( $menu_obj, menu_type );
5131				}
5132				if ( $( '.toggle-menu-wrap .sidebar-menu' ).length ) {
5133					menu_type = 'toggle_menu';
5134					$menu_obj = $( '.toggle-menu-wrap .sidebar-menu' );
5135					menu_lazyload( $menu_obj, menu_type );
5136				}
5137				if ( $( '.main-sidebar-menu .sidebar-menu' ).length ) {
5138					menu_type = 'sidebar_menu';
5139					$menu_obj = $( '.main-sidebar-menu .sidebar-menu' );
5140					$menu_obj.each( function() {
5141						let $menu_item = $( this );
5142						menu_lazyload( $menu_item, menu_type, $menu_item.closest( '.main-sidebar-menu' ).data( 'menu' ) );
5143					} );
5144
5145				}
5146				if ( $( '.header-side-nav .sidebar-menu' ).length ) {
5147					menu_type = 'header_side_menu';
5148					$menu_obj = $( '.header-side-nav .sidebar-menu' );
5149					menu_lazyload( $menu_obj, menu_type );
5150				}
5151
5152				if ( $( '#nav-panel .skeleton-body, #side-nav-panel .skeleton-body' ).length && 'pageload' == js_porto_vars.lazyload_menu ) {
5153					theme.lazyload_menu( 1, 'mobile_menu' );
5154				}
5155
5156				function menu_lazyload( $menu_item, menu_type, menu_id ) {
5157					var porto_menu_loaded = false;
5158					if ( 'pageload' == js_porto_vars.lazyload_menu ) {
5159						theme.lazyload_menu( $menu_item, menu_type, menu_id );
5160					} else if ( 'firsthover' == js_porto_vars.lazyload_menu ) {
5161						$menu_item.one( 'mouseenter touchstart', 'li.menu-item-has-children', function() {
5162							if ( porto_menu_loaded ) {
5163								return true;
5164							}
5165							theme.lazyload_menu( $menu_item, menu_type, menu_id );
5166							porto_menu_loaded = true;
5167						} );
5168					}
5169				}
5170			}
5171			// Side Navigation
5172			if ( typeof theme.SideNav !== 'undefined' ) {
5173				theme.SideNav.initialize();
5174			}
5175		} )();
5176
5177		setTimeout( () => {
5178			// Sticky Header
5179			if ( typeof theme.StickyHeader !== 'undefined' ) {
5180				theme.StickyHeader.initialize();
5181			}
5182			// Hash Scroll
5183			if ( typeof theme.HashScroll !== 'undefined' ) {
5184				theme.HashScroll.initialize();
5185			}
5186		} );
5187
5188
5189		// Common
5190
5191		// skeleton screens
5192		if ( js_porto_vars.use_skeleton_screen.length > 0 && $( '.skeleton-loading' ).length ) {
5193			var dclFired = false,
5194				dclPromise = ( function() {
5195					var deferred = $.Deferred();
5196					$( function() {
5197						deferred.resolve();
5198						dclFired = true;
5199					} );
5200					return deferred.promise();
5201				} )(),
5202				observer = false,
5203				NativeMutationObserver = window.MutationObserver || window.WebkitMutationObserver || window.MozMutationObserver;
5204			if ( typeof NativeMutationObserver != 'undefined' ) {
5205				observer = new NativeMutationObserver( function( mutationsList, observer ) {
5206					for ( var i in mutationsList ) {
5207						var mutation = mutationsList[i];
5208						if ( mutation.type == 'childList' ) {
5209							$( mutation.target ).trigger( 'skeleton:initialised' );
5210						}
5211					}
5212				} );
5213			}
5214			var killObserverTrigger = setTimeout( function() {
5215				if ( observer ) {
5216					observer.disconnect();
5217					observer = undefined;
5218				}
5219			}, 4000 );
5220			var skeletonTimer;
5221			$( '.skeleton-loading' ).each( function( e ) {
5222				var $this = $( this ),
5223					skeletonInitialisedPromise = ( function() {
5224						var deferred = $.Deferred();
5225						$this.on( 'skeleton:initialised', function( evt ) {
5226							if ( evt.target.classList.contains( 'skeleton-loading' ) ) {
5227								deferred.resolve( evt );
5228							}
5229						} );
5230						return deferred.promise();
5231					} )(),
5232					resourcesLoadedPromise = ( function() {
5233						return $.Deferred().resolve().promise();
5234					} )();
5235				$.when( skeletonInitialisedPromise, resourcesLoadedPromise, dclPromise ).done( function( e ) {
5236					var $real = $( e.target ),
5237						$placeholder = $real.siblings( '.skeleton-body' );
5238					if ( !$placeholder.length ) {
5239						$placeholder = $real.parent().parent().parent().find( '[class="' + $real.attr( 'class' ).replace( 'skeleton-loading', 'skeleton-body' ) + '"]' );
5240					}
5241					porto_init( $real );
5242					if ( $real.find( '.sidebar-menu:not(.side-menu-accordion)' ).length ) {
5243						theme.SidebarMenu.initialize( $real.find( '.sidebar-menu:not(.side-menu-accordion)' ) );
5244					}
5245					if ( skeletonTimer ) {
5246						theme.deleteTimeout( skeletonTimer );
5247					}
5248					$real.trigger( 'skeleton-loaded' );
5249					theme.requestTimeout( function() {
5250						if ( $placeholder.length ) {
5251							// fix YITH Products Filters compatibility issue
5252							if ( $placeholder.parent().hasClass( 'yit-wcan-container' ) ) {
5253								$placeholder.parent().remove();
5254							} else {
5255								$placeholder.remove();
5256							}
5257						}
5258						$real.removeClass( 'skeleton-loading' );
5259						if ( $real.closest( '.skeleton-loading-wrap' ) ) {
5260							$real.closest( '.skeleton-loading-wrap' ).removeClass( 'skeleton-loading-wrap' );
5261						}
5262						if ( $( document.body ).hasClass( 'elementor-default' ) || $( document.body ).hasClass( 'elementor-page' ) ) {
5263							$( window ).trigger( 'resize' );
5264						}
5265						theme.refreshStickySidebar( false );
5266					}, 100 );
5267					if ( !$( '.skeleton-loading' ).length ) {
5268						clearTimeout( killObserverTrigger );
5269						observer.disconnect();
5270						observer = undefined;
5271					}
5272				} );
5273				if ( $this.children( 'script[type="text/template"]' ).length ) {
5274					var content = $( JSON.parse( $this.children( 'script[type="text/template"]' ).eq( 0 ).html() ) );
5275					$this.children( 'script[type="text/template"]' ).eq( 0 ).remove();
5276					if ( observer ) {
5277						observer.observe( this, { childList: true, subtree: false } );
5278					}
5279					$this.append( content );
5280					if ( !observer ) {
5281						$this.trigger( 'skeleton:initialised' );
5282					}
5283				}
5284			} );
5285		}
5286
5287		$( document ).trigger( 'porto_theme_init' );
5288
5289	} );
5290	$( window ).on( 'load', function() {
5291		setTimeout( function() {
5292			// Search
5293			if ( typeof theme.Search !== 'undefined' ) {
5294				theme.Search.initialize();
5295			}
5296		}, 0 );
5297		// Sort Filter
5298		if ( typeof theme.SortFilter !== 'undefined' ) {
5299			theme.SortFilter.initialize();
5300		}
5301
5302		// Mobile Sidebar
5303		// filter popup events
5304		$( document ).on( 'click', '.sidebar-toggle', function( e ) {
5305			e.preventDefault();
5306			var $html = $( 'html' ),
5307				$main = $( '#main' );
5308			if ( $( this ).siblings( '.porto-product-filters' ).length ) {
5309				if ( $html.hasClass( 'filter-sidebar-opened' ) ) {
5310					$html.removeClass( 'filter-sidebar-opened' );
5311					$( '.sidebar-overlay' ).removeClass( 'active' );
5312					if ( $html.hasClass( 'sidebar-right-opened' ) ) {
5313						$html.removeClass( 'sidebar-right-opened' );
5314					}
5315				} else {
5316					$html.removeClass( 'sidebar-opened' );
5317					$html.addClass( 'filter-sidebar-opened' );
5318					$( '.sidebar-overlay' ).addClass( 'active' );
5319					if ( $main.hasClass( 'column2-right-sidebar' ) || $main.hasClass( 'column2-wide-right-sidebar' ) ) {
5320						$html.addClass( 'sidebar-right-opened' );
5321					}
5322				}
5323			} else {
5324				if ( $html.hasClass( 'sidebar-opened' ) ) {
5325					$html.removeClass( 'sidebar-opened' );
5326					$( '.sidebar-overlay' ).removeClass( 'active' );
5327					if ( $html.hasClass( 'sidebar-right-opened' ) ) {
5328						$html.removeClass( 'sidebar-right-opened' );
5329					}
5330				} else {
5331					$html.addClass( 'sidebar-opened' );
5332					$( '.sidebar-overlay' ).addClass( 'active' );
5333					//$( '.mobile-sidebar' ).find( '.porto-lazyload:not(.lazy-load-loaded)' ).trigger( 'appear' );
5334					if ( $main.hasClass( 'column2-right-sidebar' ) || $main.hasClass( 'column2-wide-right-sidebar' ) ) {
5335						$html.addClass( 'sidebar-right-opened' );
5336					}
5337				}
5338			}
5339		} );
5340
5341		$( '.minicart-offcanvas .cart-head' ).on( 'click', function() {
5342			$( this ).closest( '.minicart-offcanvas' ).toggleClass( 'minicart-opened' );
5343		} );
5344		$( '.minicart-offcanvas .minicart-overlay' ).on( 'click', function() {
5345			$( this ).closest( '.minicart-offcanvas' ).removeClass( 'minicart-opened' );
5346		} );
5347
5348		$( document.body ).on( 'click', '.sidebar-overlay', function() {
5349			var $html = $( 'html' ); 
5350			$html.removeClass( 'sidebar-opened' );
5351			$html.removeClass( 'filter-sidebar-opened' );
5352			$( this ).removeClass( 'active' );
5353			$html.removeClass( 'sidebar-right-opened' );
5354		} );
5355
5356		// Section Tab
5357		$( document.body ).on( 'click', '.section-tabs .nav-link', function( e ) {
5358			e.preventDefault();
5359			var $this = $( this ),
5360				nav_id = $this.data( 'tab' ),
5361				$section_tab = $this.closest( '.section-tabs' ),
5362				$nav_wrap = $section_tab.children( 'ul.nav' ),
5363				$tab_content = $section_tab.children( '.tab-content' );
5364			if ( nav_id ) {
5365				// Nav Item
5366				$nav_wrap.find( '.active' ).removeClass( 'active' );
5367				$this.addClass( 'active' ).parent( '.nav-item' ).addClass( 'active' );
5368
5369				// Content Item
5370				$tab_content.find( '>.active' ).removeClass( 'active' );
5371				$tab_content.find( '>.tab-pane[id="' + nav_id + '"]' ).addClass( 'active' );
5372			}
5373		} );
5374
5375		$( window ).on( 'resize', function( e ) {
5376			if ( e.originalEvent && window.innerWidth > 991 && $( 'html' ).hasClass( 'sidebar-opened' ) ) {
5377				$( '.sidebar-overlay' ).trigger( 'click' );
5378			}
5379		} );
5380
5381		// Match Height
5382		var $matchHeightObj = $( '.tabs-simple .featured-box .box-content, .porto-content-box .featured-box .box-content, .vc_general.vc_cta3, .match-height' );
5383		if ( $matchHeightObj.length ) {
5384			if ( $.fn.matchHeight ) {
5385				$matchHeightObj.matchHeight();
5386			} else {
5387				var script = document.createElement( "script" );
5388				script.addEventListener( "load", function( event ) {
5389					$matchHeightObj.matchHeight();
5390				} );
5391				script.src = js_porto_vars.ajax_loader_url.replace( '/images/[email protected]', '/js/libs/jquery.matchHeight.min.js' );
5392				script.async = true;
5393				document.body.appendChild( script );
5394			}
5395		}
5396
5397		// WhatsApp Sharing
5398		if ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ) {
5399			$( '.share-whatsapp' ).css( 'display', 'inline-block' );
5400		}
5401		$( document ).ajaxComplete( function( event, xhr, options ) {
5402			if ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ) {
5403				$( '.share-whatsapp' ).css( 'display', 'inline-block' );
5404			}
5405		} );
5406
5407		// Add Ege Browser Class
5408		var ua = window.navigator.userAgent,
5409			ie12 = ua.indexOf( 'Edge/' ) > 0;
5410		if ( ie12 ) $( 'html' ).addClass( 'ie12' );
5411
5412		// Portfolio Link Lightbox
5413		$( document ).on( 'click', '.portfolios-lightbox a.portfolio-link', function( e ) {
5414			$( this ).find( '.thumb-info-zoom' ).trigger( 'click' );
5415			return false;
5416		} );
5417
5418		$( '.porto-faqs' ).each( function() {
5419			if ( $( this ).find( '.faq .toggle.active' ).length < 1 ) {
5420				$( this ).find( '.faq' ).eq( 0 ).find( '.toggle' ).addClass( 'active' );
5421				$( this ).find( '.faq' ).eq( 0 ).find( '.toggle-content' ).show();
5422			}
5423		} );
5424
5425		// refresh wpb content
5426		$( document ).on( 'shown.bs.collapse', '.collapse', function() {
5427			var panel = $( this );
5428			theme.refreshVCContent( panel );
5429		} );
5430		$( document ).on( 'shown.bs.tab', 'a[data-bs-toggle="tab"]', function( e ) {
5431			var panel = $( $( e.target ).attr( 'href' ) );
5432			theme.refreshVCContent( panel );
5433		} );
5434
5435		// porto tooltip for header, footer
5436		$( '.porto-tooltip .tooltip-icon' ).on( 'click', function() {
5437			if ( $( this ).parent().children( ".tooltip-popup" ).css( "display" ) == "none" ) {
5438				$( this ).parent().children( ".tooltip-popup" ).fadeIn( 200 );
5439			} else {
5440				$( this ).parent().children( ".tooltip-popup" ).fadeOut( 200 );
5441			}
5442		} );
5443		$( '.porto-tooltip .tooltip-close' ).on( 'click', function() {
5444			$( this ).parent().fadeOut( 200 );
5445		} );
5446	} );
5447
5448} ).apply( this, [window.theme, jQuery] );
5449
5450( function( theme, $, undefined ) {
5451	"use strict";
5452
5453	$( document ).ready( function() {
5454		$( window ).on( 'vc_reload', function() {
5455			porto_init();
5456			$( '.type-post' ).addClass( 'post' );
5457			$( '.type-portfolio' ).addClass( 'portfolio' );
5458			$( '.type-member' ).addClass( 'member' );
5459			$( '.type-block' ).addClass( 'block' );
5460		} );
5461	} );
5462
5463	/*
5464	* Experience Timeline
5465	*/
5466	var timelineHeightAdjust = {
5467		$timeline: $( '#exp-timeline' ),
5468		$timelineBar: $( '#exp-timeline .timeline-bar' ),
5469		$firstTimelineItem: $( '#exp-timeline .timeline-box' ).first(),
5470		$lastTimelineItem: $( '#exp-timeline .timeline-box' ).last(),
5471
5472		build: function() {
5473			var self = this;
5474
5475			self.adjustHeight();
5476		},
5477		adjustHeight: function() {
5478			var self = this,
5479				calcFirstItemHeight = ( self.$firstTimelineItem.outerHeight( true ) / 2 ) + 5,
5480				calcLastItemHeight = ( self.$lastTimelineItem.outerHeight( true ) / 2 ) + 5;
5481
5482			// Set Timeline Bar Top and Bottom
5483			self.$timelineBar.css( {
5484				top: calcFirstItemHeight,
5485				bottom: calcLastItemHeight
5486			} );
5487		}
5488	}
5489
5490	if ( $( '#exp-timeline' ).get( 0 ) ) {
5491		// Adjust Timeline Height On Resize
5492		var timeline_timer = null;
5493		$( window ).smartresize( function() {
5494			if ( timeline_timer ) {
5495				clearTimeout( timeline_timer );
5496			}
5497			timeline_timer = setTimeout( function() {
5498				timelineHeightAdjust.build();
5499			}, 800 );
5500		} );
5501
5502		timelineHeightAdjust.build();
5503	}
5504
5505	$( '.custom-view-our-location' ).on( 'click', function( e ) {
5506		e.preventDefault();
5507		var this_ = $( this );
5508		$( '.custom-googlemap' ).slideDown( '1000', function() {
5509			this_.delay( 700 ).hide();
5510		} );
5511	} );
5512
5513} )( window.theme, jQuery );
5514
5515// Porto 4.0 extra shortcodes
5516( function( theme, $, undefined ) {
5517	'use strict';
5518
5519	window.onload = function() {
5520		theme.isLoaded = true;
5521	};
5522
5523	$( document ).ready( function() {
5524		if ( typeof elementorFrontend != 'undefined' ) {
5525			// fix Elementor ScrollTop
5526			$( window ).on( 'elementor/frontend/init', function() {
5527				elementorFrontend.hooks.addFilter( 'frontend/handlers/menu_anchor/scroll_top_distance', function( scrollTop ) {
5528					if ( theme && theme.StickyHeader && typeof theme.sticky_nav_height != 'undefined' ) {
5529						if ( elementorFrontend.elements.$wpAdminBar.length ) {
5530							scrollTop += elementorFrontend.elements.$wpAdminBar.height();
5531						}
5532						scrollTop = scrollTop - theme.adminBarHeight() - theme.StickyHeader.sticky_height - theme.sticky_nav_height + 1;
5533					}
5534					return scrollTop;
5535				} );
5536			} );
5537		}
5538
5539		if ( js_porto_vars.user_edit_pages ) {
5540			var porto_init_builder_tooltip = function( obj ) {
5541				var tooltipTriggerList = [].slice.call( obj.querySelectorAll( '.pb-edit-link' ) );
5542				tooltipTriggerList.map( function( o ) {
5543					var title = o.getAttribute( 'data-title' );
5544					if ( o.nextSibling && o.nextSibling.classList.contains( 'porto-block' ) ) {
5545						var tooltipobj = o.nextSibling;
5546						tooltipobj.classList.add( 'has-pb-edit' );
5547						var tooltip_ins = new bootstrap.Tooltip( tooltipobj, {
5548							html: true,
5549							template: '<div class="tooltip porto-tooltip-wrap" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
5550							trigger: 'manual',
5551							title: '<a href="' + o.getAttribute( 'data-link' ) + '"><i class="porto-icon-edit me-1"></i>' + title + '</a>',
5552							delay: 300
5553						} );
5554						if ( tooltip_ins && tooltip_ins._element ) {
5555							tooltip_ins._element.addEventListener( 'mouseenter', function( e ) {
5556								tooltip_ins._enter( e, tooltip_ins );
5557							} );
5558							tooltip_ins._element.addEventListener( 'mouseleave', function( e ) {
5559								tooltip_ins._leave( e, tooltip_ins );
5560							} );
5561						}
5562					}
5563
5564					o.parentNode.removeChild( o );
5565				} );
5566			};
5567			porto_init_builder_tooltip( document.body );
5568			$( '.skeleton-loading' ).on( 'skeleton-loaded', function() {
5569				porto_init_builder_tooltip( this );
5570			} );
5571			$( document.body ).on( 'mouseenter mouseleave', '.porto-tooltip-wrap[role="tooltip"]', function( e ) {
5572				var $element = $( '.porto-block[aria-describedby="' + $( this ).attr( 'id' ) + '"]' );
5573				if ( $element.length ) {
5574					var ins = bootstrap.Tooltip.getInstance( $element.get( 0 ) );
5575					if ( ins ) {
5576						var fn_name = 'mouseenter' == e.type ? '_enter' : '_leave';
5577						ins[fn_name]( e, ins );
5578					}
5579				}
5580			} ).on( 'porto_init_start', function( e, wrapObj ) {
5581				// init edit tooltip
5582				if ( wrapObj.classList.contains( 'porto-posts-grid' ) ) {
5583					porto_init_builder_tooltip( wrapObj );
5584				}
5585			} );
5586		}
5587	} );
5588
5589	/* Advanced Buttons */
5590	$( '.porto-btn[data-hover]' ).on( 'mouseenter', function() {
5591		var hoverColor = $( this ).data( 'hover' ),
5592			hover_border_color = $( this ).data( 'border-hover' );
5593		if ( hoverColor ) {
5594			$( this ).data( 'originalColor', $( this ).css( 'color' ) );
5595			$( this ).css( 'color', hoverColor );
5596		}
5597		if ( hover_border_color ) {
5598			$( this ).data( 'originalBorderColor', $( this ).css( 'border-color' ) );
5599			$( this ).css( 'border-color', hover_border_color );
5600		}
5601	} ).on( 'mouseleave', function() {
5602		var originalColor = $( this ).data( 'originalColor' ),
5603			original_border_color = $( this ).data( 'originalBorderColor' );
5604		if ( originalColor ) {
5605			$( this ).css( 'color', originalColor );
5606		}
5607		if ( original_border_color ) {
5608			$( this ).css( 'border-color', original_border_color );
5609		}
5610	} );
5611
5612	// widget wysija
5613	$( '#footer .widget_wysija .wysija-submit:not(.btn)' ).addClass( 'btn btn-default' );
5614
5615	// fixed visual compoer issue which has owl carousel
5616	if ( $( '[data-vc-parallax] .owl-carousel' ).length ) {
5617		theme.requestTimeout( function() { if ( typeof window.vcParallaxSkroll == 'object' ) { window.vcParallaxSkroll.refresh(); } }, 200 );
5618	}
5619
5620	if ( $( '.page-content > .alignfull, .post-content > .alignfull' ).length ) {
5621		var initAlignFull = function() {
5622			$( '.page-content > .alignfull, .post-content > .alignfull' ).each( function() {
5623				$( this ).css( 'left', -1 * $( this ).parent().offset().left ).css( 'right', -1 * $( this ).parent().offset().left ).css( 'width', $( 'body' ).width() - ( parseInt( $( this ).css( 'margin-left' ), 10 ) + parseInt( $( this ).css( 'margin-right' ), 10 ) ) );
5624			} );
5625		};
5626		initAlignFull();
5627		$( window ).smartresize( function() {
5628			initAlignFull();
5629		} );
5630	}
5631} )( window.theme, jQuery );
5632
5633// Porto Sticky icon bar on mobile
5634( function( theme, $ ) {
5635	'use strict';
5636
5637	var $header_main = $( '#header .header-main' );
5638	var $menu_wrap = $( '#header .main-menu-wrap' );
5639	if ( $( '.porto-sticky-navbar' ).length > 0 ) {
5640		window.addEventListener( 'scroll', function() {
5641			if ( window.innerWidth < 576 ) {
5642				var headerOffset = -1;
5643				var scrollTop = $( window ).scrollTop();
5644
5645				if ( $header_main.length ) {
5646					headerOffset = Math.max( $header_main.scrollTop() + $header_main.height(), headerOffset );
5647				}
5648				if ( $menu_wrap.length ) {
5649					headerOffset = Math.max( $menu_wrap.scrollTop() + $menu_wrap.height(), headerOffset );
5650				}
5651				if ( headerOffset <= 0 ) {
5652					if ( $( '#header' ).length > 0 && $( '#header' ).height() > 10 ) headerOffset = $( '#header' ).scrollTop() + $( '#header' ).height();
5653					else headerOffset = 100;
5654				}
5655				if ( headerOffset <= scrollTop ) {
5656					$( '.porto-sticky-navbar' ).addClass( 'fixed' );
5657				} else {
5658					$( '.porto-sticky-navbar' ).removeClass( 'fixed' );
5659				}
5660			}
5661		}, { passive: true } );
5662	}
5663} )( 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.