PageSourceSearch

https://chicchic.ro/wp-content/themes/uncode/library/js/lib/jquery.smartmenus.js?ver=1618642213

js chicchic.ro collected 2026-10-08 14:06:00 UTC 48,607 bytes, 1,183 lines download raw bytes

1/*
2 * SmartMenus jQuery v0.9.6
3 * http://www.smartmenus.org/
4 *
5 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd.
6 * http://vadikom.com/
7 *
8 * Released under the MIT license:
9 * http://www.opensource.org/licenses/MIT
10 */
11
12(function($) {
13
14	var menuTrees = [],
15		IE = !!window.createPopup, // we need to detect it, unfortunately
16		IElt9 = IE && !document.defaultView,
17		IElt8 = IE && !document.querySelector,
18		IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined',
19		mouse = false, // optimize for touch by default - we will detect for mouse input
20		mouseDetectionEnabled = false;
21
22	// Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.)
23	function initMouseDetection(disable) {
24		if (!mouseDetectionEnabled && !disable) {
25			// if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present
26			// in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events)
27			var firstTime = true,
28				lastMove = null;
29			$(document).bind({
30				'mousemove.smartmenus_mouse': function(e) {
31					var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() };
32					if (lastMove) {
33						var deltaX = Math.abs(lastMove.x - thisMove.x),
34							deltaY = Math.abs(lastMove.y - thisMove.y);
35	 					if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) {
36							mouse = true;
37							// if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes
38							if (firstTime) {
39								var $a = $(e.target).closest('a');
40								if ($a.is('a')) {
41									$.each(menuTrees, function() {
42										if ($.contains(this.$root[0], $a[0])) {
43											this.itemEnter({ currentTarget: $a[0] });
44											return false;
45										}
46									});
47								}
48								firstTime = false;
49							}
50						}
51					}
52					lastMove = thisMove;
53				},
54				'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) {
55					if (!/^(4|mouse|pen)$/.test(e.originalEvent.pointerType)) {
56						mouse = false;
57					}
58				}
59			});
60			mouseDetectionEnabled = true;
61		} else if (mouseDetectionEnabled && disable) {
62			$(document).unbind('.smartmenus_mouse');
63			mouseDetectionEnabled = false;
64		}
65	};
66
67	$.SmartMenus = function(elm, options) {
68		this.$root = $(elm);
69		this.opts = options;
70		this.rootId = ''; // internal
71		this.$subArrow = null;
72		this.subMenus = []; // all sub menus in the tree (UL elms) in no particular order (only real - e.g. UL's in mega sub menus won't be counted)
73		this.activatedItems = []; // stores last activated A's for each level
74		this.visibleSubMenus = []; // stores visible sub menus UL's
75		this.showTimeout = 0;
76		this.hideTimeout = 0;
77		this.scrollTimeout = 0;
78		this.clickActivated = false;
79		this.zIndexInc = 0;
80		this.$firstLink = null; // we'll use these for some tests
81		this.$firstSub = null; // at runtime so we'll cache them
82		this.disabled = false;
83		this.$disableOverlay = null;
84		this.lastLevel = 0;
85		this.init();
86	};
87
88	$.extend($.SmartMenus, {
89		hideAll: function() {
90			$.each(menuTrees, function() {
91				this.menuHideAll();
92			});
93		},
94		destroy: function() {
95			while (menuTrees.length) {
96				menuTrees[0].destroy();
97			}
98			initMouseDetection(true);
99		},
100		prototype: {
101			init: function(refresh) {
102				var self = this;
103
104				if (!refresh) {
105					menuTrees.push(this);
106
107					this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, '');
108
109					if (this.$root.hasClass('sm-rtl')) {
110						this.opts.rightToLeftSubMenus = true;
111					}
112
113					// init root (main menu)
114					this.$root
115						.data('smartmenus', this)
116						.attr('data-smartmenus-id', this.rootId)
117						.dataSM('level', 1)
118						.bind({
119							// 'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
120							// 'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this)
121							'mouseover.smartmenus': $.proxy(this.rootOver, this),
122							'mouseout.smartmenus': $.proxy(this.rootOut, this)
123						})
124						.delegate('a, div.logo-container', {
125							'mouseenter.smartmenus': $.proxy(this.itemEnter, this),
126							'mouseleave.smartmenus': $.proxy(this.itemLeave, this),
127							'mousedown.smartmenus': $.proxy(this.itemDown, this),
128							'focus.smartmenus': $.proxy(this.itemFocus, this),
129							'blur.smartmenus': $.proxy(this.itemBlur, this),
130							'click.smartmenus': $.proxy(this.itemClick, this),
131							'touchend.smartmenus': $.proxy(this.itemTouchEnd, this)
132						});
133
134					var eNamespace = '.smartmenus' + this.rootId;
135					// hide menus on tap or click outside the root UL
136					if (this.opts.hideOnClick) {
137							$(document).on('touchstart' + eNamespace, $.proxy(this.docTouchStart, this))
138								.on('touchmove' + eNamespace, $.proxy(this.docTouchMove, this))
139								.on('touchend' + eNamespace, $.proxy(this.docTouchEnd, this))
140								// for Opera Mobile < 11.5, webOS browser, etc. we'll check click too
141								.on('click' + eNamespace, $.proxy(this.docClick, this));
142					}
143					// hide sub menus on resize
144					$(window).on('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
145					var $vmenu = $('body.vmenu .vmenu-container');
146					if ( ! $vmenu.length && UNCODE.wwidth > UNCODE.mediaQuery ) {
147						$(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
148					}
149
150					if (this.opts.subIndicators) {
151						this.$subArrow = $('<span/>').addClass('sub-arrow');
152						if (this.opts.subIndicatorsText) {
153							this.$subArrow.html(this.opts.subIndicatorsText);
154						}
155					}
156
157					// make sure mouse detection is enabled
158					initMouseDetection();
159				}
160
161				// init sub menus
162				this.$firstSub = this.$root.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').each(function() { self.menuInit($(this)); }).eq(0);
163
164				this.$firstLink = this.$root.find('a').eq(0);
165
166				// find current item
167				if (this.opts.markCurrentItem) {
168					var reDefaultDoc = /(index|default)\.[^#\?\/]*/i,
169						reHash = /#.*/,
170						locHref = window.location.href.replace(reDefaultDoc, ''),
171						locHrefNoHash = locHref.replace(reHash, '');
172					this.$root.find('a').each(function() {
173						var href = this.href.replace(reDefaultDoc, ''),
174							$this = $(this);
175						if (href == locHref || href == locHrefNoHash) {
176							$this.addClass('current');
177							if (self.opts.markCurrentTree) {
178								$this.parents('li').each(function() {
179									var $this = $(this);
180									if ($this.dataSM('sub')) {
181										$this.children('a').addClass('current');
182									}
183								});
184							}
185						}
186					});
187				}
188			},
189			destroy: function() {
190				this.menuHideAll();
191				this.$root
192					.removeData('smartmenus')
193					.removeAttr('data-smartmenus-id')
194					.removeDataSM('level')
195					.unbind('.smartmenus')
196					.undelegate('.smartmenus');
197				var eNamespace = '.smartmenus' + this.rootId;
198				$(document).unbind(eNamespace);
199				$(window).unbind(eNamespace);
200				if (this.opts.subIndicators) {
201					this.$subArrow = null;
202				}
203				var self = this;
204				$.each(this.subMenus, function() {
205					if (this.hasClass('mega-menu')) {
206						this.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').removeDataSM('in-mega');
207					}
208					if (this.dataSM('shown-before')) {
209						if (IElt8) {
210							this.children().css({ styleFloat: '', width: '' });
211						}
212						if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) {
213							if (!IE6) {
214								this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap');
215							} else {
216								this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', '');
217							}
218						}
219						if (this.dataSM('scroll-arrows')) {
220							this.dataSM('scroll-arrows').remove();
221						}
222						this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' });
223					}
224					if (self.opts.subIndicators) {
225						this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove();
226					}
227					this.removeDataSM('shown-before')
228						.removeDataSM('ie-shim')
229						.removeDataSM('scroll-arrows')
230						.removeDataSM('parent-a')
231						.removeDataSM('level')
232						.removeDataSM('beforefirstshowfired')
233						.parent().removeDataSM('sub');
234				});
235				if (this.opts.markCurrentItem) {
236					this.$root.find('a.current').removeClass('current');
237				}
238				this.$root = null;
239				this.$firstLink = null;
240				this.$firstSub = null;
241				if (this.$disableOverlay) {
242					this.$disableOverlay.remove();
243					this.$disableOverlay = null;
244				}
245				menuTrees.splice($.inArray(this, menuTrees), 1);
246			},
247			disable: function(noOverlay) {
248				if (!this.disabled) {
249					this.menuHideAll();
250					// display overlay over the menu to prevent interaction
251					if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) {
252						var pos = this.$root.offset();
253						this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({
254							position: 'absolute',
255							top: pos.top,
256							left: pos.left,
257							width: this.$root.outerWidth(),
258							height: this.$root.outerHeight(),
259							zIndex: this.getStartZIndex() + 1,
260							opacity: 0
261						}).appendTo(document.body);
262					}
263					this.disabled = true;
264				}
265			},
266			docClick: function(e) {
267				// hide on any click outside the menu or on a menu link
268				if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a:not([data-filter])')) {
269					this.menuHideAll($(e.target));
270				}
271			},
272			docTouchEnd: function(e) {
273				if (!this.lastTouch) {
274					return;
275				}
276				if (this.visibleSubMenus.length && (this.lastTouch.x2 === undefined || this.lastTouch.x1 == this.lastTouch.x2) && (this.lastTouch.y2 === undefined || this.lastTouch.y1 == this.lastTouch.y2) && (!this.lastTouch.target || !$.contains(this.$root[0], this.lastTouch.target))) {
277					if (this.hideTimeout) {
278						clearTimeout(this.hideTimeout);
279						this.hideTimeout = 0;
280					}
281					// hide with a delay to prevent triggering accidental unwanted click on some page element
282					var self = this;
283					this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350);
284				}
285				this.lastTouch = null;
286			},
287			docTouchMove: function(e) {
288				if (!this.lastTouch) {
289					return;
290				}
291				var touchPoint = e.originalEvent.touches[0];
292				this.lastTouch.x2 = touchPoint.pageX;
293				this.lastTouch.y2 = touchPoint.pageY;
294			},
295			docTouchStart: function(e) {
296				var touchPoint = e.originalEvent.touches[0];
297				this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target };
298			},
299			enable: function() {
300				if (this.disabled) {
301					if (this.$disableOverlay) {
302						this.$disableOverlay.remove();
303						this.$disableOverlay = null;
304					}
305					this.disabled = false;
306				}
307			},
308			getHeight: function($elm) {
309				return this.getOffset($elm, true);
310			},
311			// returns precise width/height float values in IE9+, FF4+, recent WebKit
312			// http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/
313			getOffset: function($elm, height) {
314				var old,
315					$win = $(window),
316					winW = $win.width();
317				if ($elm.css('display') == 'none') {
318					old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility };
319					$elm.css({ position: 'absolute', visibility: 'hidden' }).show();
320					if ( 
321						($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length)
322						||
323						(( $('body').hasClass('vmenu-offcanvas-overlay') || $('body').hasClass('vmenu') ) && winW >= 960 && $elm.closest('.main-menu-container').length && !$elm.closest('.menu-horizontal-inner').length)
324					) {
325						$elm.closest('li').addClass('smartmenu-open-item');
326					}
327				}
328				var defaultView = $elm[0].ownerDocument.defaultView,
329					compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null),
330					val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']);
331				if (val) {
332					val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft'])
333	 					+ parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight'])
334	 					+ parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth'])
335	 					+ parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']);
336				} else {
337					val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth;
338				}
339				if (old) {
340					$elm.hide().css(old);
341				}
342				return val;
343			},
344			getWidth: function($elm) {
345				return this.getOffset($elm);
346			},
347			getStartZIndex: function() {
348				var zIndex = parseInt(this.$root.css('z-index'));
349				return !isNaN(zIndex) ? zIndex : 1;
350			},
351			handleEvents: function() {
352				return !this.disabled && this.isCSSOn();
353			},
354			handleItemEvents: function($a) {
355				return this.handleEvents() && !this.isLinkInMegaMenu($a);
356			},
357			isCollapsible: function() {
358				return this.$firstSub.css('position') == 'static';
359			},
360			isCSSOn: function() {
361				return this.$firstLink.css('display') == 'block' || this.$firstLink.css('display') == 'flex' || this.$firstLink.css('display') == 'inline-flex' || this.$firstLink.css('display') == 'table-cell' || this.$firstLink.css('display') == 'inline';
362			},
363			isFixed: function() {
364				return this.$root.css('position') == 'fixed';
365			},
366			isLinkInMegaMenu: function($a) {
367				return !$a.parent().parent().dataSM('level');
368			},
369			isTouchMode: function() {
370				return !mouse || this.isCollapsible();
371			},
372			itemActivate: function($a, $show) {
373				var $li = $a.parent(),
374					$ul = $li.parent(),
375					level = $ul.dataSM('level'),
376					winh = $(window).height();
377				// if for some reason the parent item is not activated (e.g. this is an API call to activate the item), activate all parent items first
378				if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) {
379					var self = this;
380					$($ul.parentsUntil('[data-smartmenus-id]', 'ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').get().reverse()).add($ul).each(function() {
381						self.itemActivate($(this).dataSM('parent-a'));
382					});
383				}
384				// hide any visible deeper level sub menus
385				if (this.visibleSubMenus.length > level) {
386					for (var i = this.visibleSubMenus.length - 1, l = !this.activatedItems[level - 1] || this.activatedItems[level - 1][0] != $a[0] ? level - 1 : level; i > l; i--) {
387						this.lastLevel = level;
388						if ( typeof $show === 'undefined' && this.isCollapsible() ) {
389							this.menuHide(this.visibleSubMenus[i], $a);
390							return;
391						} else {
392							this.menuHide(this.visibleSubMenus[i]);
393						}
394					}
395				}
396				// save new active item and sub menu for this level
397				this.activatedItems[level - 1] = $a;
398				this.visibleSubMenus[level - 1] = $ul;
399				if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) {
400					return;
401				}
402				// show the sub menu if this item has one
403				var $sub = $li.dataSM('sub');
404				if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) {
405				// if ($sub && (this.isTouchMode() || (!this.opts.showOnClick))) {
406					var aRect = $a[0].getBoundingClientRect();
407					if ( (aRect.y < 0 || aRect.y > winh) && this.isCollapsible() && (this.lastLevel === this.activatedItems.length) ) {
408						setTimeout(function(){
409							var currentScroll = $a.closest('.main-menu-container').scrollTop();
410							$a.closest('.main-menu-container').scrollTop(currentScroll + aRect.y);
411						}, 1);
412					}
413					this.menuShow($sub);
414				}
415			},
416			itemBlur: function(e) {
417				var $a = $(e.currentTarget);
418				if (!this.handleItemEvents($a)) {
419					return;
420				}
421				this.$root.triggerHandler('blur.smapi', $a[0]);
422			},
423			itemClick: function(e) {
424				var $a = $(e.currentTarget);
425
426				if (!this.handleItemEvents($a)) {
427					return;
428				}
429				$a.removeDataSM('mousedown');
430				if (this.$root.triggerHandler('click.smapi', $a[0]) === false) {
431					return false;
432				}
433				var $sub = $a.parent().dataSM('sub');
434				if (this.isTouchMode()) {
435					// undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu
436					if ($a.dataSM('href')) {
437						$a.attr('href', $a.dataSM('href')).removeDataSM('href');
438					}
439					// if the sub is not visible
440					if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
441						// try to activate the item and show the sub
442						this.itemActivate($a);
443						// if "itemActivate" showed the sub, prevent the click so that the link is not loaded
444						// if it couldn't show it, then the sub menus are disabled with an !important declaration (e.g. via mobile styles) so let the link get loaded
445						if ($sub.is(':visible')) {
446							return false;
447						}
448					}
449				// } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub && !$sub.is(':visible')) {
450				} else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) {
451					this.clickActivated = true;
452					this.menuShow($sub);
453					return false;
454				}
455				if ($a.hasClass('disabled')) {
456					return false;
457				}
458				if (this.$root.triggerHandler('select.smapi', $a[0]) === false) {
459					return false;
460				}
461			},
462			itemDown: function(e) {
463				var $a = $(e.currentTarget);
464				if (!this.handleItemEvents($a)) {
465					return;
466				}
467				$a.dataSM('mousedown', true);
468			},
469			itemEnter: function(e) {
470				// if ( this.opts.showOnClick ) {
471				// 	return
472				// }
473				var $a = $(e.currentTarget);
474				if (!this.handleItemEvents($a)) {
475					return;
476				}
477				if (!this.isTouchMode()) {
478					if (this.showTimeout) {
479						clearTimeout(this.showTimeout);
480						this.showTimeout = 0;
481					}
482					var self = this;
483					this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout);
484				}
485				this.$root.triggerHandler('mouseenter.smapi', $a[0]);
486			},
487			itemFocus: function(e) {
488				var $a = $(e.currentTarget);
489				if (!this.handleItemEvents($a)) {
490					return;
491				}
492				// fix (the mousedown check): in some browsers a tap/click produces consecutive focus + click events so we don't need to activate the item on focus
493				if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) {
494					this.itemActivate($a);
495				}
496				this.$root.triggerHandler('focus.smapi', $a[0]);
497			},
498			itemLeave: function(e) {
499				// if ( this.opts.showOnClick ) {
500				// 	return
501				// }
502				var $a = $(e.currentTarget);
503				if (!this.handleItemEvents($a)) {
504					return;
505				}
506				if (!this.isTouchMode()) {
507					if ($a[0].blur) {
508						$a[0].blur();
509					}
510					if (this.showTimeout) {
511						clearTimeout(this.showTimeout);
512						this.showTimeout = 0;
513					}
514				}
515				$a.removeDataSM('mousedown');
516				this.$root.triggerHandler('mouseleave.smapi', $a[0]);
517			},
518			itemTouchEnd: function(e) {
519				var $a = $(e.currentTarget);
520				if (!this.handleItemEvents($a)) {
521					return;
522				}
523				// prevent the address bar on iPhone from sliding down when expanding a sub menu
524				var $sub = $a.parent().dataSM('sub');
525				if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
526					$a.dataSM('href', $a.attr('href'));
527					$a.attr('href', '#');
528				}
529			},
530			menuFixLayout: function($ul) {
531				// fixes a menu that is being shown for the first time
532				if (!$ul.dataSM('shown-before')) {
533					$ul.hide().dataSM('shown-before', true);
534					// fix the layout of the items in IE<8
535					if (IElt8) {
536						$ul.children().css({ styleFloat: 'left', width: '100%' });
537					}
538				}
539			},
540			menuHide: function($sub, $show) {
541				if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) {
542					return;
543				}
544				$sub.stop(true, true);
545				if ($sub.is(':visible')) {
546					var self = this;
547					var complete = function() {
548						// unset z-index
549						if (IElt9) {
550							$sub.parent().css('z-index', '');
551						} else {
552							$sub.css('z-index', '');
553						}
554						if ( typeof $show !== 'undefined' ) {
555							self.itemActivate($show, true)
556						}
557					};
558					// if sub is collapsible (mobile view)
559					if (this.isCollapsible()) {
560						if (this.opts.collapsibleHideFunction) {
561							this.opts.collapsibleHideFunction.call(this, $sub, complete);
562						} else {
563							$sub.hide(this.opts.collapsibleHideDuration, complete);
564						}
565					} else {
566						if (this.opts.hideFunction) {
567							this.opts.hideFunction.call(this, $sub, complete);
568						} else {
569							$sub.hide(this.opts.hideDuration, complete);
570						}
571					}
572					// remove IE iframe shim
573					if ($sub.dataSM('ie-shim')) {
574						$sub.dataSM('ie-shim').remove();
575					}
576					// deactivate scrolling if it is activated for this sub
577					if ($sub.dataSM('scroll')) {
578						$sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide();
579					}
580					// unhighlight parent item
581					$sub.dataSM('parent-a').removeClass('highlighted');
582					var level = $sub.dataSM('level');
583					this.activatedItems.splice(level - 1, 1);
584					this.visibleSubMenus.splice(level - 1, 1);
585					this.$root.triggerHandler('hide.smapi', $sub[0]);
586				}
587			},
588			menuHideAll: function($item) {
589				if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return;
590				var $win = $(window),
591					winW = $win.width();
592				if (this.showTimeout) {
593					clearTimeout(this.showTimeout);
594					this.showTimeout = 0;
595				}
596				// hide all subs
597				for (var i = this.visibleSubMenus.length - 1; i > 0; i--) {
598					if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) {
599						if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) {
600							this.menuHide(this.visibleSubMenus[i]);
601							$(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item');
602						} else {
603							return;
604						}
605					} else {
606						//if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) {
607							this.menuHide(this.visibleSubMenus[i]);
608						//}
609					}
610				}
611				// hide root if it's popup
612				if (this.opts.isPopup) {
613					this.$root.stop(true, true);
614					if (this.$root.is(':visible')) {
615						if (this.opts.hideFunction) {
616							this.opts.hideFunction.call(this, this.$root);
617						} else {
618							this.$root.hide(this.opts.hideDuration);
619						}
620						// remove IE iframe shim
621						if (this.$root.dataSM('ie-shim')) {
622							this.$root.dataSM('ie-shim').remove();
623						}
624					}
625				}
626				this.activatedItems = [];
627				this.visibleSubMenus = [];
628				this.clickActivated = false;
629				// reset z-index increment
630				this.zIndexInc = 0;
631			},
632			menuIframeShim: function($ul) {
633				// create iframe shim for the menu
634				if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) {
635					$ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 })
636						.css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' })
637					);
638				}
639			},
640			menuInit: function($ul) {
641				if (!$ul.dataSM('in-mega')) {
642					this.subMenus.push($ul);
643					// mark UL's in mega drop downs (if any) so we can neglect them
644					if ($ul.hasClass('mega-menu')) {
645						$ul.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').dataSM('in-mega', true);
646					}
647					// get level (much faster than, for example, using parentsUntil)
648					var level = 2,
649						par = $ul[0];
650					while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) {
651						level++;
652					}
653					// cache stuff
654					$ul.dataSM('parent-a', $ul.prevAll('a').eq(-1))
655						.dataSM('level', level)
656						.parent().dataSM('sub', $ul);
657					// add sub indicator to parent item
658					if (this.opts.subIndicators) {
659						$ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone());
660					}
661				}
662				if ( $('.vc_row[data-parent].has-bg', $ul).length && !$('.vc_row[data-parent]:not(.has-bg)', $ul).length ) {
663					$ul.addClass('has-bg-items');
664				}
665			},
666			menuPosition: function($sub) {
667				var fixIE = $('html.ie').length;
668				// if (fixIE) {
669				// 	var $rowParent = $($sub).closest('.main-menu-container');
670				// 	$rowParent.height($rowParent.height());
671				// }
672				var $a = $sub.dataSM('parent-a'),
673					$li = $sub.parent(),
674					$ul = $sub.parent().parent(),
675					// $container = $ul.closest('.row-menu-inner').length ? ( $('body').hasClass('megamenu-side-to-side') ? ( $('body').hasClass('boxed-width') ? $ul.closest('.row-menu') : $(window) ) : $ul.closest('.row-menu-inner') ) : $ul.closest('.uncol'),
676					$container = $ul.closest('.row-menu-inner').length ? ( $('body').hasClass('megamenu-side-to-side') ? $ul.closest('.row-menu') : $ul.closest('.row-menu-inner') ) : $ul.closest('.uncol'),
677					level = $sub.dataSM('level'),
678					subW = this.getWidth($sub),
679					subH = this.getHeight($sub),
680					itemOffset = $a.offset(),
681					itemX = itemOffset.left,
682					itemY = itemOffset.top,
683					itemW = this.getWidth($a),
684					itemH = this.getHeight($a),
685					$win = $(window),
686					winX = $win.scrollLeft(),
687					winY = $win.scrollTop(),
688					winW = $win.width(),
689					winH = $win.height(),
690					containerW = $container.width(),
691					containerOffsetX = containerW + ((winW - containerW) / 2),
692					horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'),
693					subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX,
694					subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY,
695					x, y, leftPos;
696
697				if (horizontalParent) {
698					x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX;
699					y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY;
700				} else {
701					x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX;
702					y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY;
703				}
704				if (this.opts.keepInViewport && !this.isCollapsible()) {
705					if (this.isFixed()) {
706						itemX -= winX;
707						itemY -= winY;
708						winX = winY = 0;
709					}
710					var absX = itemX + x,
711						absY = itemY + y;
712					if (this.opts.rightToLeftSubMenus && absX < winX) {
713						x = horizontalParent ? winX - absX + x : itemW - subOffsetX;
714					} else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) {
715						x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW;
716					}
717					if (!horizontalParent) {
718						if (subH < winH && absY + subH > winY + winH) {
719							y += winY + winH - subH - absY;
720						} else if (subH >= winH || absY < winY) {
721							y += winY - absY;
722						}
723					}
724					// do we need scrolling?
725					// 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH"
726					if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) {
727						var self = this;
728						if (!$sub.dataSM('scroll-arrows')) {
729							$sub.dataSM('scroll-arrows', $([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0], $('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]])
730								.bind({
731									mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); },
732									mouseleave: function(e) {
733										self.menuScrollStop($sub);
734										self.menuScrollOut($sub, e);
735									},
736									'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); }
737								})
738								.insertAfter($sub)
739							);
740						}
741						// bind events to show/hide arrows on hover and save scrolling data for this sub
742						var vportY = winY - (itemY + itemH);
743						$sub.dataSM('scroll', {
744								vportY: vportY,
745								subH: subH,
746								winH: winH,
747								step: 1
748							})
749							.bind({
750								'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); },
751								'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); },
752								'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); }
753							})
754							.dataSM('scroll-arrows').css({ top: 'auto', left: '0', marginLeft: x + (parseInt($sub.css('border-left-width')) || 0), width: this.getWidth($sub) - (parseInt($sub.css('border-left-width')) || 0) - (parseInt($sub.css('border-right-width')) || 0), zIndex: this.get
754StartZIndex() + this.zIndexInc })
755							.eq(0).css('margin-top', vportY).end()
756							.eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end()
757							.eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show();
758					}
759				}
760				if ( !$sub.closest('.menu-accordion').length ) {
761					var rightPos = 'auto';
762					if ( $sub.closest('.grid-filters').length ) {
763						if ( $sub.closest('.text-right').length ) {
764							leftPos = '0px';
765							rightPos = 'auto';
766						} else {
767							leftPos = 'auto';
768							rightPos = '0px';
769						}
770						x = 0;
771					} else {
772						if ( $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)').length && $sub.closest('.row-menu').is('.limit-width') && level === 2) {
773							var parentContW = $sub.closest('.menu-container').width();
774							$sub.css({ width: parentContW});
775							$sub.addClass('need-focus');
776							leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.menu-container').offset().left));
777							x = 0;
778						} else if ( $sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)').length ) {
779							$sub.css({ width: containerW});
780							$sub.addClass('need-focus');
781							leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left));
782							if ( ! $('body').hasClass('megamenu-side-to-side') ) {
783								leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft'));
784							}
785							x = 0;
786						} else {
787							if ( $sub.is('.block-wrapper-parent') && !$sub.find('.col-custom-width').length && !$sub.find('.row-parent-limit').length && level === 2 ) {
788								leftPos = ( $li.position().left - ( (UNCODE.wwidth - $sub.outerWidth() )/2) ) + 'px';
789							} else {
790								leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').css('paddingLeft')) : $li.position().left ) + 'px';
791							}
792							x = (level > 2 && x >= 0) ? x + 1 : x - 1;
793						}
794					}
795				}
796
797				// $sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, right: rightPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-borders').length ? 1 : 0) });
798				$sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, right: rightPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-borders').length && !$sub.closest('.menu-borders.needs-after').length ? 1 : 0) });
799				// IE iframe shim
800				this.menuIframeShim($sub);
801				if ($sub.dataSM('ie-shim')) {
802					$sub.dataSM('ie-shim').css({ zIndex: $sub.css('z-index'), width: subW, height: subH, marginLeft: x, marginTop: y - itemH + ($sub.closest('.menu-mini').length ? 0 : 1) });
803				}
804			},
805			menuScroll: function($sub, up, wheel) {
806				var y = parseFloat($sub.css('margin-top')),
807					scroll = $sub.dataSM('scroll'),
808					navH = $('.navbar-main').outerHeight(),
809					end = scroll.vportY + (up ? navH + 54 : scroll.winH - scroll.subH),
810					step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step);
811				$sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end);
812				y = parseFloat($sub.css('margin-top'));
813				// show opposite arrow if appropriate
814				if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) {
815					$sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show();
816				}
817				// accelerate when not using mousewheel to scroll
818				if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) {
819					$sub.dataSM('scroll').step += 0.5;
820				}
821				// "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used
822				if (Math.abs(y - end) < 1) {
823					$sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide();
824					$sub.dataSM('scroll').step = 1;
825				} else if (!wheel) {
826					var self = this;
827					this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval);
828				}
829			},
830			menuScrollMousewheel: function($sub, e) {
831				var $closestSub = $(e.target).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
832				while ($closestSub.dataSM('in-mega')) {
833					$closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
834				}
835				if ($closestSub[0] == $sub[0]) {
836					var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0;
837					if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) {
838						this.menuScroll($sub, up, true);
839					}
840				}
841				if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) {
842					e.preventDefault();
843				}
844			},
845			menuScrollOut: function($sub, e) {
846				var reClass = /^scroll-(up|down)/,
847					$closestSub = $(e.relatedTarget).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
848				while ($closestSub.dataSM('in-mega')) {
849					$closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
850				}
851				if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) {
852					$sub.dataSM('scroll-arrows').css('visibility', 'hidden');
853				}
854			},
855			menuScrollOver: function($sub, e) {
856				var reClass = /^scroll-(up|down)/,
857					$closestSub = $(e.target).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
858				while ($closestSub.dataSM('in-mega')) {
859					$closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
860				}
861				if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) {
862					$sub.dataSM('scroll-arrows').css('visibility', 'visible');
863				}
864			},
865			menuScrollStop: function($sub) {
866				if (this.scrollTimeout) {
867					clearTimeout(this.scrollTimeout);
868					this.scrollTimeout = 0;
869					$sub.dataSM('scroll').step = 1;
870				}
871			},
872			menuShow: function($sub) {
873				if (!$sub.dataSM('beforefirstshowfired')) {
874					$sub.dataSM('beforefirstshowfired', true);
875					if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) {
876						return;
877					}
878				}
879				if ( this.isCollapsible() ) {
880					this.$root.triggerHandler('beforecollapse.smapi', $sub[0]);
881				}
882				if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) {
883					return;
884				}
885				this.menuFixLayout($sub);
886				$sub.stop(true, true);
887				if (!$sub.is(':visible')) {
888					$sub.css({
889						'visibility': 'visible',
890						'pointer-events': 'auto',
891					});
892					// set z-index - for IE < 9 set it to the parent LI
893					var zIndex = this.getStartZIndex() + (++this.zIndexInc);
894					if (IElt9) {
895						$sub.parent().css('z-index', zIndex);
896					} else {
897						$sub.css('z-index', zIndex);
898					}
899					// highlight parent item
900					if (this.opts.keepHighlighted || this.isCollapsible()) {
901						if ($sub.dataSM('parent-a').attr('data-type') != 'title')
902							$sub.dataSM('parent-a').addClass('highlighted');
903					}
904					// min/max-width fix - no way to rely purely on CSS as all UL's are nested
905					if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) {
906						if (!IElt8) {
907							$sub.css({ width: ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
908							if (this.opts.subMenusMinWidth) {
909							 	$sub.css('min-width', this.opts.subMenusMinWidth);
910							}
911							if (this.opts.subMenusMaxWidth) {
912							 	var noMaxWidth = this.getWidth($sub);
913							 	if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) {
914								 	$sub.css('max-width', this.opts.subMenusMaxWidth);
915							 	}
916								if (noMaxWidth > this.getWidth($sub)) {
917									$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
918								}
919							}
920						// IE6,7
921 						} else {
922							$sub.children().css('styleFloat', 'none');
923							if (IE6) {
924								$sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1)
925									.children().children('a').css('white-space', 'nowrap');
926							} else { // IE7
927								$sub.css({ width: ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
928								if (this.opts.subMenusMinWidth) {
929									$sub.css('min-width', this.opts.subMenusMinWidth);
930								}
931							}
932							if (this.opts.subMenusMaxWidth) {
933								var noMaxWidth = $sub.width();
934								if (IE6) {
935							 		var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width();
936									if (noMaxWidth > maxWidth) {
937										$sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', '');
938									} else {
939										$sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' });
940									}
941								} else { // IE7
942								 	if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) {
943									 	$sub.css('max-width', this.opts.subMenusMaxWidth);
944								 	}
945									if (noMaxWidth > $sub.width()) {
946										$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
947									} else {
948										$sub.width(noMaxWidth);
949									}
950								}
951							} else {
952							 	$sub.width($sub.width());
953							}
954							$sub.children().css('styleFloat', 'left');
955						}
956					}
957					if ( ( ( ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) && $('body').hasClass('scrollable-megamenu') ) ) && UNCODE.wwidth > UNCODE.mediaQuery ) {
958						var $nav = $('.navbar-main'),
959							navH = 0,
960							navTop = 0,
961							$vmenu = $('body.vmenu .vmenu-container, body.menu-overlay .vmenu-container, body.menu-offcanvas .vmenu-container');
962						if ( $nav.length && typeof $nav[0] !== 'undefined' ) {
963							var navRect = $nav[0].getBoundingClientRect();
964							navH = navRect.height;
965							navTop = navRect.top;
966						}
967						if ( ! $vmenu.length ) {
968							$sub.css({ maxHeight: UNCODE.wheight - navH });
969							if ( $('.megamenu-block-wrapper', $sub).length ) {
970								$sub.find('> li').addClass('has-scroll').css({ maxHeight: UNCODE.wheight - navH });
971							}
972						}
973					}
974					this.menuPosition($sub);
975					// insert IE iframe shim
976					if ($sub.dataSM('ie-shim')) {
977						$sub.dataSM('ie-shim').insertBefore($sub);
978					}
979					var complete = function() {
980						// fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used
981						$sub.css('overflow', '');
982					};
983					// if sub is collapsible (mobile view)
984					if (this.isCollapsible()) {
985						if (this.opts.collapsibleShowFunction) {
986							this.opts.collapsibleShowFunction.call(this, $sub, complete);
987						} else {
988							$sub.show(this.opts.collapsibleShowDuration, complete);
989						}
990					} else {
991						if (this.opts.showFunction) {
992							this.opts.showFunction.call(this, $sub, complete);
993						} else {
994							$sub.show(this.opts.showDuration, complete);
995						}
996					}
997					// save new sub menu for this level
998					this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub;
999					this.$root.triggerHandler('show.smapi', $sub[0]);
1000				}
1001			},
1002			popupHide: function(noHideTimeout) {
1003				if (this.hideTimeout) {
1004					clearTimeout(this.hideTimeout);
1005					this.hideTimeout = 0;
1006				}
1007				var self = this;
1008				this.hideTimeout = setTimeout(function() {
1009					self.menuHideAll();
1010				}, noHideTimeout ? 1 : this.opts.hideTimeout);
1011			},
1012			popupShow: function(left, top) {
1013				if (!this.opts.isPopup) {
1014					alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.');
1015					return;
1016				}
1017				if (this.hideTimeout) {
1018					clearTimeout(this.hideTimeout);
1019					this.hideTimeout = 0;
1020				}
1021				this.menuFixLayout(this.$root);
1022				this.$root.stop(true, true);
1023				if (!this.$root.is(':visible')) {
1024					this.$root.css({ left: left, top: top });
1025					// IE iframe shim
1026					this.menuIframeShim(this.$root);
1027					if (this.$root.dataSM('ie-shim')) {
1028						this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
1028: left, top: top }).insertBefore(this.$root);
1029					}
1030					// show menu
1031					if (this.opts.showFunction) {
1032						this.opts.showFunction.call(this, this.$root);
1033					} else {
1034						this.$root.show(this.opts.showDuration);
1035					}
1036					this.visibleSubMenus[0] = this.$root;
1037				}
1038			},
1039			refresh: function() {
1040				this.menuHideAll();
1041				this.$root.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').each(function() {
1042						var $this = $(this);
1043						if ($this.dataSM('scroll-arrows')) {
1044							$this.dataSM('scroll-arrows').remove();
1045						}
1046					})
1047					.removeDataSM('in-mega')
1048					.removeDataSM('shown-before')
1049					.removeDataSM('ie-shim')
1050					.removeDataSM('scroll-arrows')
1051					.removeDataSM('parent-a')
1052					.removeDataSM('level')
1053					.removeDataSM('beforefirstshowfired');
1054				this.$root.find('a.has-submenu').removeClass('has-submenu')
1055					.parent().removeDataSM('sub');
1056				if (this.opts.subIndicators) {
1057					this.$root.find('span.sub-arrow').remove();
1058				}
1059				if (this.opts.markCurrentItem) {
1060					this.$root.find('a.current').removeClass('current');
1061				}
1062				this.subMenus = [];
1063				this.init(true);
1064			},
1065			rootOut: function(e) {
1066				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
1067					return;
1068				}
1069				if (this.hideTimeout) {
1070					clearTimeout(this.hideTimeout);
1071					this.hideTimeout = 0;
1072				}
1073				if (!this.opts.showOnClick || !this.opts.hideOnClick) {
1074					var self = this;
1075					this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout);
1076				}
1077			},
1078			rootOver: function(e) {
1079				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
1080					return;
1081				}
1082				if (this.hideTimeout) {
1083					clearTimeout(this.hideTimeout);
1084					this.hideTimeout = 0;
1085				}
1086			},
1087			winResize: function(e) {
1088				if (!this.handleEvents()) {
1089					// we still need to resize the disable overlay if it's visible
1090					if (this.$disableOverlay) {
1091						var pos = this.$root.offset();
1092	 					this.$disableOverlay.css({
1093							top: pos.top,
1094							left: pos.left,
1095							width: this.$root.outerWidth(),
1096							height: this.$root.outerHeight()
1097						});
1098					}
1099					return;
1100				}
1101				// hide sub menus on resize - on mobile do it only on orientation change
1102				if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) {
1103					if (this.activatedItems.length) {
1104						this.activatedItems[this.activatedItems.length - 1][0].blur();
1105					}
1106					this.menuHideAll();
1107				}
1108			}
1109		}
1110	});
1111
1112	$.fn.dataSM = function(key, val) {
1113		if (val) {
1114			return this.data(key + '_smartmenus', val);
1115		}
1116		return this.data(key + '_smartmenus');
1117	}
1118
1119	$.fn.removeDataSM = function(key) {
1120		return this.removeData(key + '_smartmenus');
1121	}
1122
1123	$.fn.smartmenus = function(options) {
1124		if (typeof options == 'string') {
1125			var args = arguments,
1126				method = options;
1127			Array.prototype.shift.call(args);
1128			return this.each(function() {
1129				var smartmenus = $(this).data('smartmenus');
1130				if (smartmenus && smartmenus[method]) {
1131					smartmenus[method].apply(smartmenus, args);
1132				}
1133			});
1134		}
1135		var opts = $.extend({}, $.fn.smartmenus.defaults, options);
1136		return this.each(function() {
1137			new $.SmartMenus(this, opts);
1138		});
1139	}
1140
1141	// default settings
1142	$.fn.smartmenus.defaults = {
1143		isPopup:		false,		// is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar
1144		mainMenuSubOffsetX:	0,		// pixels offset from default position
1145		mainMenuSubOffsetY:	0,		// pixels offset from default position
1146		subMenusSubOffsetX:	0,		// pixels offset from default position
1147		subMenusSubOffsetY:	0,		// pixels offset from default position
1148		subMenusMinWidth:	false, //'10em',		// min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
1149		subMenusMaxWidth:	false, //'20em',		// max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
1150		subIndicators: 		true,		// create sub menu indicators - creates a SPAN and inserts it in the A
1151		subIndicatorsPos: 	'prepend',	// position of the SPAN relative to the menu item content ('prepend', 'append')
1152		subIndicatorsText:	'+',		// [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too)
1153		scrollStep: 		30,		// pixels step when scrolling long sub menus that do not fit in the viewport height
1154		scrollInterval:		30,		// interval between each scrolling step
1155		scrollAccelerate:	true,		// accelerate scrolling or use a fixed step
1156		showTimeout:		250,		// timeout before showing the sub menus
1157		hideTimeout:		500,		// timeout before hiding the sub menus
1158		showDuration:		0,		// duration for show animation - set to 0 for no animation - matters only if showFunction:null
1159		showFunction:		null,		// custom function to use when showing a sub menu (the default is the jQuery 'show')
1160							// don't forget to call complete() at the end of whatever you do
1161							// e.g.: function($ul, complete) { $ul.fadeIn(250, complete); }
1162		hideDuration:		0,		// duration for hide animation - set to 0 for no animation - matters only if hideFunction:null
1163		hideFunction:		function($ul, complete) { $ul.fadeOut(200, complete); },	// custom function to use when hiding a sub menu (the default is the jQuery 'hide')
1164							// don't forget to call complete() at the end of whatever you do
1165							// e.g.: function($ul, complete) { $ul.fadeOut(250, complete); }
1166		collapsibleShowDuration:0,		// duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null
1167		collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); },	// custom function to use when showing a collapsible sub menu
1168							// (i.e. when mobile styles are used to make the sub menus collapsible)
1169		collapsibleHideDuration:0,		// duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null
1170		collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); },	// custom function to use when hiding a collapsible sub menu
1171							// (i.e. when mobile styles are used to make the sub menus collapsible)
1172		showOnClick:		false,		// show the first-level sub menus onclick instead of onmouseover (matters only for mouse input)
1173		hideOnClick:		true,		// hide the sub menus on click/tap anywhere on the page
1174		keepInViewport:		true,		// reposition the sub menus if needed to make sure they always appear inside the viewport
1175		keepHighlighted:	true,		// keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's)
1176		markCurrentItem:	false,		// automatically add the 'current' class to the A element of the item linking to the current URL
1177		markCurrentTree:	true,		// add the 'current' class also to the A elements of all ancestor items of the current item
1178		rightToLeftSubMenus:	false,		// right to left display of the sub menus (check the CSS for the sub indicators' position)
1179		bottomToTopSubMenus:	false,		// bottom to top display of the sub menus
1180		overlapControlsInIE:	true		// make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.)
1181	};
1182
1183})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.