PageSourceSearch

https://www.obdlink.com/wp-content/uploads/bb-plugin/cache/b9ec5b9…e7c4a6cc0-layout-bundle.js?ver=2.11.0.3-1.6

js obdlink.com collected 2026-09-24 18:12:50 UTC 50,157 bytes, 1,652 lines download raw bytes

1
2;(function($) {
3	$(function() {
4
5		// FitVids
6		if ( 'undefined' !== typeof $.fn.fitVids ) {
7			$('.fl-module-fl-post-content').fitVids( {
8				ignore: '.wp-block-embed *'
9			} );
10		}
11
12	});
13})(jQuery);
14
15/* Start Layout Custom JS */
16
17/* End Layout Custom JS */
18
19
20
21;/* eslint-disable no-undef */
22(function($) {
23
24	/**
25	 * Class for Menu Module
26	 *
27	 * @since 1.6.1
28	 */
29	FLBuilderMenu = function( settings ){
30
31		// set params
32		this.nodeId              = settings.id;
33		this.nodeClass           = '.fl-node-' + settings.id;
34		this.wrapperClass        = this.nodeClass + ' .fl-menu';
35		this.type				 				 = settings.type;
36		this.mobileToggle		     = settings.mobile;
37		this.mobileBelowRow		   = settings.mobileBelowRow;
38		this.mobileFlyout		     = settings.mobileFlyout;
39		this.breakPoints         = settings.breakPoints;
40		this.mobileBreakpoint	 	 = settings.mobileBreakpoint;
41		this.currentBrowserWidth = $( window ).width();
42		this.postId              = settings.postId;
43		this.mobileStacked       = settings.mobileStacked;
44		this.submenuIcon         = settings.submenuIcon;
45		this.flyoutWidth         = settings.flyoutWidth;
46
47		// initialize the menu
48		this._initMenu();
49
50		// check if viewport is resizing
51		$( window ).on( 'resize', $.proxy( function() {
52
53			var width = $( window ).width();
54
55			// if screen width is resized, reload the menu
56		    if( width != this.currentBrowserWidth ){
57
58				this.currentBrowserWidth = width;
59				this._initMenu( true );
60 				this._clickOrHover( true );
61			}
62
63			this._resizeFlyoutMenuPanel();
64		}, this ) );
65
66		$( window ).on( 'scroll', $.proxy( function() {
67			this._resizeFlyoutMenuPanel();
68		}, this ) );
69
70		// Move focus to the first menu item if the layout is set to BelowRow
71		$( this.wrapperClass ).on( 'keydown', '.fl-menu-mobile-toggle, .menu-item:first a:first', $.proxy( function ( event ) {
72			// Make sure it is a tab key with both the menu toggle enabled & below row layout set
73			if ( event.key !== 'Tab' || ! this._isMenuToggle() || ! this._isMobileBelowRowEnabled() ) {
74				return;
75			}
76			// Trigger focus on the mobile toggle button if the user is shift tabbing from the first menu item
77			if ( event.shiftKey && $( event.currentTarget ).is( 'a' ) ) {
78				event.preventDefault();
79				$( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).trigger( 'focus' );
80			}
81			// Trigger focus on the first menu item if the user is tabbing from the mobile toggle button
82			else if ( ! event.shiftKey && $( event.currentTarget ).hasClass( 'fl-menu-mobile-toggle' ) && $( event.currentTarget ).hasClass( 'fl-active' )  ) {
83				event.preventDefault();
84				$( this.wrapperClass ).find( '.menu-item' ).first().find( 'a' ).first().trigger( 'focus' );
85			}
86		}, this ) );
87
88		// Close mobile menu or accordion when tabbing out from the first or last menu item
89		$( this.wrapperClass ).on( 'focusout', $.proxy( function ( event ) {
90			if ( $( this.wrapperClass + ' nav' ).has( $( event.relatedTarget ) ).length === 0 ) {
91				if ( this.type === 'accordion' ) {
92					this._toggleSubmenu( $( event.target ).parents( '.fl-has-submenu' ).last(), false );
93				}
94				else {
95					this._clickOrHover( true );
96				}
97				const mobileToggle = $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' );
98				if ( this._isMenuToggle() && mobileToggle.hasClass( 'fl-active' ) && ! $( event.relatedTarget ).is( mobileToggle ) && 'expanded' !== this.mobileToggle ) {
99					mobileToggle.trigger( 'click' );
100				}
101			}
102		}, this ) );
103
104	};
105
106	FLBuilderMenu.prototype = {
107		nodeClass		: '',
108		wrapperClass: '',
109		type				: '',
110		breakPoints	: {},
111		$submenus		: null,
112
113		/**
114		 * Check if the screen size fits a mobile viewport.
115		 *
116		 * @since  1.6.1
117		 * @return bool
118		 */
119		_isMobile: function(){
120			return this.currentBrowserWidth <= this.breakPoints.small ? true : false;
121		},
122
123		/**
124		 * Check if the device is connected to a mouse.
125		 * 
126		 * @since  2.9.0
127		 * @return bool
128		 */
129		_isMouseAvailable: function(){
130			return window.matchMedia("(pointer: fine) and (hover: hover)").matches;
131		},
132
133		/**
134		 * Check if the screen size fits a medium viewport.
135		 *
136		 * @since  1.10.5
137		 * @return bool
138		 */
139		_isMedium: function(){
140			return this.currentBrowserWidth <= this.breakPoints.medium ? true : false;
141		},
142
143		/**
144		 * Check if the screen size fits a large viewport.
145		 *
146		 * @since  1.10.5
147		 * @return bool
148		 */
149		_isLarge: function(){
150			return this.currentBrowserWidth <= this.breakPoints.large ? true : false;
151		},
152
153		/**
154		 * Check if the menu should toggle for the current viewport base on the selected breakpoint.
155		 *
156		 * @see 	 this._isMobile()
157		 * @see 	 this._isMedium()
158		 * @since  1.10.5
159		 * @return bool
160		 */
161		_isMenuToggle: function(){
162			if ( ( 'always' == this.mobileBreakpoint
163				|| ( this._isMobile() && 'mobile' == this.mobileBreakpoint )
164				|| ( this._isMedium() && 'medium-mobile' == this.mobileBreakpoint )
165				|| ( this._isLarge() && 'large-mobile' == this.mobileBreakpoint )
166			) && ( $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).is(':visible') || 'expanded' == this.mobileToggle ) ) {
167				return true;
168			}
169
170			return false;
171		},
172
173		/**
174		 * Initialize the toggle logic for the menu.
175		 *
176		 * @see    this._isMenuToggle()
177		 * @see    this._menuOnCLick()
178		 * @see    this._clickOrHover()
179		 * @see    this._submenuOnRight()
180		 * @see    this._submenuRowZindexFix()
181		 * @see    this._toggleForMobile()
182		 * @since  1.6.1
183		 * @return void
184		 */
185		_initMenu: function( resized = false ){
186			this._setupSubmenu();
187			if ( ! resized ) {
188				this._menuOnFocus();
189				this._menuOnClick();
190				this._menuOnEscape();
191			}
192			if ( $( this.nodeClass ).length && this.type == 'horizontal' ) {
193				this._initMegaMenus();
194			}
195
196			if( this._isMenuToggle() || this.type == 'accordion' ){
197
198				$( this.wrapperClass ).off( 'mouseenter mouseleave' );
199				this._clickOrHover();
200
201			} else {
202				this._submenuOnRight();
203				this._submenuRowZindexFix();
204			}
205
206			if( this.mobileToggle != 'expanded' ){
207				this._toggleForMobile();
208			}
209
210			if( $( this.wrapperClass ).find( '.fl-menu-search-item' ).length ){
211				this._toggleMenuSearch();
212			}
213
214			if( $( this.wrapperClass ).find( '.fl-menu-cart-item').length ){
215				this._wooUpdateParams();
216			}
217		},
218
219		/**
220		 * Whether the toggle behavior for submenus is through hovering or not.
221		 *
222		 * @since  2.5
223		 * @return void
224		 */
225		_setupSubmenu: function() {
226			if ( ! this._isMouseAvailable() || this._isMenuToggle() || this.type === 'accordion' ) {
227				$( this.wrapperClass ).addClass( 'no-hover' );
228			}
229			else {
230				$( this.wrapperClass ).removeClass( 'no-hover' );
231			}
232		},
233
234		/**
235		 * Logic for menu items when focused.
236		 *
237		 * @since  1.9.0
238		 * @return void
239		 */
240		_menuOnFocus: function(){
241			$( this.wrapperClass ).on( 'focus', 'a:not(.fl-button), .fl-menu-toggle', $.proxy( function( event ) {
242				const focusedMenuItem = $( event.currentTarget ).closest( '.menu-item' );
243				const blurredMenuItem = $( event.relatedTarget ).closest( '.menu-item' );
244				// In case the blurred & focused items are siblings
245				if ( focusedMenuItem.closest( 'ul' ).is( blurredMenuItem.closest( 'ul' ) ) )	{
246					// Check if the focus event is not between the link & submenu icon of the same menu item
247					if ( ! focusedMenuItem.is( blurredMenuItem ) ) {
248						this._toggleSubmenu( blurredMenuItem, false );
249					}
250				}
251				// In case neither items are child & parent nor vice versa
252				else if ( focusedMenuItem.has( blurredMenuItem ).length === blurredMenuItem.has( focusedMenuItem ).length ) {
253					// Get the blurred item parent & is the sibling of the focused item
254					blurredMenuItem.parents( '.fl-has-submenu' ).each( ( _, parent ) => {
255						if ( focusedMenuItem.closest( 'ul' ).is( $( parent ).closest( 'ul' ) ) ) {
256							this._toggleSubmenu( $( parent ), false );
257							return false;
258						}
259					} );
260				}
261				// In case the blurred item is a child of the focused item
262				else if ( focusedMenuItem.has( blurredMenuItem ).length ) {
263					if ( this.type !== 'accordion' && this.submenuIcon === 'none' ) {
264						this._toggleSubmenu( blurredMenuItem, false );
265					}
266				}
267			}, this ) );
268		},
269
270		/**
271		 * Logic for menu items when Escape key is pressed.
272		 *
273		 * @since  2.7.1
274		 * @return void
275		 */
276		_menuOnEscape: function(){
277			$( this.wrapperClass ).on( 'keydown', $.proxy( function( event ){
278				if ( event.key !== 'Escape' ) return;
279				const menuItem = $( event.target ).closest( '.menu-item' );
280				const mobileToggle = $( this.wrapperClass ).find( '.fl-menu-mobile-toggle' );
281				// In case there is a focused menu item
282				if ( menuItem.length || $( event.target ).hasClass( 'fl-menu-mobile-close' ) ) {
283					// Close the search form if it is open
284					if ( menuItem.hasClass( 'fl-menu-search-item' ) && $( this.wrapperClass ).find('.fl-search-form-input-wrap').is( ':visible' ) ) {
285						$( this.wrapperClass ).find('.fl-menu-search-item .fl-button:is(a, button:not([type="submit"]))').trigger( 'focus' );
286					}
287					// Close all the submenus of the focused menu item
288					else if ( menuItem.hasClass( 'fl-has-submenu' ) && menuItem.find( '.sub-menu' ).first().is( ':visible' ) ) {
289						this._toggleSubmenu( menuItem, false );
290					}
291					else {
292						// Shift focus to the parent while closing all its submenus
293						const parentMenuItem = menuItem.parents( '.fl-has-submenu' ).not( '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading' ).first();
294						// Close the mobile menu if there is no parent menu item and the mobile toggle is active
295						if ( parentMenuItem.length === 0 && this._isMenuToggle() && mobileToggle.hasClass( 'fl-active' ) ) {
296							// Blur to trigger the focus-out event for closing the menu
297							mobileToggle.trigger( 'blur' ).trigger( 'focus' );
298						}
299						// Close the parent submenu and shift focus to its link
300						else if ( parentMenuItem.length !== 0 ) {
301							this._toggleSubmenu( parentMenuItem, false );
302							parentMenuItem.find( 'a' ).first().trigger( 'focus' );
303						}
304					}
305				}
306				// Close the mobile menu if the mobile toggle is active
307				else if ( $( event.target ).hasClass( 'fl-menu-mobile-toggle' ) && mobileToggle.hasClass( 'fl-active' ) ) {
308					// Blur to trigger the focus-out event for closing the menu
309					mobileToggle.trigger( 'blur' ).trigger( 'focus' );
310				}
311			}, this ) );
312		},
313
314		/**
315		 * Logic for menu items when clicked.
316		 *
317		 * @since  1.6.1
318		 * @return void
319		 */
320		_menuOnClick: function(){
321			// Fallback for span elements and fake links to interact with the keyboard
322			$( this.wrapperClass ).on( 'keydown', 'a:not(.fl-button, [href]), span.fl-menu-toggle', $.proxy( function( event ) {
323				if ( event.key === 'Enter' || event.key === ' ' ) {
324					event.preventDefault();
325					$( event.currentTarget ).trigger( 'click' );
326				}
327			}, this ) );
328			$( this.wrapperClass ).on( 'click', 'a, .fl-menu-toggle', $.proxy( function( event ) {
329				// Only allow mouse clicks with accordion & mobile menus
330				if ( this._isMouseAvailable() && ! this._isMenuToggle() && event.detail && this.type !== 'accordion' ) return;
331				// Links only open & do not toggle submenus if there is either a submenu icon or an accordion layout
332				if ( $( event.currentTarget ).is( 'a' ) && ( this.submenuIcon !== 'none' || this.type === 'accordion' ) ) return;
333				const menuItem = $( event.currentTarget ).closest( '.menu-item, .fl-menu-logo' );
334				const menuLink = menuItem.find( 'a' ).first().attr( 'href' );
335				const submenuHidden = menuItem.find( '.sub-menu' ).first().is( ':hidden' );
336				if ( typeof menuLink === 'undefined' || menuLink === '#' || submenuHidden ) {
337					event.preventDefault();
338				}
339				if ( $( event.currentTarget ).hasClass( 'fl-menu-toggle' ) || submenuHidden ) {
340					this._toggleSubmenu( menuItem, submenuHidden );
341				}
342			}, this ) );
343		},
344
345		/**
346		 * Controls toggling the visibility of all submenu items for desktop & mobile.
347		 *
348		 * @since  2.10
349		 * @return void
350		 */
351		_toggleSubmenu: function ( menuItem, opened ) {
352			const togglingClass = this._isMenuToggle() || this.type === 'accordion' ? 'fl-active' : 'focus';
353			const toggleElement = this.submenuIcon === 'none' ? 'a' : '.fl-menu-toggle';
354			const hiddenMenu = '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading';
355			if ( opened && menuItem.hasClass( 'fl-has-submenu' ) && ! menuItem.is( hiddenMenu ) ) {
356				menuItem.addClass( togglingClass );
357				menuItem.find( toggleElement ).first().attr( 'aria-expanded', true );
358				if ( this._isMenuToggle() || this.type === 'accordion' ) {
359					menuItem.find( '.sub-menu' ).first().filter( ':hidden' ).slideDown();
360				}
361			}
362			else {
363				menuItem.parent().find( '.menu-item' ).removeClass( togglingClass );
364				menuItem.parent().find( '.fl-has-submenu' ).not( hiddenMenu ).find( toggleElement ).attr( 'aria-expanded', false );
365				if ( this._isMenuToggle() || this.type === 'accordion' ) {
366					menuItem.find( '.sub-menu' ).filter( ':visible' ).slideUp();
367				}
368			}
369		},
370
371		/**
372		 * Changes general styling and behavior of menus based on mobile / desktop viewport.
373		 *
374		 * @see    this._isMenuToggle()
375		 * @since  1.6.1
376		 * @return void
377		 */
378		_clickOrHover: function( clear = false ){
379			const selector = this._isMobileBelowRowEnabled() ? this.nodeClass + '-clone' : this.nodeClass;
380			this.$submenus = this.$submenus || $( selector ).find( '.sub-menu' );
381
382			const className = this._isMenuToggle() || this.type === 'accordion' ? 'fl-active' : 'focus';
383			const toggleElement = this.submenuIcon === 'none' ? 'a' : '.fl-menu-toggle';
384			const hiddenMenu = '.mega-menu.hide-heading, .mega-menu-disabled.hide-heading';
385			$( selector ).find( '.fl-has-submenu' ).not( hiddenMenu ).each( function() {
386				if( clear || ! $ ( this ).hasClass( className ) ){
387					if ( clear ) $( this ).removeClass( className );
388					$( this ).find( toggleElement ).first().attr( 'aria-expanded', false );
389					if ( className === 'fl-active' ) {
390						$( this ).find( '.sub-menu' ).fadeOut();
391					} else if ( className === 'focus' ) {
392						$( this ).find( '.sub-menu' ).css( {
393							'display' : '',
394							'opacity' : ''
395						} );
396					}
397				}
398			} );
399		},
400
401		/**
402		 * Logic to prevent submenus to go outside viewport boundaries.
403		 *
404		 * @since  1.6.1
405		 * @return void
406		 */
407		_submenuOnRight: function(){
408
409			$( this.wrapperClass )
410				.on( 'mouseenter focus', '.fl-has-submenu', $.proxy( function( e ){
411
412					if( $ ( e.currentTarget ).find('.sub-menu').length === 0 ) {
413						return;
414					}
415
416					var $link           = $( e.currentTarget ),
417						$parent         = $link.parent(),
418						$subMenu        = $link.find( '.sub-menu' ),
419						subMenuWidth    = $subMenu.width(),
420						subMenuPos      = 0,
421						bodyWidth       = $( 'body' ).width();
422
423					if( $link.closest( '.fl-menu-submenu-right' ).length !== 0) {
424
425						$link.addClass( 'fl-menu-submenu-right' );
426
427					} else if( $( 'body' ).hasClass( 'rtl' ) ) {
428
429						subMenuPos = $parent.is( '.sub-menu' ) ?
430									 $parent.offset().left - subMenuWidth:
431									 $link.offset().left - $link.width() - subMenuWidth;
432
433						if( subMenuPos <= 0 ) {
434							$link.addClass( 'fl-menu-submenu-right' );
435						}
436
437					} else {
438
439						subMenuPos = $parent.is( '.sub-menu' ) ?
440									 $parent.offset().left + $parent.width() + subMenuWidth :
441									 $link.offset().left + $link.width() + subMenuWidth;
442
443						if( subMenuPos > bodyWidth ) {
444							$link.addClass('fl-menu-submenu-right');
445						}
446					}
447				}, this ) )
448				.on( 'mouseleave', '.fl-has-submenu', $.proxy( function( e ){
449					$( e.currentTarget ).removeClass( 'fl-menu-submenu-right' );
450				}, this ) );
451
452		},
453
454		/**
455		 * Logic to prevent submenus to go behind the next overlay row.
456		 *
457		 * @since  1.10.9
458		 * @return void
459		 */
460		_submenuRowZindexFix: function(){
461
462			$( this.wrapperClass )
463				.on( 'mouseenter', 'ul.menu > .fl-has-submenu', $.proxy( function( e ){
464
465					if( $ ( e.currentTarget ).find('.sub-menu').length === 0 ) {
466						return;
467					}
468
469					$( this.nodeClass )
470						.closest( '.fl-row' )
471						.find( '.fl-row-content' )
472						.css( 'z-index', '10' );
473
474				}, this ) )
475				.on( 'mouseleave', 'ul.menu > .fl-has-submenu', $.proxy( function(){
476
477					$( this.nodeClass )
478						.closest( '.fl-row' )
479						.find( '.fl-row-content' )
480						.css( 'z-index', '' );
481
482				}, this ) );
483		},
484
485		/**
486		 * Logic for the mobile menu button.
487		 *
488		 * @since  1.6.1
489		 * @return void
490		 */
491		_toggleForMobile: function(){
492
493			var $wrapper = null,
494				$menu    = null,
495				self     = this;
496
497			$( this.wrapperClass ).find( '.fl-menu-mobile-toggle' ).attr('aria-controls', $( this.wrapperClass ).find( 'ul.menu' ).attr('id'));
498
499			if( this._isMenuToggle() ){
500
501				if ( this._isMobileBelowRowEnabled() ) {
502					this._placeMobileMenuBelowRow();
503					$wrapper = $( this.wrapperClass );
504					$menu    = $( this.nodeClass + '-clone' );
505					$menu.find( 'ul.menu' ).show();
506				}
507				else {
508					$wrapper = $( this.wrapperClass );
509					$menu    = $wrapper.find( '.menu' );
510				}
511
512				if( !$wrapper.find( '.fl-menu-mobile-toggle' ).hasClass( 'fl-active' ) && ! self.mobileFlyout ){
513					$menu.css({ display: 'none' });
514				}
515
516				// Flayout Menu
517				if ( self.mobileFlyout ) {
518					this._initFlyoutMenu();
519				}
520
521				$wrapper.on( 'click', '.fl-menu-mobile-toggle', function( e ){
522					e.stopImmediatePropagation();
523
524					$( this ).toggleClass( 'fl-active' );
525
526					if ( self.mobileFlyout ) {
527						self._toggleFlyoutMenu();
528						const flyoutWrapper = $( '.fl-menu-mobile-flyout' );
529						if ( $( this ).hasClass( 'fl-active' ) ) {
530							flyoutWrapper.attr( 'aria-hidden', false );
531							flyoutWrapper.find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex="-1"]' ).attr( 'tabindex', 0 );
532						}
533						else {
534							flyoutWrapper.attr( 'aria-hidden', true );
535							flyoutWrapper.find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex]:not
535([tabindex="-1"])' ).attr( 'tabindex', -1 );
536						}
537					}
538					else {
539						var targetMenu = null;
540
541						if ( self.mobileBelowRow ) {
542							var $closestCol = $( this ).parents( '.fl-col, .fl-module-box' ),
543								$closestColGroup = $closestCol.length ? $closestCol.parent( '.fl-col-group' ) : null;
544								targetMenu  = $closestCol.length ? $closestCol.last().next( '.fl-menu-mobile-clone' ) : null;
545
546							if ( $closestColGroup.length ) {
547								if ( $closestColGroup.hasClass( 'fl-col-group-responsive-reversed' ) ) {
548									$closestColGroup.find( '.fl-menu-mobile-clone' ).css( 'order', -1 );
549								} else if ( $closestColGroup ) {
550									$closestColGroup.find( '.fl-menu-mobile-clone' ).css( 'order', 2 );
551								}
552							}
553						} else {
554							targetMenu = $( this ).closest( '.fl-menu' ).find( 'ul.menu' );
555						}
556						
557						if ( targetMenu.length ) {
558							$menu = $( targetMenu );
559						}
560
561						$menu.slideToggle();
562					}
563
564					e.stopPropagation();
565				} );
566
567				// Hide active menu when click on anchor link ID that exists on a page
568				$menu.off().on( 'click', '.menu-item > a[href*="#"]:not([href="#"])', function(){
569					var $href = $(this).attr('href'),
570						$targetID = $href.split('#')[1],
571						element = $('#' + $targetID);
572					if ( $('body').find(element).length > 0 ) {
573						$( this ).toggleClass( 'fl-active' );
574						FLBuilderLayout._scrollToElement( element );
575						if ( ! self._isMenuToggle() ) {
576							$menu.slideToggle();
577						}
578					}
579				});
580			}
581			else {
582
583				if ( this._isMobileBelowRowEnabled() ) {
584					this._removeMenuFromBelowRow();
585				}
586
587				$wrapper = $( this.wrapperClass ),
588				$menu    = $wrapper.find( 'ul.menu' );
589				$wrapper.find( '.fl-menu-mobile-toggle' ).removeClass( 'fl-active' );
590				$menu.css({ display: '' });
591
592				if ( ! this._isMobileBelowRowEnabled() ) {
593					$menu.off( 'click', '.menu-item > a[href*="#"]:not([href="#"])' );
594				}
595
596				if ( this.mobileFlyout && $wrapper.find( '.fl-menu-mobile-flyout' ).length > 0 ) {
597					$( 'body' ).css( 'margin', '' );
598					$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', '' );
599					$menu.unwrap();
600					$wrapper.find( '.fl-menu-mobile-close' ).remove();
601					$wrapper.find( '.fl-menu-mobile-opacity' ).remove();
602				}
603			}
604		},
605
606		/**
607		 * Init any mega menus that exist.
608		 *
609		 * @see 	 this._isMenuToggle()
610		 * @since  1.10.4
611		 * @return void
612		 */
613		_initMegaMenus: function(){
614
615			var module     = $( this.nodeClass ),
616				rowContent = module.closest( '.fl-row-content' ),
617				rowWidth   = rowContent.width(),
618				megas      = module.find( '.mega-menu' ),
619				disabled   = module.find( '.mega-menu-disabled' ),
620				isToggle   = this._isMenuToggle();
621
622			if ( isToggle ) {
623				megas.removeClass( 'mega-menu' ).addClass( 'mega-menu-disabled' );
624				module.find( 'li.mega-menu-disabled > ul.sub-menu' ).css( 'width', '' );
625				rowContent.css( 'position', '' );
626			} else {
627				disabled.removeClass( 'mega-menu-disabled' ).addClass( 'mega-menu' );
628				module.find( 'li.mega-menu > ul.sub-menu' ).css( 'width', rowWidth + 'px' );
629				rowContent.css( 'position', 'relative' );
630			}
631		},
632
633		/**
634		 * Check to see if Below Row should be enabled.
635		 *
636		 * @since  1.11
637		 * @return boolean
638		 */
639		_isMobileBelowRowEnabled: function() {
640			return this.mobileBelowRow && ( $( this.nodeClass ).parents( '.fl-col, .fl-module-box' ).length );
641		},
642
643		/**
644		 * Logic for putting the mobile menu below the menu's
645		 * column so it spans the full width of the page.
646		 *
647		 * @since  1.10
648		 * @return void
649		 */
650		_placeMobileMenuBelowRow: function(){
651
652			if ( $( this.nodeClass + '-clone' ).length ) {
653				return;
654			}
655
656			var module = $( this.nodeClass ),
657				clone  = null,
658				col    = module.parents( '.fl-col, .fl-module-box' ).last();
659
660			if ( module.length < 1 ) {
661				return;
662			}
663
664			clone = ( module.length > 1 ) ? $( module[0] ).clone() : module.clone();
665			module.find( 'ul.menu' ).remove();
666			clone.addClass( ( this.nodeClass + '-clone' ).replace( '.', '' ) );
667			clone.addClass( 'fl-menu-mobile-clone' );
668			clone.find( '.fl-menu-mobile-toggle' ).remove();
669			col.after( clone );
670
671			// Removes animation when enabled
672			if ( module.hasClass( 'fl-animation' ) ) {
673				clone.removeClass( 'fl-animation' );
674			}
675
676			this._menuOnFocus();
677			this._menuOnClick();
678			this._menuOnEscape();
679		},
680
681		/**
682		 * Logic for removing the mobile menu from below the menu's
683		 * column and putting it back in the main wrapper.
684		 *
685		 * @since  1.10
686		 * @return void
687		 */
688		_removeMenuFromBelowRow: function(){
689
690			if ( ! $( this.nodeClass + '-clone' ).length ) {
691				return;
692			}
693
694			var module = $( this.nodeClass ),
695				clone  = $( this.nodeClass + '-clone' ),
696				menu   = clone.find( 'ul.menu' ),
697				nav    = module.find( 'nav' );
698
699			if ( nav.length ) {
700				nav.append( menu );
701			} else {
702				module.find( '.fl-menu-mobile-toggle' ).after( menu );
703			}
704			clone.remove();
705			menu.find( 'a' ).each( FLBuilderLayout._initAnchorLink );
706		},
707
708		/**
709		 * Logic for Flyout responsive menu.
710		 *
711		 * @since  2.2
712		 * @return void
713		 */
714		_initFlyoutMenu: function(){
715			var wrapper = $( this.wrapperClass ),
716				menu  	= wrapper.find( 'ul.menu' ),
717				button	= wrapper.find( '.fl-menu-mobile-toggle' );
718
719			if ( 0 === wrapper.find( '.fl-menu-mobile-flyout' ).length ) {
720				menu.wrap( '<div class="fl-menu-mobile-flyout" aria-hidden="true"></div>' );
721			}
722
723			if ( 0 === wrapper.find( '.fl-menu-mobile-close' ).length ) {
724				var close = window.fl_responsive_close || 'Close'
725				wrapper.find( '.fl-menu-mobile-flyout' ).prepend( '<button class="fl-menu-mobile-close fl-content-ui-button" aria-label="' + close + '"><i class="fas fa-times"></i></button>' );
726			}
727
728			// Push with opacity
729			if ( wrapper.hasClass( 'fl-menu-responsive-flyout-push-opacity' ) && 0 === wrapper.find( '.fl-menu-mobile-opacity' ).length ) {
730				wrapper.append( '<div class="fl-menu-mobile-opacity"></div>' );
731			}
732
733			wrapper.off( 'click', '.fl-menu-mobile-opacity, .fl-menu-mobile-close' ).on( 'click', '.fl-menu-mobile-opacity, .fl-menu-mobile-close', function(e){
734				button.trigger('focus').trigger( 'click' );
735				e.stopPropagation();
736			});
737
738			if ( 'undefined' !== typeof FLBuilder ) {
739				FLBuilder.addHook('restartEditingSession', function(){
740					$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', '' );
741
742					// Toggle active menu
743					if ( button.hasClass( 'fl-active' ) ) {
744						button.trigger( 'click' );
745					}
746				});
747			}
748			$( '.fl-menu-mobile-flyout' ).find( 'a[href], button, input, select, textarea, span.fl-menu-toggle, [tabindex]:not([tabindex="-1"])' ).attr( 'tabindex', -1 );
749		},
750
751		/**
752		 * Logic to enable/disable the Flyout menu on button click.
753		 *
754		 * @since  2.2
755		 * @return void
756		 */
757		_toggleFlyoutMenu: function(){
758			var wrapper		= $( this.wrapperClass ),
759				button		= wrapper.find( '.fl-menu-mobile-toggle' ),
760				position 	= wrapper.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
761				pushMenu 	= wrapper.hasClass( 'fl-menu-responsive-flyout-push' ) || wrapper.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
762				opacity		= wrapper.find( '.fl-menu-mobile-opacity' ),
763				marginPos	= {},
764				fixedPos 	= {},
765				fixedHeader	= $('header, header > div');
766
767			this._resizeFlyoutMenuPanel();
768
769			// Fix the push menu when builder ui panel is pinned
770			if ( $( '.fl-builder-ui-pinned-content-transform' ).length > 0 && ! $( 'body' ).hasClass( 'fl-builder-edit' ) ) {
771				$( '.fl-builder-ui-pinned-content-transform' ).css( 'transform', 'none' );
772			}
773
774			if ( pushMenu ) {
775				marginPos[ 'margin-' + position ] = button.hasClass( 'fl-active' ) ? this.flyoutWidth + 'px' : '0px';
776				$( 'body' ).animate( marginPos, 200);
777
778				// Fixed header
779				if ( fixedHeader.length > 0 ) {
780					fixedPos[ position] = button.hasClass( 'fl-active' ) ? this.flyoutWidth + 'px' : '0px';
781					fixedHeader.each(function(){
782						if ( 'fixed' == $( this ).css( 'position' ) ) {
783							$( this ).css({ 'transition' : 'none' });
784							$( this ).animate( fixedPos, 200 );
785						}
786					});
787				}
788			}
789
790			if ( opacity.length > 0 && button.hasClass( 'fl-active' ) ) {
791				opacity.show();
792			}
793			else {
794				opacity.hide();
795			}
796		},
797
798		/**
799		 * Resize or reposition the Flyout Menu Panel.
800		 * 
801		 * @since  2.8.1
802		 * @return void
803		 */
804		_resizeFlyoutMenuPanel: function(){
805			const wrapper    = $( this.wrapperClass );
806			const wrapFlyout = wrapper.find( '.fl-menu-mobile-flyout' );
807				
808			if ( wrapFlyout.length > 0 ) {
809				wrapFlyout.css( this._getFlyoutMenuPanelPosition() );
810			}
811		},
812
813		/**
814		 * Compute the Flyout Menu Panel's position on the screen.
815		 * 
816		 * @since  2.8.1
817		 * @return object
818		 */
819		_getFlyoutMenuPanelPosition: function() {
820			var wrapper        = $( this.wrapperClass ),
821				button         = wrapper.find( '.fl-menu-mobile-toggle' ),
822				side           = wrapper.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
823				winHeight      = $(window).outerHeight(),
824				winTop         = $(window).scrollTop(),
825				adminBarHeight = $( '#wpadminbar' ).length ? $( '#wpadminbar' ).height() : 0,
826				flyoutPosition = {};
827
828			flyoutPosition[ side ]  = '-' + ( parseInt( this.flyoutWidth ) + 15 ) + 'px';
829			if ( ! button.hasClass( 'fl-active' ) ) {
830				return flyoutPosition;
831			}
832
833			flyoutPosition[ side ]  = '0px';
834			flyoutPosition[ 'height' ]  = winHeight + 'px';
835			flyoutPosition[ 'top' ] = '0px';
836			
837			if ( adminBarHeight > 0 ) {
838				const diff = adminBarHeight - winTop;
839				flyoutPosition[ 'top' ] = diff <= 0 ? '0px' : (diff) + 'px';
840			}
841
842			return flyoutPosition;
843		},
844
845		/**
846		 * Shows or hides the nav search form.
847		 *
848		 * @since  2.5
849		 * @method _toggleMenuSearch
850		 */
851		_toggleMenuSearch: function(){
852			const form   = $( this.wrapperClass ).find('.fl-menu-search-item .fl-search-form-input-wrap'); 
853			const button = $( this.wrapperClass ).find('.fl-menu-search-item .fl-button:is(a, button:not([type="submit"]))');
854			form.on('submit', () => form.stop().fadeToggle('fast'));
855			// Close the search form when focus is lost
856			form.on('focusout', (event) => {
857				if (form.is(':visible') && form.has($(event.relatedTarget)).length === 0) {
858					button.trigger('click');
859				}
860			});
861			button.attr('aria-expanded', false);
862			// Close other open submenus when focusing on the search button
863			button.on('focus', (event) => {
864				const parentMenus = $(event.relatedTarget).parents('.menu-item.fl-has-submenu');
865				if (event.relatedTarget && parentMenus.length) {
866					this._toggleSubmenu(parentMenus, false);
867				}
868			});
869			button.on('click', (event) => {
870				// Prevent toggling when clicking with mouse while the form is already open
871				if (event.detail && event.type === 'click' && form.is(':visible')) return;
872				form.stop().fadeToggle('fast', () => {
873					button.attr('aria-expanded', form.is(':visible'));
874					if(form.is(':visible')) {
875						form.find('.fl-search-text').focus();
876					}
877				});
878			});
879		},
880
881		/**
882		 * Adds menu node and post ID to WooCommerce ajax URL requests.
883		 *
884		 * @since  2.5
885		 * @return void
886		 */
887		_wooUpdateParams: function() {
888			if ( 'undefined' !== typeof wc_cart_fragments_params ) {
889				wc_cart_fragments_params.wc_ajax_url += '&fl-menu-node='+ this.nodeId +'&post-id='+ this.postId;
890			}
891			if ( 'undefined' !== typeof wc_add_to_cart_params ) {
892				wc_add_to_cart_params.wc_ajax_url += '&fl-menu-node='+ this.nodeId +'&post-id='+ this.postId;
893			}
894		},
895	};
896
897})(jQuery);
898
899(function($) {
900
901	$(function() {
902
903		new FLBuilderMenu({
904			id: '5b4e4504e6e84',
905			type: 'horizontal',
906			mobile: 'expanded',
907			mobileBelowRow: false,
908			mobileFlyout: false,
909			breakPoints: {
910				large: 1200,
911				medium: 992,
912				small: 768			},
913			mobileBreakpoint: 'mobile',
914			postId : '793',
915			mobileStacked: true,
916			submenuIcon: 'none',
917			flyoutWidth: '250',
918		});
919
920	});
921
922})(jQuery);
923
924/* Start Layout Custom JS */
925
926/* End Layout Custom JS */
927
928
929jQuery(function($) {
930	
931		$(function() {
932		$( '.fl-node-5da892bbc0b4e .fl-photo-img' )
933			.on( 'mouseenter', function( e ) {
934				$( this ).data( 'title', $( this ).attr( 'title' ) ).removeAttr( 'title' );
935			} )
936			.on( 'mouseleave', function( e ){
937				$( this ).attr( 'title', $( this ).data( 'title' ) ).data( 'title', null );
938			} );
939	});
940		window._fl_string_to_slug_regex = 'a-zA-Z0-9';
941});
942
943(function($) {
944
945	$(function() {
946
947		new FLBuilderMenu({
948			id: '5da892bbc0b4a',
949			type: 'horizontal',
950			mobile: 'hamburger',
951			mobileBelowRow: true,
952			mobileFlyout: false,
953			breakPoints: {
954				large: 1200,
955				medium: 992,
956				small: 768			},
957			mobileBreakpoint: 'medium-mobile',
958			postId : '15756',
959			mobileStacked: true,
960			submenuIcon: 'none',
961			flyoutWidth: '250',
962		});
963
964	});
965
966})(jQuery);
967
968/* Start Layout Custom JS */
969
970/* End Layout Custom JS */
971
972(function($){
973
974	/**
975	 * Helper class for header layout logic.
976	 *
977	 * @since 1.0
978	 * @class FLThemeBuilderHeaderLayout
979	 */
980	FLThemeBuilderHeaderLayout = {
981
982		/**
983		 * A reference to the window object for this page.
984		 *
985		 * @since 1.0
986		 * @property {Object} win
987		 */
988		win : null,
989
990		/**
991		 * A reference to the body object for this page.
992		 *
993		 * @since 1.0
994		 * @property {Object} body
995		 */
996		body : null,
997
998		/**
999		 * A reference to the header object for this page.
1000		 *
1001		 * @since 1.0
1002		 * @property {Object} header
1003		 */
1004		header : null,
1005
1006		/**
1007		 * Whether this header overlays the content or not.
1008		 *
1009		 * @since 1.0
1010		 * @property {Boolean} overlay
1011		 */
1012		overlay : false,
1013
1014		/**
1015		 * Whether the page has the WP admin bar or not.
1016		 *
1017		 * @since 1.0
1018		 * @property {Boolean} hasAdminBar
1019		 */
1020		hasAdminBar : false,
1021
1022		/**
1023		 * Breakpoint for when the sticky header should apply.
1024		 *
1025		 * @since 1.4
1026		 * @property {String} stickyOn
1027		 */
1028		stickyOn: '',
1029
1030		/**
1031		 * A reference of the sticky and shrink header breakpoint.
1032		 *
1033		 * @since 1.2.5
1034		 * @property {Number} breakpointWidth
1035		 */
1036		breakpointWidth: 0,
1037
1038		/**
1039		 * Initializes header layout logic.
1040		 *
1041		 * @since 1.0
1042		 * @method init
1043		 */
1044		init: function()
1045		{
1046			var editing          = $( 'html.fl-builder-edit' ).length,
1047				header           = $( '.fl-builder-content[data-type=header]' ),
1048				menuModule       = header.find( '.fl-module-menu' ),
1049				breakpoint       = null;
1050
1051			if ( ! editing && header.length ) {
1052
1053				header.imagesLoaded( $.proxy( function() {
1054
1055					this.win         = $( window );
1056					this.body        = $( 'body' );
1057					this.header      = header.eq( 0 );
1058					this.overlay     = !! Number( header.attr( 'data-overlay' ) );
1059					this.hasAdminBar = !! $( 'body.admin-bar' ).length;
1060					this.stickyOn    = this.header.data( 'sticky-on' );
1061					breakpoint       = this.header.data( 'sticky-breakpoint' );
1062
1063					if ( '' == this.stickyOn ) {
1064						if ( typeof FLBuilderLayoutConfig.breakpoints[ breakpoint ] !== undefined ) {
1065							this.breakpointWidth = FLBuilderLayoutConfig.breakpoints[ breakpoint ];
1066						}
1067						else {
1068							this.breakpointWidth = FLBuilderLayoutConfig.breakpoints.medium;
1069						}
1070					}
1071
1072					if ( Number( header.attr( 'data-sticky' ) ) ) {
1073
1074						this.header.data( 'original-top', this.header.offset().top );
1075						this.win.on( 'resize', $.throttle( 500, $.proxy( this._initSticky, this ) ) );
1076						this._initSticky();
1077
1078					}
1079
1080				}, this ) );
1081			}
1082		},
1083
1084		/**
1085		 * Initializes sticky logic for a header.
1086		 *
1087		 * @since 1.0
1088		 * @access private
1089		 * @method _initSticky
1090		 */
1091		_initSticky: function( e )
1092		{
1093			var header     = $('.fl-builder-content[data-type=header]'),
1094				windowSize = this.win.width(),
1095				makeSticky = false;
1096
1097			makeSticky = this._makeWindowSticky( windowSize );
1098			if ( makeSticky || ( this.breakpointWidth > 0 && windowSize >= this.breakpointWidth ) ) {
1099				this.win.on( 'scroll.fl-theme-builder-header-sticky', $.proxy( this._doSticky, this ) );
1100				//
1101				// Check if Event Type is 'resize' then invoke this._doSticky()
1102				// only if the 'fl-theme-builder-header-sticky' class is already present.
1103				//
1104				if ( e && 'resize' === e.type ) {
1105					if ( this.header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1106						this._doSticky( e );
1107					}
1108					this._adjustStickyHeaderWidth();
1109				}
1110
1111				if ( Number( header.attr( 'data-shrink' ) ) ) {
1112					this.header.data( 'original-height', this.header.outerHeight() );
1113					this.win.on( 'resize', $.throttle( 500, $.proxy( this._initShrink, this ) ) );
1114					this._initShrink();
1115				}
1116
1117				this._initFlyoutMenuFix( e );
1118			} else {
1119				this.win.off( 'scroll.fl-theme-builder-header-sticky' );
1120				this.win.off( 'resize.fl-theme-builder-header-sticky' );
1121
1122				this.header.removeClass( 'fl-theme-builder-header-sticky' );
1123				this.header.removeAttr( 'style' );
1124				this.header.parent().css( 'padding-top', '0' );
1125			}
1126		},
1127
1128		/**
1129		 * Check if Header should be sticky at a particular Window size.
1130		 *
1131		 * @since 1.4
1132		 * @access private
1133		 * @param  widowSize
1134		 * @method _makeWindowSticky
1135		 */
1136		_makeWindowSticky: function ( windowSize )
1137		{
1138			var makeSticky = false;
1139
1140			switch (this.stickyOn) {
1141				case 'xl':
1142					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['large'];
1143					break;
1144				case '': // Default
1145				case 'desktop':
1146					makeSticky = windowSize >= FLBuilderLayoutConfig.breakpoints['medium'];
1147					break;
1148				case 'desktop-medium':
1149					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['small'];
1150					break;
1151				case 'large':
1152					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['medium'] && windowSize <= FLBuilderLayoutConfig.breakpoints['large'];
1153					break;
1154				case 'large-medium':
1155					makeSticky = windowSize > FLBuilderLayoutConfig.breakpoints['small'] && windowSize <= FLBuilderLayoutConfig.breakpoints['large'];
1156					break;
1157				case 'medium':
1158					makeSticky = ( windowSize <= FLBuilderLayoutConfig.breakpoints['medium'] && windowSize > FLBuilderLayoutConfig.breakpoints['small'] );
1159					break;
1160				case 'medium-mobile':
1161					makeSticky = (windowSize <= FLBuilderLayoutConfig.breakpoints['medium']);
1162					break;
1163				case 'mobile':
1164					makeSticky = (windowSize <= FLBuilderLayoutConfig.breakpoints['small']);
1165					break;
1166				case 'all':
1167					makeSticky = true;
1168					break;
1169			}
1170
1171			return makeSticky;
1172		},
1173
1174		/**
1175		 * Sticks the header when the page is scrolled.
1176		 *
1177		 * @since 1.0
1178		 * @access private
1179		 * @method _doSticky
1180		 */
1181		_doSticky: function( e )
1182		{
1183			var winTop    		  = Math.floor( this.win.scrollTop() ),
1184				headerTop 		  = Math.floor( this.header.data( 'original-top' ) ),
1185				hasStickyClass    = this.header.hasClass( 'fl-theme-builder-header-sticky' ),
1186				hasScrolledClass  = this.header.hasClass( 'fl-theme-builder-header-scrolled' ),
1187				beforeHeader      = this.header.prevAll( '.fl-builder-content' ),
1188				bodyTopPadding    = parseInt( jQuery('body').css('padding-top') ),
1189				winBarHeight      = $('#wpadminbar').length ? $('#wpadminbar').outerHeight() : 0,
1190				headerHeight      = 0;
1191
1192			if ( isNaN( bodyTopPadding ) ) {
1193				bodyTopPadding = 0;
1194			}
1195
1196			if ( this.hasAdminBar && this.win.width() > 600 ) {
1197				winTop += Math.floor( winBarHeight );
1198			}
1199
1200			if ( winTop > headerTop ) {
1201				if ( ! hasStickyClass ) {
1202					if ( e && ( 'scroll' === e.type || 'smartscroll' === e.type ) ) {
1203					 	this.header.addClass( 'fl-theme-builder-header-sticky' );
1204						if ( this.overlay && beforeHeader.length ) {
1205							this.header.css( 'top', winBarHeight);
1206						}
1207					}
1208
1209					if ( ! this.overlay ) {
1210						this._adjustHeaderHeight();
1211					}
1212				}
1213			}
1214			else if ( hasStickyClass ) {
1215				this.header.removeClass( 'fl-theme-builder-header-sticky' );
1216				this.header.removeAttr( 'style' );
1217				this.header.parent().css( 'padding-top', '0' );
1218			}
1219
1220			this._adjustStickyHeaderWidth();
1221
1222			if ( winTop > headerTop ) {
1223				if ( ! hasScrolledClass ) {
1224					this.header.addClass( 'fl-theme-builder-header-scrolled' );
1225				}
1226			} else if ( hasScrolledClass ) {
1227				this.header.removeClass( 'fl-theme-builder-header-scrolled' );
1228			}
1229
1230			this._flyoutMenuFix( e );
1231		},
1232
1233		/**
1234		 * Initializes flyout menu fixes on sticky header.
1235		 *
1236		 * @since 1.4.1
1237		 * @method _initFlyoutMenuFix
1238		 */
1239		_initFlyoutMenuFix: function( e ) {
1240			var header       = this.header,
1241				menuModule   = header.closest( '.fl-menu' ),
1242				flyoutMenu   = menuModule.find( '.fl-menu-mobile-flyout' ),
1243				isPushMenu   = menuModule.hasClass( 'fl-menu-responsive-flyout-push' ) || menuModule.hasClass( 'fl-menu-responsive-flyout-push-opacity' ),
1244				isOverlay    = menuModule.hasClass( 'fl-menu-responsive-flyout-overlay' ),
1245				flyoutPos    = menuModule.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
1246				flyoutParent = header.parent().is( 'header' ) ? header.parent().parent() : header.parent();
1247				isFullWidth  = this.win.width() === header.width(),
1248				flyoutLayout = '',
1249				activePos    = 250,
1250				headerPos    = 0;
1251
1252			if ( ! flyoutMenu.length ) {
1253				return;
1254			}
1255
1256			if ( this.win.width() > header.parent().width() ) {
1257				headerPos = ( this.win.width() - header.width() ) / 2;
1258			}
1259
1260			if ( isOverlay ) {
1261				activePos = headerPos;
1262			}
1263			else if ( isPushMenu ) {
1264				activePos = activePos + headerPos;
1265			}
1266			flyoutMenu.data( 'activePos', activePos );
1267
1268			if ( isPushMenu ) {
1269				flyoutLayout = 'push-' + flyoutPos;
1270			}
1271			else if ( isOverlay ) {
1272				flyoutLayout = 'overlay-' + flyoutPos;
1273			}
1274
1275			if ( isPushMenu && ! $( 'html' ).hasClass( 'fl-theme-builder-has-flyout-menu' ) ) {
1276				$( 'html' ).addClass( 'fl-theme-builder-has-flyout-menu' );
1277			}
1278
1279			if ( ! flyoutParent.hasClass( 'fl-theme-builder-flyout-menu-' + flyoutLayout ) ) {
1280				flyoutParent.addClass( 'fl-theme-builder-flyout-menu-' + flyoutLayout );
1281			}
1282
1283			if ( ! header.hasClass( 'fl-theme-builder-flyout-menu-overlay' ) && isOverlay ) {
1284				header.addClass( 'fl-theme-builder-flyout-menu-overlay' );
1285			}
1286
1287			if ( ! header.hasClass( 'fl-theme-builder-header-full-width' ) && isFullWidth ) {
1288			   header.addClass( 'fl-theme-builder-header-full-width' );
1289		    }
1290			else if ( ! isFullWidth ) {
1291				header.removeClass( 'fl-theme-builder-header-full-width' );
1292			}
1293
1294			menuModule.on( 'click', '.fl-menu-mobile-toggle', $.proxy( function( event ){
1295				if ( menuModule.find( '.fl-menu-mobile-toggle.fl-active' ).length ) {
1296					$( 'html' ).addClass( 'fl-theme-builder-flyout-menu-active' );
1297					event.stopImmediatePropagation();
1298				}
1299				else {
1300					$( 'html' ).removeClass( 'fl-theme-builder-flyout-menu-active' );
1301				}
1302
1303				this._flyoutMenuFix( event );
1304			}, this ) );
1305		},
1306
1307		/**
1308		 * Fix flyout menu inside the sticky header.
1309		 *
1310		 * @since 1.4.1
1311		 * @method _flyoutMenuFix
1312		 */
1313		_flyoutMenuFix: function( e ){
1314			var header      = this.header,
1315			    menuModule  = $( e.target ).closest( '.fl-menu' ),
1316				flyoutMenu  = menuModule.find( '.fl-menu-mobile-flyout' ),
1317				flyoutPos   = menuModule.hasClass( 'fl-flyout-right' ) ? 'right' : 'left',
1318				menuOpacity = menuModule.find( '.fl-menu-mobile-opacity' ),
1319				isScroll    = 'undefined' !== typeof e && 'scroll' === e.handleObj.type,
1320				activePos   = 'undefined' !== typeof flyoutMenu.data( 'activePos' ) ? flyoutMenu.data( 'activePos' ) : 0,
1321				headerPos   = ( this.win.width() - header.width() ) / 2,
1322				inactivePos = headerPos > 0 ? activePos + 4 : 254;
1323
1324			if ( ! flyoutMenu.length ) {
1325				return;
1326			}
1327
1328			if ( this.overlay ) {
1329				return;
1330			}
1331
1332			if( $( '.fl-theme-builder-flyout-menu-active' ).length ) {
1333
1334				if ( isScroll && ! flyoutMenu.hasClass( 'fl-menu-disable-transition' ) ) {
1335					flyoutMenu.addClass( 'fl-menu-disable-transition' );
1336				}
1337
1338				if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1339					if ( ! isScroll ) {
1340						setTimeout( $.proxy( function(){
1341							flyoutMenu.css( flyoutPos, '-' + activePos + 'px' );
1342						}, this ), 1 );
1343					}
1344					else {
1345						flyoutMenu.css( flyoutPos, '-' + activePos + 'px' );
1346					}
1347				}
1348				else {
1349					flyoutMenu.css( flyoutPos, '0px' );
1350				}
1351			}
1352			else {
1353				if ( flyoutMenu.hasClass( 'fl-menu-disable-transition' ) ) {
1354					flyoutMenu.removeClass( 'fl-menu-disable-transition' );
1355				}
1356
1357				if ( header.hasClass( 'fl-theme-builder-flyout-menu-overlay' ) && headerPos > 0 && headerPos < 250 ) {
1358					if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1359						inactivePos = headerPos + 254;
1360					}
1361					else {
1362						inactivePos = 254;
1363					}
1364				}
1365
1366				if ( e && e.type === 'resize' ) {
1367					inactivePos = headerPos + 254;
1368				}
1369
1370				flyoutMenu.css( flyoutPos, '-' + inactivePos + 'px' );
1371			}
1372
1373			if ( e && menuModule.is('.fl-menu-responsive-flyout-overlay') && $.infinitescroll ) {
1374				e.stopImmediatePropagation();
1375			}
1376
1377			if( menuOpacity.length ) {
1378				if ( header.hasClass( 'fl-theme-builder-header-sticky' ) ) {
1379					if ( '0px' === menuOpacity.css( 'left' ) ) {
1380						menuOpacity.css( 'left', '-' + headerPos + 'px' );
1381					}
1382				}
1383				else {
1384					menuOpacity.css( 'left', '' );
1385				}
1386			}
1387		},
1388
1389		/**
1390		 * Adjust sticky header width if BB Theme Boxed Layout is used.
1391		 *
1392		 * @since 1.4
1393		 * @access private
1394		 * @method _adjustStickyHeaderWidth
1395		 */
1396		_adjustStickyHeaderWidth: function () {
1397			if ( $('body').hasClass( 'fl-fixed-width' ) ) {
1398				var parentWidth = this.header.parent().width();
1399
1400				// Better if this is set in the stylesheet file.
1401				if ( this.win.width() >= 992 ) {
1402					this.header.css({
1403						'margin': '0 auto',
1404						'max-width': parentWidth,
1405					});
1406				}
1407				else {
1408					this.header.css({
1409						'margin': '',
1410						'max-width': '',
1411					});
1412				}
1413			}
1414		},
1415
1416		/**
1417		 * Adjust Sticky Header Height
1418		 *
1419		 * @since 1.4
1420		 * @access private
1421		 * @method _adjustHeaderHeight
1422		 */
1423		_adjustHeaderHeight: function () {
1424			var beforeHeader = this.header.prevAll('.fl-builder-content'),
1425				beforeHeaderHeight = 0,
1426				beforeHeaderFix = 0,
1427				headerHeight = Math.floor( this.header.outerHeight() ),
1428				bodyTopPadding = parseInt( $( 'body' ).css( 'padding-top' ) ),
1429				wpAdminBarHeight = 0,
1430				totalHeaderHeight = 0;
1431
1432			if ( isNaN( bodyTopPadding ) ) {
1433				bodyTopPadding = 0;
1434			}
1435
1436			if ( beforeHeader.length ) {
1437				$.each( beforeHeader, function() {
1438					beforeHeaderHeight += Math.floor( $(this).outerHeight() );
1439				});
1440				// Subtract this value from the header parent's top padding.
1441				beforeHeaderFix = 2;
1442			}
1443
1444			if ( this.hasAdminBar && this.win.width() <= 600 ) {
1445				wpAdminBarHeight = Math.floor( $('#wpadminbar').outerHeight() );
1446			}
1447
1448			totalHeaderHeight = Math.floor( beforeHeaderHeight + headerHeight);
1449
1450			if ( headerHeight > 0 ) {
1451				var headerParent = this.header.parent(),
1452					headerParentTopPadding = 0;
1453
1454				// If the header's parent container is the BODY tag ignore its top padding.
1455				if ( $( headerParent ).is('body') ) {
1456					headerParentTopPadding = Math.floor( headerHeight - wpAdminBarHeight );
1457				} else {
1458					headerParentTopPadding = Math.floor( headerHeight - bodyTopPadding - wpAdminBarHeight );
1459				}
1460
1461				$( headerParent ).css( 'padding-top',  ( headerParentTopPadding - beforeHeaderFix ) + 'px' );
1462
1463				this.header.css({
1464					'-webkit-transform': 'translate(0px, -' + totalHeaderHeight + 'px)',
1465					'-ms-transform': 'translate(0px, -' + totalHeaderHeight + 'px)',
1466					'transform': 'translate(0px, -' + totalHeaderHeight + 'px)'
1467				});
1468
1469			}
1470
1471		},
1472
1473		/**
1474		 * Initializes shrink logic for a header.
1475		 *
1476		 * @since 1.0
1477		 * @access private
1478		 * @method _initShrink
1479		 */
1480		_initShrink: function( e )
1481		{
1482			if ( this.win.width() >= this.breakpointWidth ) {
1483				this.win.on( 'scroll.fl-theme-builder-header-shrink', $.proxy( this._doShrink, this ) );
1484				this._setImageMaxHeight();
1485
1486				if ( this.win.scrollTop() > 0 ){
1487					this._doShrink();
1488				}
1489
1490			} else {
1491				this.header.parent().css( 'padding-top', '0' );
1492				this.win.off( 'scroll.fl-theme-builder-header-shrink' );
1493				this._removeShrink();
1494				this._removeImageMaxHeight();
1495			}
1496		},
1497
1498		/**
1499		 * Shrinks the header when the page is scrolled.
1500		 *
1501		 * @since 1.0
1502		 * @access private
1503		 * @method _doShrink
1504		 */
1505		_doShrink: function( e )
1506		{
1507			var winTop 			  = this.win.scrollTop(),
1508				headerTop 		  = this.header.data('original-top'),
1509				headerHeight 	  = this.header.data('original-height'),
1510				shrinkImageHeight = this.header.data('shrink-image-height'),
1511				windowSize   	  = this.win.width(),
1512				makeSticky   	  = this._makeWindowSticky( windowSize ),
1513				hasClass     	  = this.header.hasClass( 'fl-theme-builder-header-shrink' );
1514
1515
1516			if ( this.hasAdminBar ) {
1517				winTop += 32;
1518			}
1519
1520			if ( makeSticky && ( winTop > headerTop + headerHeight ) ) {
1521				if ( ! hasClass ) {
1522
1523					this.header.addClass( 'fl-theme-builder-header-shrink' );
1524
1525					// Shrink images but don't include lightbox and menu images.
1526					this.header.find('img').each( function( i ) {
1527						var image           = $( this ),
1528							maxMegaMenu     = image.closest( '.max-mega-menu' ).length,
1529							imageInLightbox = image.closest( '.fl-button-lightbox-content' ).length,
1530							imageInNavMenu  = image.closest( 'li.menu-item' ).length;
1531
1532						if ( ! ( imageInLightbox || imageInNavMenu || maxMegaMenu ) ) {
1533							image.css( 'max-height', shrinkImageHeight );
1534						}
1535
1536					});
1537
1538					this.header.find( '.fl-row-content-wrap' ).each( function() {
1539
1540						var row = $( this );
1541
1542						if ( parseInt( row.css( 'padding-bottom' ) ) > 5 ) {
1543							row.addClass( 'fl-theme-builder-header-shrink-row-bottom' );
1544						}
1545
1546						if ( parseInt( row.css( 'padding-top' ) ) > 5 ) {
1547							row.addClass( 'fl-theme-builder-header-shrink-row-top' );
1548						}
1549					} );
1550
1551					this.header.find( '.fl-module' ).each( function() {
1552
1553						var module = $( this ).find( '.fl-module-content' ).length ? $( this ).find( '.fl-module-content' ) : $( this );
1554
1555						if ( parseInt( module.css( 'margin-bottom' ) ) > 5 ) {
1556							module.addClass( 'fl-theme-builder-header-shrink-module-bottom' );
1557						}
1558
1559						if ( parseInt( module.css( 'margin-top' ) ) > 5 ) {
1560							module.addClass( 'fl-theme-builder-header-shrink-module-top' );
1561						}
1562					} );
1563				}
1564			} else if (hasClass) {
1565				this.header.find( 'img' ).css( 'max-height', '' );
1566				this._removeShrink();
1567			}
1568
1569			// Fixes Shrink header issue with BB Theme when window is scrolled then resized and back.
1570			if ( 'undefined' === typeof( e ) && $('body').hasClass( 'fl-fixed-width' ) ) {
1571				if ( ! this.overlay ) {
1572					this._adjustHeaderHeight();
1573				}
1574			}
1575
1576		},
1577
1578		/**
1579		 * Removes the header shrink effect.
1580		 *
1581		 * @since 1.0
1582		 * @access private
1583		 * @method _removeShrink
1584		 */
1585		_removeShrink: function()
1586		{
1587			var rows    = this.header.find( '.fl-row-content-wrap' ),
1588				modules = this.header.find('.fl-module, .fl-module-content');
1589
1590			rows.removeClass( 'fl-theme-builder-header-shrink-row-bottom' );
1591			rows.removeClass( 'fl-theme-builder-header-shrink-row-top' );
1592			modules.removeClass( 'fl-theme-builder-header-shrink-module-bottom' );
1593			modules.removeClass( 'fl-theme-builder-header-shrink-module-top' );
1594			this.header.removeClass( 'fl-theme-builder-header-shrink' );
1595		},
1596
1597		/**
1598		 * Adds max height to images in modules for smooth scrolling.
1599		 *
1600		 * @since 1.1.1
1601		 * @access private
1602		 * @method _setImageMaxHeight
1603		 */
1604		_setImageMaxHeight: function()
1605		{
1606			var head = $( 'head' ),
1607				stylesId = 'fl-header-styles-' + this.header.data( 'post-id' ),
1608				styles = '',
1609				images = this.header.find( '.fl-module img' );
1610
1611			if ( $( '#' + stylesId ).length ) {
1612				return;
1613			}
1614
1615			images.each( function( i ) {
1616				var image           = $( this ),
1617					height          = image.height(),
1618					node            = image.closest( '.fl-module' ).data( 'node' ),
1619					className       = 'fl-node-' + node + '-img-' + i,
1620					maxMegaMenu     = image.closest( '.max-mega-menu' ).length,
1621					imageInLightbox = image.closest( '.fl-button-lightbox-content' ).length,
1622					imageInNavMenu  = image.closest( 'li.menu-item' ).length;
1623
1624				if ( ! ( imageInLightbox || imageInNavMenu || maxMegaMenu  ) ) {
1625					image.addClass( className );
1626					styles += '.' + className + ' { max-height: ' + ( height ? height : image[0].height )  + 'px }';
1627				}
1628
1629			} );
1630
1631			if ( '' !== styles ) {
1632				head.append( '<style id="' + stylesId + '">' + styles + '</style>' );
1633			}
1634		},
1635
1636		/**
1637		 * Removes max height on images in modules for smooth scrolling.
1638		 *
1639		 * @since 1.1.1
1640		 * @access private
1641		 * @method _removeImageMaxHeight
1642		 */
1643		_removeImageMaxHeight: function()
1644		{
1645			$( '#fl-header-styles-' + this.header.data( 'post-id' ) ).remove();
1646		},
1647	};
1648
1649	$( function() { FLThemeBuilderHeaderLayout.init(); } );
1650
1651})(jQuery);
1652

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.