/**
 * Theme Name: errigal
 * Theme URI: https://projecterrigal.com/themes/errigal/
 * Author: Project errigal
 * Author URI: https://projecterrigal.com/
 * Version: 1.2.1
 */
( function() {
	'use strict';

	const ATTRIBUTE_ARIA_CONTROLS = 'aria-controls';
	const ATTRIBUTE_ID = 'id';
	const CLASS_SHARED_HIDDEN = 'hidden';
	const CLASS_SHARED_MENU_FLIP = 'menu-flip';
	const CLASS_SHARED_NO_SCROLL = 'no-scroll';
	const CLASS_SHARED_SHOW = 'show';
	const CSS_DISPLAY = 'display';
	const CSS_TRANSITION = 'transition';
	const CSS_VALUE_NONE = 'none';
	const DELAY_SHORT = 100;
	const DELAY_SHORTER = 50;
	const TOGGLE_ARIA_VISIBLE = false;
	const TOGGLE_CLOSE = false;
	const TOGGLE_OPEN = true;
	const NULL_ELEMENT = null;
	const TAG_A = 'a';
	const INDEX_FIRST = 0;
	const NULL_VALUE = null;

	function isObjectType( value, expectedType ) {
		return Object.prototype.toString.call( value ) ===
			`[object ${ expectedType }]`;
	}

	function isNumber( value ) {
		return (
			! isNaN( value ) &&
			isObjectType( value, 'Number' ) &&
			isFinite( value )
		);
	}

	function isPositiveNumber( value ) {
		return isNumber( value ) && value > 0;
	}

	function isIterable( items ) {
		return !! items && isPositiveNumber( items.length );
	}

	function getFirstItem( items ) {
		return isIterable( items )
			? items[ INDEX_FIRST ]
			: NULL_VALUE;
	}

	function isHTMLCollection( elements ) {
		return elements instanceof HTMLCollection;
	}

	function isFunction( value ) {
		return value instanceof Function;
	}

	function isTrue( value ) {
		return value === true;
	}

	function forEach( items, callback ) {
		if ( ! isIterable( items ) || ! isFunction( callback ) ) {
			return false;
		}

		if ( isHTMLCollection( items ) ) {
			items = Array.prototype.slice.call( items );
		}

		for ( let i = INDEX_FIRST; i < items.length; i++ ) {
			if ( isTrue( callback( items[ i ], i, items ) ) ) {
				return true;
			}
		}

		return false;
	}

	function hasClassList( element ) {
		return (
			!! element &&
			element.classList instanceof DOMTokenList &&
			isFunction( element.classList.contains )
		);
	}

	function isHTMLElement( element, ...classNames ) {
		if ( ! ( element instanceof HTMLElement ) ) {
			return false;
		}

		return (
			hasClassList( element ) &&
			! forEach(
				classNames,
				( className ) => ! element.classList.contains( className )
			)
		);
	}

	const EMPTY_STRING = '';

	function isString( value ) {
		return isObjectType( value, 'String' );
	}

	function isNonEmptyString( value ) {
		return (
			isString( value ) &&
			isFunction( value.trim ) &&
			value.trim() !== EMPTY_STRING
		);
	}

	function isDocument( element ) {
		return element instanceof Document;
	}

	function isisHTMLElementOrDocument( element ) {
		return isHTMLElement( element ) || isDocument( element );
	}

	function callElementMethod(
		methodName,
		nameOrSelectors,
		rootElement
	) {
		return (
			isNonEmptyString( methodName ) &&
			isNonEmptyString( nameOrSelectors ) &&
			isisHTMLElementOrDocument( rootElement ) &&
			isFunction( rootElement[ methodName ] )
		)
			? rootElement[ methodName ]( nameOrSelectors )
			: NULL_ELEMENT;
	}

	function getElementsByTagName(
		tagName,
		rootElement = document
	) {
		const ELEMENTS =
			callElementMethod(
				'getElementsByTagName',
				tagName,
				rootElement
			);

		return isHTMLCollection( ELEMENTS )
			? ELEMENTS
			: NULL_ELEMENT;
	}

	function getElementByTagName(
		tagName,
		rootElement = document
	) {
		return getFirstItem( getElementsByTagName( tagName, rootElement ) );
	}

	const CLASS_NAV_MENU_ITEM = 'menu-item';

	function isMenuItem( element ) {
		return isHTMLElement( element, CLASS_NAV_MENU_ITEM );
	}

	function getMenuItemLink( menuItem ) {
		return isMenuItem( menuItem )
			? getElementByTagName( TAG_A, menuItem )
			: NULL_ELEMENT;
	}

	function getParentElement( element ) {
		return isHTMLElement( element )
			? element.parentElement
			: NULL_ELEMENT;
	}

	const CLASS_NAV_MENU_ITEM_WITH_SUBMENU = 'menu-item-has-children';

	function isMenuItemWithSubmenu( element ) {
		return isHTMLElement( element, CLASS_NAV_MENU_ITEM_WITH_SUBMENU );
	}

	function isIe() {
		return !! window.MSInputMethodContext && !! document.documentMode;
	}

	function isLocationObject( obj ) {
		return (
			isIe() &&
			!! obj &&
			isString( obj.hash ) &&
			isFunction( obj.assign ) &&
			isFunction( obj.replace ) &&
			isFunction( obj.reload )
		);
	}

	function isLocation( element ) {
		return element instanceof Location || isLocationObject( element );
	}

	function removeTrailingSlash( url ) {
		return isNonEmptyString( url )
			? url.replace( /\/+$/, '' )
			: EMPTY_STRING;
	}

	function isEmptyHref( href ) {
		if ( ! isNonEmptyString( href ) || ! isLocation( window.location ) ) {
			return false;
		}

		const ORIGIN = window.location.origin;

		return (
			isNonEmptyString( ORIGIN ) &&
			removeTrailingSlash( href ) === removeTrailingSlash( ORIGIN )
		);
	}

	function hasHref( element ) {
		return (
			!! element &&
			isNonEmptyString( element.href ) &&
			! isEmptyHref( element.href )
		);
	}

	function toLowerCase( value ) {
		return isNonEmptyString( value ) && isFunction( value.toLowerCase )
			? value.toLowerCase()
			: EMPTY_STRING;
	}

	function areStringsEqualIgnoreCase( str1, str2 ) {
		return toLowerCase( str1 ) === toLowerCase( str2 );
	}

	function hasTagName( element ) {
		return !! element && isNonEmptyString( element.tagName );
	}

	function isElementOfType( element, tagName ) {
		return (
			hasTagName( element ) &&
			isNonEmptyString( tagName ) &&
			areStringsEqualIgnoreCase( element.tagName, tagName )
		);
	}

	function isHTMLElementOfType(
		tagName,
		element,
		...classNames
	) {
		return (
			isHTMLElement( element, ...classNames ) &&
			isElementOfType( element, tagName )
		);
	}

	function isAnchorElement( element, ...classNames ) {
		return isHTMLElementOfType( TAG_A, element, ...classNames );
	}

	const SELECTOR_NAV_MENU_ITEM_WITH_SUBMENU_LINK = `.${ CLASS_NAV_MENU_ITEM_WITH_SUBMENU } > ${ TAG_A }`;

	function matches( element, selectors ) {
		if ( ! isHTMLElement( element ) || ! isNonEmptyString( selectors ) ) {
			return false;
		}

		if ( isFunction( element.matches ) ) {
			return isTrue( element.matches( selectors ) );
		}

		if ( isFunction( element.msMatchesSelector ) ) {
			return isTrue( element.msMatchesSelector( selectors ) );
		}

		return false;
	}

	function isMenuItemWithSubmenuLink( element ) {
		return matches( element, SELECTOR_NAV_MENU_ITEM_WITH_SUBMENU_LINK );
	}

	function isAnchorElementWithoutHref( element ) {
		return isAnchorElement( element ) && ! hasHref( element );
	}

	function isMenuItemWithSubmenuLinkWithoutHref( element ) {
		return (
			isMenuItemWithSubmenuLink( element ) &&
			isAnchorElementWithoutHref( element )
		);
	}

	const CLASS_NAV_SUBMENU_TOGGLE = 'sub-menu-toggle';

	function isSubmenuToggle( element ) {
		return isHTMLElement( element, CLASS_NAV_SUBMENU_TOGGLE );
	}

	function isSubmenuOpenerElement( element ) {
		return (
			isSubmenuToggle( element ) ||
			isMenuItemWithSubmenuLinkWithoutHref( element )
		);
	}

	function getMenuItemWithSubmenu( submenuOpenerElement ) {
		if ( ! isSubmenuOpenerElement( submenuOpenerElement ) ) {
			return NULL_ELEMENT;
		}

		const MENU_ITEM_WITH_SUBMENU = getParentElement( submenuOpenerElement );

		return isMenuItemWithSubmenu( MENU_ITEM_WITH_SUBMENU )
			? MENU_ITEM_WITH_SUBMENU
			: NULL_ELEMENT;
	}

	const CLASS_NAV_SUBMENU = 'sub-menu';

	function getElementsByClassName(
		className,
		rootElement = document
	) {
		const ELEMENTS =
			callElementMethod(
				'getElementsByClassName',
				className,
				rootElement
			);

		return isHTMLCollection( ELEMENTS )
			? ELEMENTS
			: NULL_ELEMENT;
	}

	function getElementByClassName(
		className,
		rootElement = document
	) {
		return getFirstItem( getElementsByClassName( className, rootElement ) );
	}

	function getSubmenu( menuItemWithSubmenu ) {
		return isMenuItemWithSubmenu( menuItemWithSubmenu )
			? getElementByClassName( CLASS_NAV_SUBMENU, menuItemWithSubmenu )
			: NULL_ELEMENT;
	}

	function getFirstSubmenuItemLink( submenuOpenerElement ) {
		const SUBMENU = getSubmenu( getMenuItemWithSubmenu( submenuOpenerElement ) );

		return !! SUBMENU
			? getMenuItemLink( SUBMENU.firstElementChild )
			: NULL_ELEMENT;
	}

	const CLASS_NAV_MENU = 'menu';
	const CLASS_NAV_MENU_CONTAINER = 'menu-container';
	const SELECTOR_NAV_MOBILE_MENU_OPENED = `.${ CLASS_NAV_MENU_CONTAINER }.${ CLASS_SHARED_SHOW }`;
	const SELECTOR_NAV_LAST_TOP_LEVEL_MOBILE_MENU_ITEM_LINK = `${ SELECTOR_NAV_MOBILE_MENU_OPENED } .${ CLASS_NAV_MENU }:last-of-type > .${ CLASS_NAV_MENU_ITEM }:last-of-type > ${ TAG_A }`;

	function querySelector( selectors, rootElement = document ) {
		return callElementMethod( 'querySelector', selectors, rootElement );
	}

	function getLastTopLevelMobileMenuItemLink() {
		return querySelector( SELECTOR_NAV_LAST_TOP_LEVEL_MOBILE_MENU_ITEM_LINK );
	}

	const CLASS_NAV_MAIN_NAVIGATION = 'main-navigation';

	function getMainNavigation() {
		return getElementByClassName( CLASS_NAV_MAIN_NAVIGATION );
	}

	const SELECTOR_NAV_MENU = `.${ CLASS_NAV_MENU_CONTAINER } .${ CLASS_NAV_MENU }`;

	function getMenu() {
		return querySelector( SELECTOR_NAV_MENU );
	}

	function getMenuContainer() {
		return getElementByClassName( CLASS_NAV_MENU_CONTAINER );
	}

	const SELECTOR_NAV_MENU_ITEM_WITH_SUBMENU = `.${ CLASS_NAV_MAIN_NAVIGATION } .${ CLASS_NAV_MENU_ITEM_WITH_SUBMENU }`;

	function isNodeList( element ) {
		return element instanceof NodeList;
	}

	function querySelectorAll( selectors, rootElement = document ) {
		const ELEMENTS =
			callElementMethod(
				'querySelectorAll',
				selectors,
				rootElement
			);

		return isNodeList( ELEMENTS )
			? ELEMENTS
			: NULL_ELEMENT;
	}

	function getMenuItemsWithSubmenu() {
		return querySelectorAll( SELECTOR_NAV_MENU_ITEM_WITH_SUBMENU );
	}

	const CLASS_NAV_MOBILE_MENU_BACKGROUND = 'main-navigation-background';

	function getMobileMenuBackground() {
		return getElementByClassName( CLASS_NAV_MOBILE_MENU_BACKGROUND );
	}

	const CLASS_NAV_MOBILE_MENU_BUTTON = 'mobile-navigation__menu-button';

	function getMobileMenuButton() {
		return getElementByClassName( CLASS_NAV_MOBILE_MENU_BUTTON );
	}

	const CLASS_NAV_MOBILE_MENU_CLOSE_BUTTON = 'close-menu-button';

	function getMobileMenuCloseButton() {
		return getElementByClassName( CLASS_NAV_MOBILE_MENU_CLOSE_BUTTON );
	}

	function getNextElementSibling( element ) {
		return isHTMLElement( element )
			? element.nextElementSibling
			: NULL_ELEMENT;
	}

	const SELECTOR_NAV_MENU_ITEM_LINK = `.${ CLASS_NAV_MENU_ITEM } > ${ TAG_A }`;

	function isMenuItemLink( element ) {
		return matches( element, SELECTOR_NAV_MENU_ITEM_LINK );
	}

	function getNextMenuItemLink( menuItemLink ) {
		if ( ! isMenuItemLink( menuItemLink ) ) {
			return NULL_ELEMENT;
		}

		const MENU_ITEM = getParentElement( menuItemLink );

		return isMenuItem( MENU_ITEM )
			? getMenuItemLink( getNextElementSibling( MENU_ITEM ) )
			: NULL_ELEMENT;
	}

	const SELECTOR_NAV_OPENED_MENU_ITEM_ELEMENT = `.${ CLASS_SHARED_SHOW }`;
	const SELECTOR_NAV_MAIN_NAVIGATION_ELEMENT = `.${ CLASS_NAV_MAIN_NAVIGATION } *`;

	function isMainNavigationElement( element ) {
		return matches( element, SELECTOR_NAV_MAIN_NAVIGATION_ELEMENT );
	}

	function getOpenedMenuItemElements( element ) {
		return isMainNavigationElement( element )
			? querySelectorAll( SELECTOR_NAV_OPENED_MENU_ITEM_ELEMENT, element )
			: NULL_ELEMENT;
	}

	const ATTRIBUTE_HREF = 'href';
	const SELECTOR_NAV_DESKTOP_MENU_CONTAINER = `.${ CLASS_NAV_MENU_CONTAINER }:not(.${ CLASS_SHARED_SHOW })`;
	const SELECTOR_NAV_MENU_ITEM_OPENED = `.${ CLASS_NAV_MENU_ITEM }.${ CLASS_SHARED_SHOW }`;
	const SELECTOR_NAV_OPENED_TOP_LEVEL_DESKTOP_MENU_ITEM_LINK_WITH_HREF = `${ SELECTOR_NAV_DESKTOP_MENU_CONTAINER } .${ CLASS_NAV_MENU } > ${ SELECTOR_NAV_MENU_ITEM_OPENED } > ${ TAG_A }[${ ATTRIBUTE_HREF }]`;

	function getOpenedTopLevelDesktopMenuItemLinkWithHref() {
		return querySelector(
			SELECTOR_NAV_OPENED_TOP_LEVEL_DESKTOP_MENU_ITEM_LINK_WITH_HREF
		);
	}

	const SELECTOR_NAV_OPENED_TOP_LEVEL_DESKTOP_MENU_ITEM_SUBMENU_TOGGLE = `${ SELECTOR_NAV_DESKTOP_MENU_CONTAINER } .${ CLASS_NAV_MENU } > ${ SELECTOR_NAV_MENU_ITEM_OPENED } > .${ CLASS_NAV_SUBMENU_TOGGLE }`;

	function getOpenedTopLevelDesktopMenuItemSubmenuToggle() {
		return querySelector(
			SELECTOR_NAV_OPENED_TOP_LEVEL_DESKTOP_MENU_ITEM_SUBMENU_TOGGLE
		);
	}

	function getPreviousElementSibling( element ) {
		return isHTMLElement( element )
			? element.previousElementSibling
			: NULL_ELEMENT;
	}

	function getPreviousMenuItemLink( menuItemLink ) {
		if ( ! isMenuItemLink( menuItemLink ) ) {
			return NULL_ELEMENT;
		}

		const MENU_ITEM = getParentElement( menuItemLink );

		return isMenuItem( MENU_ITEM )
			? getMenuItemLink( getPreviousElementSibling( MENU_ITEM ) )
			: NULL_ELEMENT;
	}

	const CLASS_NAV_SITE_HEADER_MENU_BUTTON = 'site-header__menu-button';

	function getSiteHeaderMenuButton() {
		return getElementByClassName( CLASS_NAV_SITE_HEADER_MENU_BUTTON );
	}

	function getSubmenuToggle( menuItemWithSubmenu ) {
		return isMenuItemWithSubmenu( menuItemWithSubmenu )
			? getElementByClassName( CLASS_NAV_SUBMENU_TOGGLE, menuItemWithSubmenu )
			: NULL_ELEMENT;
	}

	const CLASS_NAV_SUBMENU_TOGGLE_TEXT_CLOSE = 'sub-menu-toggle-text-close';

	function getSubmenuToggleTextClose( submenuToggle ) {
		return isSubmenuToggle( submenuToggle )
			? getElementByClassName(
				CLASS_NAV_SUBMENU_TOGGLE_TEXT_CLOSE,
				submenuToggle
			)
			: NULL_ELEMENT;
	}

	const CLASS_NAV_SUBMENU_TOGGLE_TEXT_OPEN = 'sub-menu-toggle-text-open';

	function getSubmenuToggleTextOpen( submenuToggle ) {
		return isSubmenuToggle( submenuToggle )
			? getElementByClassName(
				CLASS_NAV_SUBMENU_TOGGLE_TEXT_OPEN,
				submenuToggle
			)
			: NULL_ELEMENT;
	}

	const CLASS_NAV_CLOSE_MENU_BUTTON_CONTAINER = 'close-menu-button__container';

	function isCloseMenuButtonContainer( element ) {
		return isHTMLElement( element, CLASS_NAV_CLOSE_MENU_BUTTON_CONTAINER );
	}

	const SELECTOR_NAV_CLOSED_SUBMENU_TOGGLE = `.${ CLASS_NAV_MENU_ITEM }:not(.${ CLASS_SHARED_SHOW }) > .${ CLASS_NAV_SUBMENU_TOGGLE }`;
	const CLASS_COMPONENT_GRID_ROW = 'row';
	const SELECTOR_NAV_LAST_TOP_LEVEL_MENU_ITEM = `.${ CLASS_NAV_MAIN_NAVIGATION } .${ CLASS_COMPONENT_GRID_ROW } > .${ CLASS_NAV_MENU }:last-child > .${ CLASS_NAV_MENU_ITEM }:last-child`;
	const SELECTOR_NAV_MENU_ITEM_WITHOUT_SUBMENU_LINK = `.${ CLASS_NAV_MENU_ITEM }:not(.${ CLASS_NAV_MENU_ITEM_WITH_SUBMENU }) > ${ TAG_A }`;

	function getGrandparentElement( element ) {
		return isHTMLElement( element ) && element.parentElement
			? element.parentElement.parentElement
			: NULL_ELEMENT;
	}

	function isLastTopLevelMenuItem( element ) {
		return matches( element, SELECTOR_NAV_LAST_TOP_LEVEL_MENU_ITEM );
	}

	function isLastMenuItem( element ) {
		return isMenuItem( element ) && ! getNextElementSibling( element );
	}

	function isMenuItemWithoutSubmenuLink( element ) {
		return matches( element, SELECTOR_NAV_MENU_ITEM_WITHOUT_SUBMENU_LINK );
	}

	function isClosedSubmenuToggle( element ) {
		return matches( element, SELECTOR_NAV_CLOSED_SUBMENU_TOGGLE );
	}

	function isEndOfMenu( element ) {
		if (
			! (
				isClosedSubmenuToggle( element ) ||
				isMenuItemWithoutSubmenuLink( element )
			)
		) {
			return false;
		}

		element = getParentElement( element );

		if ( ! isLastMenuItem( element ) ) {
			return false;
		}

		while ( isMenuItem( element ) ) {
			if ( ! isLastMenuItem( element ) ) {
				return false;
			}

			if ( isLastTopLevelMenuItem( element ) ) {
				return true;
			}

			element = getGrandparentElement( element );
		}

		return false;
	}

	function isMenu( element ) {
		return isHTMLElement( element, CLASS_NAV_MENU );
	}

	const CHARACTER_HASH = '#';

	function getLastItem( items ) {
		return isIterable( items )
			? items[ items.length - 1 ]
			: NULL_VALUE;
	}

	const EMPTY_ARRAY = [];

	function toChars( value ) {
		return isNonEmptyString( value )
			? value.split( '' )
			: EMPTY_ARRAY;
	}

	function hasEmptyAnchorLink( element ) {
		return (
			hasHref( element ) &&
			getLastItem( toChars( element.href ) ) === CHARACTER_HASH
		);
	}

	function isMenuItemLinkWithEmptyAnchorLink( element ) {
		return (
			matches( element, SELECTOR_NAV_MENU_ITEM_LINK ) &&
			hasEmptyAnchorLink( element )
		);
	}

	function isMobileMenuBackground( element ) {
		return isHTMLElement( element, CLASS_NAV_MOBILE_MENU_BACKGROUND );
	}

	function isMobileMenuButton( element ) {
		return isHTMLElement( element, CLASS_NAV_MOBILE_MENU_BUTTON );
	}

	function isMobileMenuCloseButton( element ) {
		return isHTMLElement( element, CLASS_NAV_MOBILE_MENU_CLOSE_BUTTON );
	}

	const SELECTOR_NAV_MOBILE_MENU_CONTAINER = `${ SELECTOR_NAV_MOBILE_MENU_OPENED }, ${ SELECTOR_NAV_MOBILE_MENU_OPENED } > .${ CLASS_COMPONENT_GRID_ROW }`;

	function isMobileMenuContainer( element ) {
		return matches( element, SELECTOR_NAV_MOBILE_MENU_CONTAINER );
	}

	const SELECTOR_NAV_MOBILE_MENU_ELEMENT = `${ SELECTOR_NAV_MOBILE_MENU_OPENED } *`;

	function isMobileMenuElement( element ) {
		return matches( element, SELECTOR_NAV_MOBILE_MENU_ELEMENT );
	}

	function isMobileMenuOpened() {
		return !! querySelector( SELECTOR_NAV_MOBILE_MENU_OPENED );
	}

	const SELECTOR_NAV_TOP_LEVEL_MENU_ITEM = `.${ CLASS_NAV_MENU } > .${ CLASS_NAV_MENU_ITEM }`;
	const SELECTOR_NAV_OPENED_SUBMENU_OF_TOP_LEVEL_DESKTOP_MENU_ITEM = `${ SELECTOR_NAV_DESKTOP_MENU_CONTAINER } ${ SELECTOR_NAV_TOP_LEVEL_MENU_ITEM } > .${ CLASS_NAV_SUBMENU }.${ CLASS_SHARED_SHOW }`;

	function isOpenedSubmenuOfTopLevelDesktopMenuItem( element ) {
		return matches(
			element,
			SELECTOR_NAV_OPENED_SUBMENU_OF_TOP_LEVEL_DESKTOP_MENU_ITEM
		);
	}

	const SELECTOR_NAV_PARENT_MENU_ITEM_OPENED = `${ SELECTOR_NAV_MENU_ITEM_OPENED } > *`;

	function isParentMenuItemOpened( element ) {
		return (
			isSubmenuOpenerElement( element ) &&
			matches( element, SELECTOR_NAV_PARENT_MENU_ITEM_OPENED )
		);
	}

	function isSiteHeaderMenuButton( element ) {
		return isHTMLElement( element, CLASS_NAV_SITE_HEADER_MENU_BUTTON );
	}

	function isSubmenu( element ) {
		return isHTMLElement( element, CLASS_NAV_SUBMENU );
	}

	const SELECTOR_NAV_SUBMENU_ITEM = `.${ CLASS_NAV_SUBMENU } > .${ CLASS_NAV_MENU_ITEM }`;
	const SELECTOR_NAV_SUBMENU_ITEM_LINK = `${ SELECTOR_NAV_SUBMENU_ITEM } > ${ TAG_A }`;

	function isSubmenuItemLink( element ) {
		return matches( element, SELECTOR_NAV_SUBMENU_ITEM_LINK );
	}

	function isSubmenuItemLinkLastItem( element ) {
		return isSubmenuItemLink( element ) && ! getNextMenuItemLink( element );
	}

	function isSubmenuItemLinkNotFirstItem( element ) {
		return isSubmenuItemLink( element ) && !! getPreviousMenuItemLink( element );
	}

	function isSubmenuItemLinkNotLastItem( element ) {
		return isSubmenuItemLink( element ) && !! getNextMenuItemLink( element );
	}

	const SELECTOR_NAV_SUBMENU_TOGGLE_OPENED = `${ SELECTOR_NAV_MENU_ITEM_OPENED } > .${ CLASS_NAV_SUBMENU_TOGGLE }`;

	function isSubmenuToggleOpened( element ) {
		return matches( element, SELECTOR_NAV_SUBMENU_TOGGLE_OPENED );
	}

	const SELECTOR_NAV_TOP_LEVEL_MENU_ITEM_LINK = `${ SELECTOR_NAV_TOP_LEVEL_MENU_ITEM } > ${ TAG_A }`;

	function isTopLevelMenuItemLink( element ) {
		return matches( element, SELECTOR_NAV_TOP_LEVEL_MENU_ITEM_LINK );
	}

	function isTopLevelMobileMenuItemLinkNotFirstItem( element ) {
		return (
			isMobileMenuElement( element ) &&
			isTopLevelMenuItemLink( element ) &&
			!! getPreviousMenuItemLink( element )
		);
	}

	function isTopLevelMobileMenuItemLinkNotLastItem( element ) {
		return (
			isMobileMenuElement( element ) &&
			isTopLevelMenuItemLink( element ) &&
			!! getNextMenuItemLink( element )
		);
	}

	function addClass( element, className ) {
		if (
			! isHTMLElement( element ) ||
			! hasClassList( element ) ||
			! isFunction( element.classList.add ) ||
			! isNonEmptyString( className )
		) {
			return;
		}

		element.classList.add( className );
	}

	function getAttribute( element, name ) {
		return isHTMLElement( element ) && isFunction( element.getAttribute )
			? element.getAttribute( name )
			: NULL_VALUE;
	}

	function isObject( value ) {
		return value instanceof Object;
	}

	function getObjectValue( obj, key ) {
		return isObject( obj ) && ( key in obj )
			? obj[ key ]
			: NULL_VALUE;
	}

	function getStyleProp( element, property ) {
		if ( ! isHTMLElement( element ) ) {
			return NULL_VALUE;
		}

		const STYLE_PROP =
			getObjectValue(
				window.getComputedStyle( element ),
				property
			);

		return isString( STYLE_PROP )
			? STYLE_PROP
			: NULL_VALUE;
	}

	const RECT_RIGHT = 'right';
	const PIXEL_ZERO = 0;

	function getRectProp( element, property ) {
		if (
			! isHTMLElement( element ) ||
			! isFunction( element.getBoundingClientRect )
		) {
			return PIXEL_ZERO;
		}

		const RECT_PROP =
			getObjectValue(
				element.getBoundingClientRect(),
				property
			);

		return isNumber( RECT_PROP )
			? RECT_PROP
			: PIXEL_ZERO;
	}

	function getViewportRight( element ) {
		return getRectProp( element, RECT_RIGHT );
	}

	function getViewportWidth() {
		return (
			window.innerWidth ||
			document.documentElement.clientWidth ||
			document.body.clientWidth
		);
	}

	function removeClass( element, className ) {
		if (
			! isHTMLElement( element ) ||
			! hasClassList( element ) ||
			! isFunction( element.classList.remove ) ||
			! isNonEmptyString( className )
		) {
			return;
		}

		element.classList.remove( className );
	}

	const ATTRIBUTE_STYLE = 'style';

	function filter( items, callback ) {
		return (
			!! items &&
			isFunction( items.filter ) &&
			isFunction( callback )
		)
			? items.filter( callback )
			: NULL_VALUE;
	}

	function hasStyle( element ) {
		return (
			!! element &&
			element.style instanceof CSSStyleDeclaration &&
			isFunction( element.style.setProperty )
		);
	}

	function removeAttribute( element, ...names ) {
		if (
			! isHTMLElement( element ) ||
			! isFunction( element.removeAttribute )
		) {
			return;
		}

		forEach( names, ( name ) => element.removeAttribute( name ) );
	}

	function resetElementInlineStyle( element, ...properties ) {
		if ( ! isHTMLElement( element ) || ! hasStyle( element ) ) {
			return;
		}

		forEach(
			filter( properties, ( property ) => property in element.style ),
			( property ) => element.style[ property ] = EMPTY_STRING
		);

		if ( ! isNonEmptyString( element.style.cssText ) ) {
			removeAttribute( element, ATTRIBUTE_STYLE );
		}
	}

	function setAttribute( element, name, value ) {
		if (
			! isHTMLElement( element ) ||
			! isFunction( element.setAttribute ) ||
			! isNonEmptyString( name )
		) {
			return;
		}

		element.setAttribute( name, value );
	}

	const ATTRIBUTE_ARIA_EXPANDED = 'aria-expanded';

	function isBoolean( value ) {
		return isObjectType( value, 'Boolean' );
	}

	function toggleAriaExpanded( expanded, ...elements ) {
		if ( ! isBoolean( expanded ) ) {
			return;
		}

		forEach(
			elements,
			( element ) => setAttribute(
				element,
				ATTRIBUTE_ARIA_EXPANDED,
				isTrue( expanded )
			)
		);
	}

	const ATTRIBUTE_ARIA_HIDDEN = 'aria-hidden';

	function toggleAriaHidden( hidden, ...elements ) {
		if ( ! isBoolean( hidden ) ) {
			return;
		}

		forEach(
			elements,
			( element ) => setAttribute(
				element,
				ATTRIBUTE_ARIA_HIDDEN,
				isTrue( hidden )
			)
		);
	}

	function toggleClass( add, element, className ) {
		if ( ! isBoolean( add ) ) {
			return;
		}

		const TOGGLE_CLASS = isTrue( add ) ? addClass : removeClass;

		TOGGLE_CLASS( element, className );
	}

	function isStyleProperty( property ) {
		return (
			isString( property ) &&
			hasStyle( document.documentElement ) &&
			property in document.documentElement.style
		);
	}

	function updateInlineStyle(
		element,
		property,
		value,
		isPriority
	) {
		if (
			! element ||
			! hasStyle( element ) ||
			! isStyleProperty( property ) ||
			! ( isString( value ) || isNumber( value ) ) ||
			! isBoolean( isPriority )
		) {
			return;
		}

		if ( isTrue( isPriority ) ) {
			element.style.setProperty( property, value, 'important' );

			return;
		}

		element.style.setProperty( property, value );
	}

	function updateElementInlineStyle(
		element,
		property,
		value,
		isPriority = false
	) {
		if ( ! isHTMLElement( element ) ) {
			return;
		}

		updateInlineStyle( element, property, value, isPriority );
	}

	function isEvent( value ) {
		return (
			value instanceof Event &&
			isFunction( value.preventDefault ) &&
			isFunction( value.stopPropagation )
		);
	}

	function isKey( event, key, keyCode ) {
		return isEvent( event ) && isNonEmptyString( key ) && isNumber( keyCode )
			? areStringsEqualIgnoreCase( event.key, key ) ||
			event.keyCode === keyCode
			: false;
	}

	function isDownKey( event ) {
		return isKey( event, 'ArrowDown', 40 );
	}

	function isEnterKey( event ) {
		return isKey( event, 'Enter', 13 );
	}

	function isEscapeKey( event ) {
		return isKey( event, 'Escape', 27 );
	}

	function isShiftKey( event ) {
		return isEvent( event ) && isTrue( event.shiftKey );
	}

	function isTabKey( event ) {
		return isKey( event, 'Tab', 9 );
	}

	function isUpKey( event ) {
		return isKey( event, 'ArrowUp', 38 );
	}

	const EVENT_CLICK = 'click';

	function isUndefined( value ) {
		return isObjectType( value, 'Undefined' );
	}

	function onDocumentEvent( eventType, callback, options ) {
		if (
			! isNonEmptyString( eventType ) ||
			! isFunction( callback ) ||
			! ( isUndefined( options ) || isObject( options ) || isBoolean( options ) )
		) {
			return;
		}

		document.addEventListener( eventType, callback, options || false );
	}

	function onDocumentClick( callback, options ) {
		onDocumentEvent( EVENT_CLICK, callback, options );
	}

	const EVENT_DOMCONTENTLOADED = 'DOMContentLoaded';

	function onDocumentDomContentLoaded( callback, options ) {
		onDocumentEvent( EVENT_DOMCONTENTLOADED, callback, options );
	}

	const EVENT_FOCUSIN = 'focusin';

	function onDocumentFocusin( callback, options ) {
		onDocumentEvent( EVENT_FOCUSIN, callback, options );
	}

	const EVENT_KEYDOWN = 'keydown';

	function onDocumentKeydown( callback, options ) {
		onDocumentEvent( EVENT_KEYDOWN, callback, options );
	}

	const EVENT_MOUSEDOWN = 'mousedown';

	function onDocumentMousedown( callback, options ) {
		onDocumentEvent( EVENT_MOUSEDOWN, callback, options );
	}

	const EVENT_LOAD = 'load';

	function onWindowEvent( eventType, callback, options ) {
		if (
			! isNonEmptyString( eventType ) ||
			! isFunction( callback ) ||
			! ( isUndefined( options ) || isObject( options ) || isBoolean( options ) )
		) {
			return;
		}

		window.addEventListener( eventType, callback, options || false );
	}

	function onWindowLoad( callback, options ) {
		onWindowEvent( EVENT_LOAD, callback, options );
	}

	const EVENT_RESIZE = 'resize';

	function onWindowResize( callback, options ) {
		onWindowEvent( EVENT_RESIZE, callback, options );
	}

	const EVENT_SCROLL = 'scroll';

	function onWindowScroll( callback, options ) {
		onWindowEvent( EVENT_SCROLL, callback, options );
	}

	const CALLBACK_INITIAL_ATTEMPT_COUNT = 0;
	const CALLBACK_INITIAL_INTERVAL = 0;
	const CALLBACK_INTERVAL = 50;
	const CALLBACK_MAX_ATTEMPT_COUNT = 20;

	function focusElement(
		element,
		attemptCount = CALLBACK_INITIAL_ATTEMPT_COUNT,
		interval = CALLBACK_INITIAL_INTERVAL
	) {
		if (
			! isHTMLElement( element ) ||
			! isFunction( element.focus ) ||
			! isNumber( attemptCount ) ||
			! isNumber( interval ) ||
			attemptCount === CALLBACK_MAX_ATTEMPT_COUNT
		) {
			return;
		}

		element.focus();
		setTimeout(
			() => {
				if ( element === document.activeElement ) {
					return;
				}

				focusElement( element, ++attemptCount, CALLBACK_INTERVAL );
			},
			interval
		);
	}

	function scrollIntoView( element ) {
		if ( ! isHTMLElement( element ) || ! isFunction( element.scrollIntoView ) ) {
			return;
		}

		element.scrollIntoView();
	}

	function hasAttribute( element, attribute ) {
		return (
			!! element &&
			isFunction( element.hasAttribute ) &&
			isTrue( element.hasAttribute( attribute ) )
		);
	}

	const CLASS_SHARED_MOBILE_DEVICE = 'mobile-device';

	function isMobile() {
		return isHTMLElement( document.body, CLASS_SHARED_MOBILE_DEVICE );
	}

	function isDesktop() {
		return ! isMobile();
	}

	function createPreviousEventObject() {
		let wasClick = false;
		let wasMouseDown = false;

		return {
			get wasClick() {
				const WAS_CLICK = wasClick;

				wasClick = false;

				return WAS_CLICK;
			},
			setWasClick: () => wasClick = true,
			get wasMouseDown() {
				const WAS_MOUSE_DOWN = wasMouseDown;

				wasMouseDown = false;

				return WAS_MOUSE_DOWN;
			},
			setWasMouseDown: () => wasMouseDown = true,
		};
	}

	const PREVIOUS_EVENT = createPreviousEventObject();

	function preventMobileMenuResizeFlicker() {
		const MENU_CONTAINER = getMenuContainer();

		if ( ! MENU_CONTAINER ) {
			return;
		}

		updateElementInlineStyle( MENU_CONTAINER, CSS_TRANSITION, CSS_VALUE_NONE );
		requestAnimationFrame( () => {
			resetElementInlineStyle( MENU_CONTAINER, CSS_TRANSITION );
		} );
	}

	function focusPreviousMenuItemLink( menuItemLink ) {
		focusElement( getPreviousMenuItemLink( menuItemLink ) );
	}

	function focusLastTopLevelMobileMenuItemLink() {
		focusElement( getLastTopLevelMobileMenuItemLink() );
	}

	function closeSubmenusAndFocusOnPreviouslyOpenedTopLevelMenuItem() {
		const TOP_LEVEL_DESKTOP_MENU_ITEM_LINK_WITH_HREF_OPENED =
			getOpenedTopLevelDesktopMenuItemLinkWithHref();
		const MENU_ITEM_ELEMENT_TO_FOCUS =
			TOP_LEVEL_DESKTOP_MENU_ITEM_LINK_WITH_HREF_OPENED
				? TOP_LEVEL_DESKTOP_MENU_ITEM_LINK_WITH_HREF_OPENED
				: getOpenedTopLevelDesktopMenuItemSubmenuToggle();

		if ( ! MENU_ITEM_ELEMENT_TO_FOCUS ) {
			return;
		}

		closeSubmenus();
		focusElement( MENU_ITEM_ELEMENT_TO_FOCUS );
	}

	function focusNextMenuItemLink( menuItemLink ) {
		focusElement( getNextMenuItemLink( menuItemLink ) );
	}

	function addSubmenuIdAndSubmenuToggleAriaControls() {
		forEach(
			getMenuItemsWithSubmenu(),
			( menuItem, index ) => {
				const SUBMENU = getSubmenu( menuItem );

				if ( ! SUBMENU ) {
					return;
				}

				if ( ! hasAttribute( SUBMENU, ATTRIBUTE_ID ) ) {
					const ID_MATCH = menuItem.id && menuItem.id.match( /^menu-item-(\d+)$/ );
					const ID_NUMBER = ( ID_MATCH && ID_MATCH[ 1 ] ) || ( index + 1 );

					setAttribute( SUBMENU, ATTRIBUTE_ID, `sub-menu-${ ID_NUMBER }` );
				}

				setAttribute(
					getSubmenuToggle( menuItem ),
					ATTRIBUTE_ARIA_CONTROLS,
					getAttribute( SUBMENU, ATTRIBUTE_ID )
				);
			}
		);
	}

	function focusFirstSubmenuItemLink( submenuOpenerElement ) {
		focusElement( getFirstSubmenuItemLink( submenuOpenerElement ) );
	}

	function isSubmenuOffRight( submenu ) {
		return isSubmenu( submenu )
			? getViewportWidth() < getViewportRight( submenu )
			: false;
	}

	function setSubmenuDirection( submenu ) {
		if ( ! isSubmenu( submenu ) ) {
			return;
		}

		toggleClass(
			isOpenedSubmenuOfTopLevelDesktopMenuItem( submenu ) &&
			isSubmenuOffRight( submenu ),
			submenu,
			CLASS_SHARED_MENU_FLIP
		);
	}

	function openSubmenu( submenuOpenerElement ) {
		const MENU_ITEM_WITH_SUBMENU =
			getMenuItemWithSubmenu(
				submenuOpenerElement
			);

		if ( ! MENU_ITEM_WITH_SUBMENU ) {
			return;
		}

		const SUBMENU = getSubmenu( MENU_ITEM_WITH_SUBMENU );

		if ( ! SUBMENU ) {
			return;
		}

		addClass( MENU_ITEM_WITH_SUBMENU, CLASS_SHARED_SHOW );
		addClass( SUBMENU, CLASS_SHARED_HIDDEN );
		addClass( SUBMENU, CLASS_SHARED_SHOW );
		setSubmenuDirection( SUBMENU );
		removeClass( SUBMENU, CLASS_SHARED_HIDDEN );
		toggleSubmenu( MENU_ITEM_WITH_SUBMENU, TOGGLE_OPEN );
	}

	function openSubmenuAndFocusFirstSubmenuItemLink( submenuOpenerElement ) {
		if ( ! isSubmenuOpenerElement( submenuOpenerElement ) ) {
			return;
		}

		openSubmenu( submenuOpenerElement );
		focusFirstSubmenuItemLink( submenuOpenerElement );
	}

	function closeSiblingAndDescendantMenuItems( element ) {
		if ( ! ( isMenuItemLink( element ) || isSubmenuToggle( element ) ) ) {
			return;
		}

		const MENU_ITEM_PARENT_ELEMENT = getGrandparentElement( element );

		if ( ! MENU_ITEM_PARENT_ELEMENT ) {
			return;
		}

		if ( isMenu( MENU_ITEM_PARENT_ELEMENT ) ) {
			closeSubmenus();
		}

		closeDescendantMenuItems( MENU_ITEM_PARENT_ELEMENT );
	}

	function focusSiteHeaderMenuButton() {
		focusElement( getSiteHeaderMenuButton() );
	}

	function focusMobileMenuButton() {
		focusElement( getMobileMenuButton() );
	}

	function closeMobileMenu() {
		const MOBILE_MENU_BACKGROUND = getMobileMenuBackground();

		if ( ! MOBILE_MENU_BACKGROUND ) {
			return;
		}

		const MENU_CONTAINER = getMenuContainer();

		if ( ! MENU_CONTAINER ) {
			return;
		}

		toggleMenuButtonAriaExpanded( TOGGLE_CLOSE );
		removeClass( MENU_CONTAINER, CLASS_SHARED_SHOW );
		setTimeout(
			() => {
				removeClass( MOBILE_MENU_BACKGROUND, CLASS_SHARED_SHOW );
				removeClass( document.body, CLASS_SHARED_NO_SCROLL );
				toggleMobileMenuAriaHidden();
			},
			DELAY_SHORT
		);
	}

	function toggleSubmenu( menuItemWithSubmenu, open ) {
		if ( ! isBoolean( open ) ) {
			return;
		}

		const SUBMENU_TOGGLE = getSubmenuToggle( menuItemWithSubmenu );

		if ( ! SUBMENU_TOGGLE ) {
			return;
		}

		toggleAriaExpanded(
			open,
			SUBMENU_TOGGLE
		);
		toggleAriaHidden(
			open,
			getSubmenuToggleTextOpen( SUBMENU_TOGGLE )
		);
		toggleAriaHidden(
			! open,
			getSubmenuToggleTextClose( SUBMENU_TOGGLE )
		);
	}

	function closeDescendantMenuItem( openedMenuItemElement ) {
		removeClass( openedMenuItemElement, CLASS_SHARED_SHOW );
		removeClass( openedMenuItemElement, CLASS_SHARED_MENU_FLIP );

		if ( ! isMenuItemWithSubmenu( openedMenuItemElement ) ) {
			return;
		}

		toggleSubmenu( openedMenuItemElement, TOGGLE_CLOSE );
	}

	function closeDescendantMenuItems( element ) {
		forEach( getOpenedMenuItemElements( element ), closeDescendantMenuItem );
	}

	function closeSubmenus() {
		closeDescendantMenuItems( getMenuContainer() );
	}

	function closeMobileMenuAndSubmenus() {
		closeSubmenus();
		closeMobileMenu();
	}

	function closeMobileMenuAndSubmenusAndFocusMenuButton() {
		closeMobileMenuAndSubmenus();

		if ( isMobile() ) {
			focusMobileMenuButton();

			return;
		}

		focusSiteHeaderMenuButton();
	}

	function focusMobileMenuCloseButton() {
		focusElement( getMobileMenuCloseButton() );
	}

	function toggleMenuButtonAriaExpanded( open ) {
		toggleAriaExpanded(
			open,
			isMobile()
				? getMobileMenuButton()
				: getSiteHeaderMenuButton()
		);
	}

	function shouldAriaHideMobileMenu() {
		return isMobile()
			? true
			: ! areStringsEqualIgnoreCase(
				getStyleProp(
					getSiteHeaderMenuButton(),
					CSS_DISPLAY
				),
				CSS_VALUE_NONE
			);
	}

	function toggleMobileMenuAriaHidden( hidden = shouldAriaHideMobileMenu() ) {
		toggleAriaHidden(
			hidden,
			getMainNavigation()
		);
	}

	function openMobileMenu() {
		const MOBILE_MENU_BACKGROUND = getMobileMenuBackground();

		if ( ! MOBILE_MENU_BACKGROUND ) {
			return;
		}

		const MENU_CONTAINER = getMenuContainer();

		if ( ! MENU_CONTAINER ) {
			return;
		}

		const MENU = getMenu();

		if ( ! MENU ) {
			return;
		}

		if ( ! getMobileMenuCloseButton() ) {
			return;
		}

		toggleMobileMenuAriaHidden( TOGGLE_ARIA_VISIBLE );
		addClass( document.body, CLASS_SHARED_NO_SCROLL );
		addClass( MOBILE_MENU_BACKGROUND, CLASS_SHARED_SHOW );
		setTimeout(
			() => {
				toggleMenuButtonAriaExpanded( TOGGLE_OPEN );
				addClass( MENU_CONTAINER, CLASS_SHARED_SHOW );
				scrollIntoView( MENU );
			},
			DELAY_SHORTER
		);
	}

	function openMobileMenuAndFocusMobileMenuCloseButton() {
		openMobileMenu();
		focusMobileMenuCloseButton();
	}

	function addMenuEvents() {
		onDocumentClick( ( event ) => {
			if ( ! isEvent( event ) ) {
				return;
			}

			if (
				isSiteHeaderMenuButton( event.target ) ||
				isMobileMenuButton( event.target )
			) {
				openMobileMenuAndFocusMobileMenuCloseButton();

				return;
			}

			if (
				isMobileMenuBackground( event.target ) ||
				isMobileMenuCloseButton( event.target )
			) {
				closeMobileMenuAndSubmenusAndFocusMenuButton();

				return;
			}

			if (
				isMobileMenuContainer( event.target ) ||
				isCloseMenuButtonContainer( event.target )
			) {
				event.preventDefault();

				return;
			}

			if ( isMenuItemWithSubmenuLinkWithoutHref( event.target ) ) {
				event.stopPropagation();

				return;
			}

			if ( isMainNavigationElement( event.target ) ) {
				if ( isSubmenuOpenerElement( event.target ) ) {
					event.preventDefault();

					if ( isParentMenuItemOpened( event.target ) ) {
						closeSiblingAndDescendantMenuItems( event.target );
						focusElement( event.target );

						return;
					}

					closeSiblingAndDescendantMenuItems( event.target );
					openSubmenuAndFocusFirstSubmenuItemLink( event.target );

					return;
				}

				if (
					isMobileMenuOpened() &&
					isMenuItemLinkWithEmptyAnchorLink( event.target )
				) {
					closeMobileMenuAndSubmenus();

					return;
				}
			}

			closeSubmenus();
		} );
		onDocumentDomContentLoaded( addSubmenuIdAndSubmenuToggleAriaControls );
		onDocumentFocusin( ( event ) => {
			if ( ! isEvent( event ) ) {
				return;
			}

			if (
				(
					isMenuItemLink( event.target ) ||
					isSubmenuToggleOpened( event.target )
				) &&
				! PREVIOUS_EVENT.wasMouseDown
			) {
				closeSiblingAndDescendantMenuItems( event.target );
			}
		} );
		onDocumentKeydown( ( event ) => {
			if ( ! isEvent( event ) ) {
				return;
			}

			if ( isDownKey( event ) ) {
				if ( isMainNavigationElement( event.target ) ) {
					if (
						isSubmenuItemLinkNotLastItem( event.target ) ||
						isTopLevelMobileMenuItemLinkNotLastItem( event.target )
					) {
						event.preventDefault();
						focusNextMenuItemLink( event.target );

						return;
					}

					if ( isSubmenuItemLinkLastItem( event.target ) ) {
						event.preventDefault();
					}
				}

				return;
			}

			if ( isEnterKey( event ) ) {
				if (
					isSiteHeaderMenuButton( event.target ) ||
					isMobileMenuButton( event.target )
				) {
					event.preventDefault();
					openMobileMenuAndFocusMobileMenuCloseButton();

					return;
				}

				if ( isMobileMenuCloseButton( event.target ) ) {
					event.preventDefault();
					closeMobileMenuAndSubmenusAndFocusMenuButton();

					return;
				}

				if ( isMainNavigationElement( event.target ) ) {
					if ( isSubmenuOpenerElement( event.target ) ) {
						event.preventDefault();
						openSubmenuAndFocusFirstSubmenuItemLink( event.target );

						return;
					}

					if (
						isMobileMenuOpened() &&
						isMenuItemLinkWithEmptyAnchorLink( event.target )
					) {
						closeMobileMenuAndSubmenus();

						return;
					}

					if ( isMenuItemLinkWithEmptyAnchorLink( event.target ) ) {
						closeSubmenus();
					}
				}

				return;
			}

			if ( isEscapeKey( event ) ) {
				if ( isMobileMenuOpened() ) {
					event.preventDefault();
					closeMobileMenuAndSubmenusAndFocusMenuButton();

					return;
				}

				if ( isDesktop() ) {
					event.preventDefault();
					closeSubmenusAndFocusOnPreviouslyOpenedTopLevelMenuItem();
				}

				return;
			}

			if ( isTabKey( event ) ) {
				if ( isMainNavigationElement( event.target ) ) {
					if ( isShiftKey( event ) && isMobileMenuCloseButton( event.target ) ) {
						event.preventDefault();
						focusLastTopLevelMobileMenuItemLink();

						return;
					}

					if ( ! isShiftKey( event ) && isEndOfMenu( event.target ) ) {
						closeSubmenus();

						if ( isMobileMenuElement( event.target ) ) {
							event.preventDefault();
							focusMobileMenuCloseButton();
						}
					}

					return;
				}

				if (
					isShiftKey( event ) &&
					isMobileMenuOpened() &&
					! isMainNavigationElement( event.target )
				) {
					event.preventDefault();
					focusMobileMenuCloseButton();
				}

				return;
			}

			if ( isUpKey( event ) ) {
				if ( isMainNavigationElement( event.target ) ) {
					if (
						isSubmenuItemLinkNotFirstItem( event.target ) ||
						isTopLevelMobileMenuItemLinkNotFirstItem( event.target )
					) {
						event.preventDefault();
						focusPreviousMenuItemLink( event.target );

						return;
					}

					if ( isMenuItemLink( event.target ) ) {
						event.preventDefault();
					}
				}
			}
		} );
		onDocumentMousedown( () => {
			PREVIOUS_EVENT.setWasMouseDown();
		} );
		onWindowLoad( () => {
			toggleMobileMenuAriaHidden();
		} );
		onWindowResize( () => {
			if ( isMobile() ) {
				return;
			}

			toggleMobileMenuAriaHidden();

			if ( isMobileMenuOpened() ) {
				closeMobileMenuAndSubmenus();

				return;
			}

			preventMobileMenuResizeFlicker();
			closeSubmenus();
		} );
		onWindowScroll( closeSubmenus );
	}

	const CLASS_SHARED_STICKY = 'sticky';
	const CSS_MARGIN_BOTTOM = 'margin-bottom';

	function isMainNavigation( element ) {
		return isHTMLElement( element, CLASS_NAV_MAIN_NAVIGATION );
	}

	const CLASS_SECTION_SITE_HEADER = 'site-header';

	function getSiteHeader() {
		return getElementByClassName( CLASS_SECTION_SITE_HEADER );
	}

	function isSiteHeader( element ) {
		return isHTMLElement( element, CLASS_SECTION_SITE_HEADER );
	}

	const RECT_HEIGHT = 'height';

	function getHeight( element ) {
		return getRectProp( element, RECT_HEIGHT );
	}

	function getPageHeight() {
		return Math.max(
			document.body.scrollHeight,
			document.body.offsetHeight,
			document.documentElement.clientHeight,
			document.documentElement.scrollHeight,
			document.documentElement.offsetHeight
		);
	}

	function getScrollTop() {
		return isIe()
			? window.pageYOffset
			: window.scrollY || document.documentElement.scrollTop;
	}

	const RECT_TOP = 'top';

	function getViewportTop( element ) {
		return getRectProp( element, RECT_TOP );
	}

	function getPageTop( element ) {
		return getViewportTop( element ) + getScrollTop();
	}

	function getViewportHeight() {
		return (
			window.innerHeight ||
			document.documentElement.clientHeight ||
			document.body.clientHeight
		);
	}

	function toPx( value ) {
		return isNumber( value )
			? value + 'px'
			: EMPTY_STRING;
	}

	const CSS_POSITION = 'position';
	const CSS_VALUE_FIXED = 'fixed';

	function isFixedElement( element ) {
		return areStringsEqualIgnoreCase(
			getStyleProp( element, CSS_POSITION ),
			CSS_VALUE_FIXED
		);
	}

	function isStickyElement( element ) {
		return isHTMLElement( element, CLASS_SHARED_STICKY );
	}

	function addSiteHeaderMarginBottom( mainNavigation, siteHeader ) {
		if ( ! isMainNavigation( mainNavigation ) || ! isSiteHeader( siteHeader ) ) {
			return;
		}

		const MAIN_NAVIGATION_HEIGHT = getHeight( mainNavigation );
		const SITE_HEADER_MARGIN_BOTTOM = isIe()
			? toPx( MAIN_NAVIGATION_HEIGHT )
			: MAIN_NAVIGATION_HEIGHT;

		updateElementInlineStyle(
			siteHeader,
			CSS_MARGIN_BOTTOM,
			SITE_HEADER_MARGIN_BOTTOM
		);
	}

	function updateSiteHeaderMarginBottom( mainNavigation, siteHeader ) {
		if ( ! isMainNavigation( mainNavigation ) || ! isSiteHeader( siteHeader ) ) {
			return;
		}

		addSiteHeaderMarginBottom( mainNavigation, siteHeader );
	}

	function hasMainNavigationHeightChanged( mainNavigation, siteHeader ) {
		return (
			isMainNavigation( mainNavigation ) &&
			isSiteHeader( siteHeader ) &&
			getStyleProp( siteHeader, CSS_MARGIN_BOTTOM ) !== getHeight( mainNavigation )
		);
	}

	function removeSiteHeaderMarginBottom( siteHeader ) {
		if ( ! isSiteHeader( siteHeader ) ) {
			return;
		}

		resetElementInlineStyle( siteHeader, CSS_MARGIN_BOTTOM );
	}

	function canMenuBecomeSticky() {
		const SITE_HEADER = getSiteHeader();

		if ( ! SITE_HEADER ) {
			return false;
		}

		const SCROLLABLE_HEIGHT = getPageHeight() - getViewportHeight();
		const SITE_HEADER_HEIGHT = getHeight( SITE_HEADER );

		return SCROLLABLE_HEIGHT > SITE_HEADER_HEIGHT;
	}

	function toggleStickyMenu() {
		if ( ! canMenuBecomeSticky() ) {
			return;
		}

		const SITE_HEADER = getSiteHeader();

		if ( ! SITE_HEADER ) {
			return;
		}

		if ( isFixedElement( SITE_HEADER ) ) {
			removeSiteHeaderMarginBottom( SITE_HEADER );

			return;
		}

		const MAIN_NAVIGATION = getMainNavigation();

		if ( ! MAIN_NAVIGATION ) {
			return;
		}

		const SCROLL_TOP = getScrollTop();

		if ( isStickyElement( MAIN_NAVIGATION ) ) {
			if ( hasMainNavigationHeightChanged( MAIN_NAVIGATION, SITE_HEADER ) ) {
				updateSiteHeaderMarginBottom( MAIN_NAVIGATION, SITE_HEADER );
			}

			if ( SCROLL_TOP <= getHeight( SITE_HEADER ) ) {
				removeClass( MAIN_NAVIGATION, CLASS_SHARED_STICKY );
				removeSiteHeaderMarginBottom( SITE_HEADER );
			}

			return;
		}

		if ( SCROLL_TOP >= getPageTop( MAIN_NAVIGATION ) ) {
			addClass( MAIN_NAVIGATION, CLASS_SHARED_STICKY );
			addSiteHeaderMarginBottom( MAIN_NAVIGATION, SITE_HEADER );
		}
	}

	function addStickyMenuEvents() {
		onWindowLoad( toggleStickyMenu );
		onWindowResize( toggleStickyMenu );
		onWindowScroll( toggleStickyMenu );
	}

	function addNavigationEvents() {
		addMenuEvents();
		addStickyMenuEvents();
	}

	addNavigationEvents();
}() );
