PageSourceSearch

https://buckinghamcrossfit.ca/wp-content/themes/Impreza/framework/js/us.core.js?ver=3.3.2

js buckinghamcrossfit.ca collected 2026-10-08 03:29:09 UTC 46,813 bytes, 1,427 lines download raw bytes

1/**
2 * UpSolution Theme Core JavaScript Code
3 *
4 * @requires jQuery
5 */
6if (window.$us === undefined) window.$us = {};
7
8/**
9 * Retrieve/set/erase dom modificator class <mod>_<value> for UpSolution CSS Framework
10 * @param {String} mod Modificator namespace
11 * @param {String} [value] Value
12 * @returns {string|jQuery}
13 */
14jQuery.fn.usMod = function(mod, value){
15	if (this.length == 0) return this;
16	// Remove class modificator
17	if (value === false) {
18		this.get(0).className = this.get(0).className.replace(new RegExp('(^| )' + mod + '\_[a-z0-9]+( |$)'), '$2');
19		return this;
20	}
21	var pcre = new RegExp('^.*?' + mod + '\_([a-z0-9]+).*?$'),
22		arr;
23	// Retrieve modificator
24	if (value === undefined) {
25		return (arr = pcre.exec(this.get(0).className)) ? arr[1] : false;
26	}
27	// Set modificator
28	else {
29		this.usMod(mod, false).get(0).className += ' ' + mod + '_' + value;
30		return this;
31	}
32};
33
34/**
35 * Convert data from PHP to boolean the right way
36 * @param {mixed} value
37 * @returns {Boolean}
38 */
39$us.toBool = function(value){
40	if (typeof value == 'string') return (value == 'true' || value == 'True' || value == 'TRUE' || value == '1');
41	if (typeof value == 'boolean') return value;
42	return !!parseInt(value);
43};
44
45// Fixing hovers for devices with both mouse and touch screen
46jQuery.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
47jQuery('html').toggleClass('no-touch', !jQuery.isMobile);
48
49/**
50 * Commonly used jQuery objects
51 */
52!function($){
53	$us.$window = $(window);
54	$us.$document = $(document);
55	$us.$html = $('html');
56	$us.$body = $('.l-body:first');
57	$us.$htmlBody = $us.$html.add($us.$body);
58	$us.$canvas = $('.l-canvas:first');
59}(jQuery);
60
61/**
62 * $us.canvas
63 *
64 * All the needed data and functions to work with overall canvas.
65 */
66!function($){
67	"use strict";
68
69	function USCanvas(options){
70
71		// Setting options
72		var defaults = {
73			disableEffectsWidth: 900,
74			responsive: true
75		};
76		this.options = $.extend({}, defaults, options || {});
77
78		// Commonly used dom elements
79		this.$header = $us.$canvas.find('.l-header');
80		this.$main = $us.$canvas.find('.l-main');
81		this.$titlebar = $us.$canvas.find('.l-titlebar');
82		this.$sections = $us.$canvas.find('.l-section');
83		this.$firstSection = this.$sections.first();
84		this.$fullscreenSections = this.$sections.filter('.height_full');
85		this.$topLink = $('.w-toplink');
86
87		// Canvas modificators
88		this.sidebar = $us.$canvas.usMod('sidebar');
89		this.type = $us.$canvas.usMod('type');
90		// Initial header position
91		this._headerPos = this.$header.usMod('pos');
92		// Current header position
93		this.headerPos = this._headerPos;
94		this.headerBg = this.$header.usMod('bg');
95		this.rtl = $us.$body.hasClass('rtl');
96
97		// Will be used to count fullscreen sections heights and proper scroll positions
98		this.scrolledOccupiedHeight = 0;
99
100		// Boundable events
101		this._events = {
102			scroll: this.scroll.bind(this),
103			resize: this.resize.bind(this)
104		};
105
106		$us.$window.on('scroll', this._events.scroll);
107		$us.$window.on('resize load', this._events.resize);
108		// Complex logics requires two initial renders: before inner elements render and after
109		setTimeout(this._events.resize, 25);
110		setTimeout(this._events.resize, 75);
111	}
112
113	USCanvas.prototype = {
114
115		/**
116		 * Scroll-driven logics
117		 */
118		scroll: function(){
119			var scrollTop = parseInt($us.$window.scrollTop());
120
121			// Show/hide go to top link
122			this.$topLink.toggleClass('active', (scrollTop >= this.winHeight));
123		},
124
125		/**
126		 * Resize-driven logics
127		 */
128		resize: function(){
129			// Window dimensions
130			this.winHeight = parseInt($us.$window.height());
131			this.winWidth = parseInt($us.$window.width());
132
133			// Disabling animation on mobile devices
134			$us.$body.toggleClass('disable_effects', (this.winWidth <= this.options.disableEffectsWidth));
135
136			// Updating fullscreen sections
137			if (this.$fullscreenSections.length > 0) {
138				this.$fullscreenSections.each(function(index, section){
139					var $section = $(section),
140						sectionHeight = this.winHeight,
141						isFirstSection = (index == 0 && this.$titlebar.length == 0 && $section.is(this.$firstSection));
142					// First section
143					if (isFirstSection) {
144						sectionHeight -= $section.offset().top;
145					}
146					// 2+ sections
147					else {
148						sectionHeight -= $us.header.scrolledOccupiedHeight;
149					}
150					$section.css('min-height', sectionHeight);
151					if ($section.hasClass('valign_center')) {
152						var $sectionH = $section.find('.l-section-h'),
153							sectionTopPadding = parseInt($section.css('padding-top')),
154							contentHeight = $sectionH.outerHeight(),
155							topMargin;
156						$sectionH.css('margin-top', '');
157						// Section was extended by extra top padding that is overlapped by fixed solid header and n
157ot visible
158						var sectionOverlapped = isFirstSection && $us.header.pos == 'fixed' && $us.header.bg != 'transparent' && $us.header.orientation != 'ver';
159						if (sectionOverlapped) {
160							// Part of first section is overlapped by header
161							topMargin = Math.max(0, (sectionHeight - sectionTopPadding - contentHeight) / 2);
162						} else {
163							topMargin = Math.max(0, (sectionHeight - contentHeight) / 2 - sectionTopPadding);
164						}
165						$sectionH.css('margin-top', topMargin || '');
166					}
167					$section.find('.upb_row_bg').css('min-height', $section.height());
168				}.bind(this));
169				$us.$canvas.trigger('contentChange');
170			}
171
172			// Fix scroll glitches that could occur after the resize
173			this.scroll();
174		}
175	};
176
177	$us.canvas = new USCanvas($us.canvasOptions || {});
178
179}(jQuery);
180
181/**
182 * $us.header
183 * Dev note: should be initialized after $us.canvas
184 */
185!function($){
186	"use strict";
187	function USHeader(settings){
188		this.settings = settings || {};
189		this.state = 'default'; // 'tablets' / 'mobiles'
190		this.$container = $us.$canvas.find('.l-header');
191		this.$topCell = this.$container.find('.l-subheader.at_top .l-subheader-cell:first');
192		this.$middleCell = this.$container.find('.l-subheader.at_middle .l-subheader-cell:first');
193		this.$bottomCell = this.$container.find('.l-subheader.at_bottom .l-subheader-cell:first');
194		this.$showBtn = $('.w-header-show:first');
195		this.orientation = $us.$body.usMod('header');
196		this.pos = this.$container.usMod('pos'); // 'fixed' / 'static'
197		this.bg = this.$container.usMod('bg'); // 'solid' / 'transparent'
198
199		// Will be used to count fullscreen sections heights and proper scroll positions
200		this.scrolledOccupiedHeight = 0;
201
202		this._events = {
203			scroll: this.scroll.bind(this),
204			resize: this.resize.bind(this),
205			contentChange: function(){
206				this._countScrollable();
207			}.bind(this),
208			hideMobileVerticalHeader: function(e){
209				if ($.contains(this.$container[0], e.target)) return;
210				$us.$body
211					.off($.isMobile ? 'touchstart' : 'click', this._events.hideMobileVerticalHeader)
212					.removeClass('header-show');
213			}.bind(this)
214		};
215		this.$elms = {};
216		this.$places = {
217			hidden: this.$container.find('.l-subheader.for_hidden')
218		};
219		this.$container.find('.l-subheader-cell').each(function(index, cell){
220			var $cell = $(cell);
221			this.$places[$cell.parent().parent().usMod('at') + '_' + $cell.usMod('at')] = $cell;
222		}.bind(this));
223		var regexp = /(^| )ush_([a-z_]+)_([0-9]+)( |$)/;
224		this.$container.find('[class*=ush_]').each(function(index, elm){
225			var $elm = $(elm),
226				matches = regexp.exec($elm.attr('class'));
227			if (!matches) return;
228			var id = matches[2] + ':' + matches[3];
229			this.$elms[id] = $elm;
230			if ($elm.is('.w-vwrapper, .w-hwrapper')) {
231				this.$places[id] = $elm;
232			}
233		}.bind(this));
234		// TODO Objects with the header elements
235		$us.$window.on('scroll', this._events.scroll);
236		$us.$window.on('resize load', this._events.resize);
237		this.resize();
238
239		$us.$canvas.on('contentChange', function(){
240			if (this.orientation == 'ver') this.docHeight = $us.$document.height();
241		}.bind(this));
242
243		this.$container.on('contentChange', this._events.contentChange);
244
245		this.$showBtn.on('click', function(e){
246			if ($us.$body.hasClass('header-show')) return;
247			e.stopPropagation();
248			$us.$body
249				.addClass('header-show')
250				.on($.isMobile ? 'touchstart' : 'click', this._events.hideMobileVerticalHeader);
251		}.bind(this));
252	}
253
254	$.extend(USHeader.prototype, {
255		scroll: function(){
256			var scrollTop = parseInt($us.$window.scrollTop());
257			if (this.pos == 'fixed') {
258				if (this.orientation == 'hor') {
259					this.$container.toggleClass('sticky', scrollTop >= (this.settings[this.state].options.scroll_breakpoint || 100));
260				} else if (this.$container.hasClass('scrollable') && this.docHeight > this.headerHeight + this.htmlTopMargin) {
261					var scrollRangeDiff = this.headerHeight - $us.canvas.winHeight + this.htmlTopMargin;
262					if (this._sidedHeaderScrollRange === undefined) {
263						this._sidedHeaderScrollRange = [0, scrollRangeDiff];
264					}
265					if (scrollTop <= this._sidedHeaderScrollRange[0]) {
266						this._sidedHeaderScrollRange[0] = Math.max(0, scrollTop);
267						this._sidedHeaderScrollRange[1] = this._sidedHeaderScrollRange[0] + scrollRangeDiff;
268						this.$container.css({
269							position: 'fixed',
270							top: this.htmlTopMargin
271						});
272					}
273					else if (this._sidedHeaderScrollRange[0] < scrollTop && scrollTop < this._sidedHeaderScrollRange[1]) {
274						this.$container.css({
275							position: 'absolute',
276							top: this._sidedHeaderScrollRange[0]
277						});
278					}
279					else if (this._sidedHeaderScrollRange[1] <= scrollTop) {
280						this._sidedHeaderScrollRange[1] = Math.min(this.docHeight - $us.canvas.winHeight, scrollTop);
281						this._sidedHeaderScrollRange[0] = this._sidedHeaderScrollRange[1] - scrollRangeDiff;
282						this.$container.css({
283							position: 'fixed',
284							top: $us.canvas.winHeight - this.headerHeight
285						});
286					}
287				}
288			}
289		},
290		resize: function(){
291			var newState = 'default';
292			if (window.innerWidth <= 900) newState = (window.innerWidth <= 600) ? 'mobiles' : 'tablets';
293			this.setState(newState);
294			if (this.pos == 'fixed' && this.orientation == 'hor') {
295				var isSticky = this.$container.hasClass('sticky');
296				this.$container.addClass('notransition');
297				if (!isSticky) this.$container.addClass('sticky');
298				this.scrolledOccupiedHeight = this.$container.height();
299				if (!isSticky) this.$container.removeClass('sticky');
300				// Removing with a small delay to prevent css glitch
301				setTimeout(function(){
302					this.$container.removeClass('notransition');
303				}.bind(this), 50);
304			} else /*if (this.orientation == 'ver' || this.pos == 'static')*/ {
305				this.scrolledOccupiedHeight = 0;
306			}
307			this._countScrollable();
308			this.scroll();
309		},
310		setState: function(newState){
311			if (newState == this.state) return;
312			var newOrientation = this.settings[newState].options.orientation || 'hor',
313				newPos = $us.toBool(this.settings[newState].options.sticky) ? 'fixed' : 'static',
314				newBg = $us.toBool(this.settings[newState].options.transparent) ? 'transparent' : 'solid';
315			if (newOrientation == 'ver') {
316				newPos = 'fixed';
317				newBg = 'solid';
318			}
319			this.state = newState;
320			// Don't change the order: orientation -> pos -> bg -> layout
321			this._setOrientation(newOrientation);
322			this._setPos(newPos);
323			this._setBg(newBg);
324			this._setLayout(this.settings[newState].layout || {});
325			$us.$body.usMod('state', newState);
326			if (newState == 'default') $us.$body.removeClass('header-show');
327			// Updating the main menu because of dependencies
328			if ($us.nav !== undefined) $us.nav.resize();
329		},
330		_setOrientation: function(newOrientation){
331			if (newOrientation == this.orientation) return;
332			$us.$body.usMod('header', newOrientation);
333			this.orientation = newOrientation;
334		},
335		_countScrollable: function(){
336			if (this.orientation == 'ver' && this.pos == 'fixed' && this.state == 'default') {
337				this.docHeight = $us.$document.height();
338				this.htmlTopMargin = parseInt($us.$html.css('margin-top'));
339				this.headerHeight = this.$topCell.height() + this.$middleCell.height() + this.$bottomCell.height();
340				if (this.headerHeight > $us.canvas.winHeight - this.htmlTopMargin) {
341					this.$container.addClass('scrollable');
342				} else if (this.$container.hasClass('scrollable')) {
343					this.$container.removeClass('scrollable').resetInlineCSS('position', 'top', 'bottom');
344					delete this._sidedHeaderScrollRange;
345				}
346				if (this.headerHeight + this.htmlTopMargin >= this.docHeight) {
347					this.$container.css({
348						position: 'absolute',
349						top: 0
350					});
351				}
352			} else if (this.$container.hasClass('scrollable')) {
353				this.$container.removeClass('scrollable').resetInlineCSS('position', 'top', 'bottom');
354				delete this._sidedHeaderScrollRange;
355			}
356		},
357		_setPos: function(newPos){
358			if (newPos == this.pos) return;
359			this.$container.usMod('pos', newPos);
360			if (newPos == 'static') {
361				this.$container.removeClass('sticky');
362			}
363			this.pos = newPos;
364			this._countScrollable();
365		},
366		_setBg: function(newBg){
367			if (newBg == this.bg) return;
368			this.$container.usMod('bg', newBg);
369			this.bg = newBg;
370		},
371		/**
372		 * Recursive function to place elements based on their ids
373		 * @param {Array} elms
374		 * @param {jQuery} $place
375		 * @private
376		 */
377		_placeElements: function(elms, $place){
378			for (var i = 0; i < elms.length; i++) {
379				var elmId;
380				if (typeof elms[i] == 'object') {
381					// Wrapper
382					elmId = elms[i][0];
383					if (this.$places[elmId] === undefined || this.$elms[elmId] === undefined) continue;
384					this.$elms[elmId].appendTo($place);
385					this._placeElements(elms[i].shift(), this.$places[elmId]);
386				} else {
387					// Element
388					elmId = elms[i];
389					if (this.$elms[elmId] === undefined) continue;
390					this.$elms[elmId].appendTo($place);
391				}
392			}
393		},
394		_setLayout: function(newLayout){
395			// Retrieving the currently shown layout structure
396			var curLayout = {};
397			$.each(this.$places, function(place, $place){
398			}.bind(this));
399			for (var place in newLayout) {
400				if (!newLayout.hasOwnProperty(place) || this.$places[place] === undefined) continue;
401				this._placeElements(newLayout[place], this.$places[place]);
402			}
403		}
404	});
405	$us.header = new USHeader($us.headerSettings || {});
406}(jQuery);
407
408/**
409 * $us.nav
410 *
411 * Header navigation will all the possible states
412 *
413 * @requires $us.canvas
414 */
415!function($){
416
417	function USNav(){
418
419		// Commonly used dom elements
420		this.$nav = $('.l-header .w-nav:first');
421		if (this.$nav.length == 0) return;
422		this.$control = this.$nav.find('.w-nav-control');
423		this.$items = this.$nav.find('.w-nav-item');
424		this.$list = this.$nav.find('.w-nav-list.level_1');
425		this.$subItems = this.$list.find('.w-nav-item.menu-item-has-children');
426		this.$subAnchors = this.$list.find('.w-nav-item.menu-item-has-children > .w-nav-anchor');
427		this.$subLists = this.$list.find('.w-nav-item.menu-item-has-children > .w-nav-list');
428		this.$anchors = this.$nav.find('.w-nav-anchor');
429
430		// Setting options
431		this.options = this.$nav.find('.w-nav-options:first')[0].onclick() || {};
432
433		// In case the nav doesn't exist, do nothing
434		if (this.$nav.length == 0) return;
435
436		this.type = this.$nav.usMod('type');
437
438		this.mobileOpened = false;
439		this.animationType = this.$nav.usMod('animation');
440		var showFn = 'fadeInCSS',
441			hideFn = 'fadeOutCSS';
442		if (this.animationType == 'height') {
443			showFn = 'slideDownCSS';
444			hideFn = 'slideUpCSS';
445		}
446		else if (this.animationType == 'mdesign') {
447			showFn = 'showMD';
448			hideFn = 'hideMD';
449		}
450
451		// Mobile menu toggler
452		this.$control.on('click', function(){
453			this.mobileOpened = !this.mobileOpened;
454			if (this.mobileOpened) {
455				// Closing opened sublists
456				this.$items.filter('.opened').removeClass('opened');
457				this.$subLists.resetInlineCSS('display', 'opacity', 'height', 'padding-top', 'padding-bottom', 'margin-top');
458				this.$list.slideDownCSS(250, this._events.contentChanged);
459			} else {
460				this.$list.slideUpCSS(250, this._events.contentChanged);
461			}
462		}.bind(this));
463
464		// Boundable events
465		this._events = {
466			// Mobile submenu togglers
467			toggle: function(e){
468				if (this.type != 'mobile') return;
469				e.stopPropagation();
470				e.preventDefault();
471				var $item = $(e.currentTarget).closest('.w-nav-item'),
472					$sublist = $item.children('.w-nav-list');
473				if ($item.hasClass('opened')) {
474					$item.removeClass('opened');
475					$sublist.slideUpCSS(250, this._events.contentChanged);
476				} else {
477					$item.addClass('opened');
478					$sublist.slideDownCSS(250, this._events.contentChanged);
479				}
480			}.bind(this),
481			resize: this.resize.bind(this),
482			contentChanged: function(){
483				if (this.type == 'mobile' && $us.header.orientation == 'hor' && $us.canvas.headerPos == 'fixed') {
484					this.setFixedMobileMaxHeight();
485				}
486				$us.header.$container.trigger('contentChange');
487			}.bind(this)
488		};
489
490		// Toggle on item clicks
491		if (this.options.mobileBehavior) {
492			this.$subAnchors.on('click', this._events.toggle);
493		}
494		// Toggle on arrows
495		else {
496			this.$list.find('.w-nav-item.menu-item-has-children > .w-nav-anchor > .w-nav-arrow').on('click', this._events.toggle);
497		}
498		// Mark all the togglable items
499		this.$subItems.each(function(){
500			var $this = $(this),
501				$parentItem = $this.parent().closest('.w-nav-item');
502			if ($parentItem.length == 0 || $parentItem.usMod('columns') === false) $this.addClass('togglable');
503		});
504		// Touch device handling in default (notouch) layout
505		if (!$us.$html.hasClass('no-touch')) {
506			this.$list.find('.w-nav-item.menu-item-has-children.togglable > .w-nav-anchor').on('click', function(e){
507				if (this.type == 'mobile') return;
508				e.preventDefault();
509				var $this = $(e.currentTarget),
510					$item = $this.parent(),
511					$list = $item.children('.w-nav-list');
512
513				// Second tap: going to the URL
514				if ($item.hasClass('opened')) return location.assign($this.attr('href'));
515				$list[showFn]();
516				$item.addClass('opened');
517				var outsideClickEvent = function(e){
518					if ($.contains($item[0], e.target)) return;
519					$item.removeClass('opened');
520					$list[hideFn]();
521					$us.$body.off('touchstart', outsideClickEvent);
522				};
523
524				$us.$body.on('touchstart', outsideClickEvent);
525			}.bind(this));
526		}
527		// Desktop device hovers
528		else {
529			this.$subItems
530				.filter('.togglable')
531				.on('mouseenter', function(e){
532					if (this.type == 'mobile') return;
533					var $list = $(e.currentTarget).children('.w-nav-list');
534					$list[showFn]();
535				}.bind(this))
536				.on('mouseleave', function(e){
537					if (this.type == 'mobile') return;
538					var $list = $(e.currentTarget).children('.w-nav-list');
539					$list[hideFn]();
540				}.bind(this));
541		}
542		// Close menu on anchor clicks
543		this.$anchors.on('click', function(e){
544			if (this.type != 'mobile' || $us.header.orientation != 'hor') return;
545			// Toggled the item
546			if (this.options.mobileBehavior && $(e.currentTarget).closest('.w-nav-item').hasClass('menu-item-has-children')) return;
547			this.$list.slideUpCSS();
548			this.mobileOpened = false;
549		}.bind(this));
550
551		$us.$window.on('resize', this._events.resize);
552		setTimeout(function(){
553			this.resize();
554			$us.header.$container.trigger('contentChange');
555		}.bind(this), 50);
556	}
557
558	USNav.prototype = {
559
560		/**
561		 * Count proper dimensions
562		 */
563		setFixedMobileMaxHeight: function(){
564			var listTop = Math.min(this.$list.position().top, $us.header.scrolledOccupiedHeight);
565			this.$list.css('max-height', $us.canvas.winHeight - listTop + 'px');
566		},
567
568		/**
569		 * Resize handler
570		 */
571		resize: function(){
572			if (this.$nav.length == 0) return;
573			var nextType = (window.innerWidth <= this.options.mobileWidth) ? 'mobile' : 'desktop';
574			if ($us.header.orientation != this.headerOrientation || nextType != this.type) {
575				// Clearing the previous state
576				this.$subLists.resetInlineCSS('display', 'opacity', 'height', 'padding-top', 'padding-bottom', 'margin-top');
577				if (this.headerOrientation == 'hor' && this.type == 'mobile') {
578					this.$list.resetInlineCSS('height', 'max-height', 'display', 'opacity', 'padding-top', 'padding-bottom');
579				}
580				// Closing opened sublists
581				this.$items.removeClass('opened');
582				// Applying the new state
583				if ($us.header.orientation == 'hor') {
584					if (nextType == 'desktop') {
585						this.$items.filter('.togglable').children('.w-nav-list').css('display', 'none');
586					} else if (nextType == 'mobile') {
587						this.mobileOpened = false;
588						this.$list.css('height', 0);
589						this.$subLists.css('height', 0);
590					}
591				}
592				this.headerOrientation = $us.header.orientation;
593				this.type = nextType;
594				this.$nav.usMod('type', nextType);
595			}
596			// Max-height limitation for fixed header layouts
597			if ($us.header.orientation == 'hor' && this.type == 'mobile' && $us.canvas.headerPos == 'fixed') this.setFixedMobileMaxHeight();
598			this.$list.removeClass('hidden');
599		}
600	};
601
602	$us.nav = new USNav();
603
604}(jQuery);
605
606
607/**
608 * $us.scroll
609 *
610 * ScrollSpy, Smooth scroll links and hash-based scrolling all-in-one
611 *
612 * @requires $us.canvas
613 */
614!function($){
615	"use strict";
616
617	function USScroll(options){
618
619		// Setting options
620		var defaults = {
621			/**
622			 * @param {String|jQuery} Selector or object of hash scroll anchors that should be attached on init
623			 */
624			attachOnInit: '.w-nav a[href*="#"], .w-menu a[href*="#"], a.w-btn[href*="#"], .w-iconbox a[href*="#"], .w-image a[href*="#"], .w-img a[href*="#"], .w-text a[href*="#"], ' +
625			'.vc_icon_element a[href*="#"], .vc_custom_heading a[href*="#"], a.w-portfolio-item-anchor[href*="#"], .widget_nav_menu a[href*="#"], .w-toplink, ' +
626			'.w-blog-post-meta-comments a[href*="#"], .w-comments-title a[href*="#"], .w-comments-item-date, a.smooth-scroll[href*="#"]',
627			/**
628			 * @param {String} Classname that will be toggled on relevant buttons
629			 */
630			buttonActiveClass: 'active',
631			/**
632			 * @param {String} Classname that will be toggled on relevant menu items
633			 */
634			menuItemActiveClass: 'current-menu-item',
635			/**
636			 * @param {String} Classname that will be toggled on relevant menu ancestors
637			 */
638			menuItemAncestorActiveClass: 'current-menu-ancestor',
639			/**
640			 * @param {Number} Duration of scroll animation
641			 */
642			animationDuration: 1200,
643			/**
644			 * @param {String} Easing for scroll animation
645			 */
646			animationEasing: 'easeInOutQuint'
647		};
648		this.options = $.extend({}, defaults, options || {});
649
650		// Hash blocks with targets and activity indicators
651		this.blocks = {};
652
653		// Is scrolling to some specific block at the moment?
654		this.isScrolling = false;
655
656		// Waypoints that will be called at certain scroll position
657		this.waypoints = [];
658
659		// Boundable events
660		this._events = {
661			cancel: this.cancel.bind(this),
662			scroll: this.scroll.bind(this),
663			resize: this.resize.bind(this)
664		};
665
666		this._canvasTopOffset = 0;
667		$us.$window.on('resize load', this._events.resize);
668		setTimeout(this._events.resize, 75);
669
670		$us.$window.on('scroll', this._events.scroll);
671		setTimeout(this._events.scroll, 75);
672
673		if (this.options.attachOnInit) {
674			this.attach(this.options.attachOnInit);
675		}
676
677		// Recount scroll positions on any content changes
678		$us.$canvas.on('contentChange', this._countAllPositions.bind(this));
679
680		// Handling initial document hash
681		if (document.location.hash && document.location.hash.indexOf('#!') == -1) {
682			var hash = document.location.hash,
683				scrollPlace = (this.blocks[hash] !== undefined) ? hash : undefined;
684			if (scrollPlace === undefined) {
685				try {
686					var $target = $(hash);
687					if ($target.length != 0) {
688						scrollPlace = $target;
689					}
690				} catch (error) {
691					//Do not have to do anything here since scrollPlace is already undefined
692				}
693
694			}
695			if (scrollPlace !== undefined) {
696				// While page loads, its content changes, and we'll keep the proper scroll on each sufficient content change
697				// until the page finishes loading or user scrolls the page manually
698				var keepScrollPositionTimer = setInterval(function(){
699					this.scrollTo(scrollPlace);
700				}.bind(this), 100);
701				var clearHashEvents = function(){
702					// Content size still may change via other script right after page load
703					setTimeout(function(){
704						clearInterval(keepScrollPositionTimer);
705						$us.canvas.resize();
706						this._countAllPositions();
707						this.scrollTo(scrollPlace);
708					}.bind(this), 100);
709					$us.$window.off('load touchstart mousewheel DOMMouseScroll touchstart', clearHashEvents);
710				}.bind(this);
711				$us.$window.on('load touchstart mousewheel DOMMouseScroll touchstart', clearHashEvents);
712			}
713		}
714	}
715
716	USScroll.prototype = {
717
718		/**
719		 * Count hash's target position and store it properly
720		 *
721		 * @param {String} hash
722		 * @private
723		 */
724		_countPosition: function(hash){
725			this.blocks[hash].top = Math.ceil(this.blocks[hash].target.offset().top - $us.header.scrolledOccupiedHeight - this._canvasTopOffset);
726			this.blocks[hash].bottom = this.blocks[hash].top + this.blocks[hash].target.outerHeight(false);
727		},
728
729		/**
730		 * Count all targets' positions for proper scrolling
731		 *
732		 * @private
733		 */
734		_countAllPositions: function(){
735			// Take into account #wpadminbar (and others possible) offset
736			this._canvasTopOffset = $us.$canvas.offset().top;
737			for (var hash in this.blocks) {
738				if (!this.blocks.hasOwnProperty(hash)) continue;
739				this._countPosition(hash);
740			}
741			// Counting waypoints
742			for (var i = 0; i < this.waypoints.length; i++) {
743				this._countWaypoint(this.waypoints[i]);
744			}
745		},
746
747		/**
748		 * Indicate scroll position by hash
749		 *
750		 * @param {String} activeHash
751		 * @private
752		 */
753		_indicatePosition: function(activeHash){
754			var activeMenuAncestors = [];
755			for (var hash in this.blocks) {
756				if (!this.blocks.hasOwnProperty(hash)) continue;
757				if (this.blocks[hash].buttons !== undefined) {
758					this.blocks[hash].buttons.toggleClass(this.options.buttonActiveClass, hash === activeHash);
759				}
760				if (this.blocks[hash].menuItems !== undefined) {
761					this.blocks[hash].menuItems.toggleClass(this.options.menuItemActiveClass, hash === activeHash);
762				}
763				if (this.blocks[hash].menuAncestors !== undefined) {
764					this.blocks[hash].menuAncestors.removeClass(this.options.menuItemAncestorActiveClass);
765				}
766			}
767			if (this.blocks[activeHash] !== undefined && this.blocks[activeHash].menuAncestors !== undefined) {
768				this.blocks[activeHash].menuAncestors.addClass(this.options.menuItemAncestorActiveClass);
769			}
770		},
771
772		/**
773		 * Attach anchors so their targets will be listened for possible scrolls
774		 *
775		 * @param {String|jQuery} anchors Selector or list of anchors to attach
776		 */
777		attach: function(anchors){
778			// Location pattern to check absolute URLs for current location
779			var locationPattern = new RegExp('^' + location.pathname.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + '#');
780
781			var $anchors = $(anchors);
782			if ($anchors.length == 0) return;
783			$anchors.each(function(index, anchor){
784				var $anchor = $(anchor),
785					href = $anchor.attr('href'),
786					hash = $anchor.prop('hash');
787				// Ignoring ajax links
788				if (hash.indexOf('#!') != -1) return;
789				// Checking if the hash is connected with the current page
790				if (!(
791						// Link type: #something
792						href.charAt(0) == '#' ||
793							// Link type: /#something
794						(href.charAt(0) == '/' && locationPattern.test(href)) ||
795							// Link type: http://example.com/some/path/#something
796						href.indexOf(location.host + location.pathname + '#') > -1
797					)) return;
798				// Do we have an actual target, for which we'll need to count geometry?
799				if (hash != '' && hash != '#') {
800					// Attach target
801					if (this.blocks[hash] === undefined) {
802						var $target = $(hash);
803						// Don't attach anchors that actually have no target
804						if ($target.length == 0) return;
805						// If it's the only row in a section, than use section instead
806						if ($target.hasClass('g-cols') && $target.parent().children().length == 1) {
807							$target = $target.closest('.l-section');
808						}
809						this.blocks[hash] = {
810							target: $target
811						};
812						this._countPosition(hash);
813					}
814					// Attach activity indicator
815					if ($anchor.hasClass('w-nav-anchor')) {
816						var $menuIndicator = $anchor.closest('.w-nav-item');
817						this.blocks[hash].menuItems = (this.blocks[hash].menuItems || $()).add($menuIndicator);
818						var $menuAncestors = $menuIndicator.parents('.menu-item-has-children');
819						if ($menuAncestors.length > 0) {
820							this.blocks[hash].menuAncestors = (this.blocks[hash].menuAncestors || $()).add($menuAncestors);
821						}
822					}
823					else {
824						this.blocks[hash].buttons = (this.blocks[hash].buttons || $()).add($anchor);
825					}
826				}
827				$anchor.on('click', function(event){
828					event.preventDefault();
829					this.scrollTo(hash, true);
830				}.bind(this));
831			}.bind(this));
832		},
833
834		/**
835		 * Scroll page to a certain position or hash
836		 *
837		 * @param {Number|String|jQuery} place
838		 * @param {Boolean} animate
839		 */
840		scrollTo: function(place, animate){
841			var placeType,
842				newY;
843			// Scroll to top
844			if (place == '' || place == '#') {
845				newY = 0;
846				placeType = 'top';
847			}
848			// Scroll by hash
849			else if (this.blocks[place] !== undefined) {
850				newY = this.blocks[place].top;
851				placeType = 'hash';
852			}
853			else if (place instanceof $) {
854				newY = Math.floor(place.offset().top - $us.header.scrolledOccupiedHeight - this._canvasTopOffset);
855				placeType = 'element';
856			}
857			else {
858				newY = Math.floor(place - $us.header.scrolledOccupiedHeight - this._canvasTopOffset);
859			}
860			var indicateActive = function(){
861				if (placeType == 'hash') {
862					this._indicatePosition(place);
863				}
864				else {
865					this.scroll();
866				}
867			}.bind(this);
868			if (animate) {
869				this.isScrolling = true;
870				$us.$htmlBody.stop(true, false).animate({
871					scrollTop: newY + 'px'
872				}, {
873					duration: this.options.animationDuration,
874					easing: this.options.animationEasing,
875					always: function(){
876						$us.$window.off('keydown mousewheel DOMMouseScroll touchstart', this._events.cancel);
877						this.isScrolling = false;
878						indicateActive();
879					}.bind(this)
880				});
881				// Allow user to stop scrolling manually
882				$us.$window.on('keydown mousewheel DOMMouseScroll touchstart', this._events.cancel);
883			}
884			else {
885				$us.$htmlBody.stop(true, false).scrollTop(newY);
886				indicateActive();
887			}
888		},
889
890		/**
891		 * Cancel scroll
892		 */
893		cancel: function(){
894			$us.$htmlBody.stop(true, false);
895		},
896
897		/**
898		 * Add new waypoint
899		 *
900		 * @param {jQuery} $elm object with the element
901		 * @param {mixed} offset Offset from bottom of screen in pixels ('100') or percents ('20%')
902		 * @param {Function} fn The function that will be called
903		 */
904		addWaypoint: function($elm, offset, fn){
905			$elm = ($elm instanceof $) ? $elm : $($elm);
906			if ($elm.length == 0) return;
907			if (typeof offset != 'string' || offset.indexOf('%') == -1) {
908				// Not percent: using pixels
909				offset = parseInt(offset);
910			}
911			var waypoint = {
912				$elm: $elm,
913				offset: offset,
914				fn: fn
915			};
916			this._countWaypoint(waypoint);
917			this.waypoints.push(waypoint);
918		},
919
920		/**
921		 *
922		 * @param {Object} waypoint
923		 * @private
924		 */
925		_countWaypoint: function(waypoint){
926			var elmTop = waypoint.$elm.offset().top,
927				winHeight = $us.$window.height();
928			if (typeof waypoint.offset == 'number') {
929				// Offset is defined in pixels
930				waypoint.scrollPos = elmTop - winHeight + waypoint.offset;
931			} else {
932				// Offset is defined in percents
933				waypoint.scrollPos = elmTop - winHeight + winHeight * parseInt(waypoint.offset) / 100;
934			}
935		},
936
937		/**
938		 * Scroll handler
939		 */
940		scroll: function(){
941			var scrollTop = parseInt($us.$window.scrollTop());
942			if (!this.isScrolling) {
943				var activeHash;
944				for (var hash in this.blocks) {
945					if (!this.blocks.hasOwnProperty(hash)) continue;
946					if (scrollTop >= this.blocks[hash].top && scrollTop < this.blocks[hash].bottom) {
947						activeHash = hash;
948						break;
949					}
950				}
951				this._indicatePosition(activeHash);
952			}
953			// Handling waypoints
954			for (var i = 0; i < this.waypoints.length; i++) {
955				if (this.waypoints[i].scrollPos < scrollTop)
955 {
956					this.waypoints[i].fn(this.waypoints[i].$elm);
957					this.waypoints.splice(i, 1);
958					i--;
959				}
960			}
961		},
962
963		/**
964		 * Resize handler
965		 */
966		resize: function(){
967			// Delaying the resize event to prevent glitches
968			setTimeout(function(){
969				this._countAllPositions();
970				this.scroll();
971			}.bind(this), 150);
972			this._countAllPositions();
973			this.scroll();
974		}
975	};
976
977	$(function(){
978		$us.scroll = new USScroll($us.scrollOptions || {});
979	});
980
981}(jQuery);
982
983
984jQuery(function($){
985	"use strict";
986
987	// TODO Move all of the below to us.widgets
988	if ($.fn.magnificPopup) {
989
990		$('.product .images').magnificPopup({
991			type: 'image',
992			delegate: 'a.with-lightbox',
993			gallery: {
994				enabled: true,
995				navigateByImgClick: true,
996				preload: [0, 1],
997				tPrev: $us.langOptions.magnificPopup.tPrev, // Alt text on left arrow
998				tNext: $us.langOptions.magnificPopup.tNext, // Alt text on right arrow
999				tCounter: $us.langOptions.magnificPopup.tCounter // Markup for "1 of 7" counter
1000			},
1001			removalDelay: 300,
1002			mainClass: 'mfp-fade',
1003			fixedContentPos: false
1004
1005		});
1006
1007		$('a[ref=magnificPopup][class!=direct-link]').magnificPopup({
1008			type: 'image',
1009			fixedContentPos: false
1010		});
1011	}
1012
1013	if ($.fn.revolution) {
1014		$('.fullwidthbanner').revolution({
1015			delay: 9000,
1016			startwidth: 1140,
1017			startheight: 500,
1018			soloArrowLeftHOffset: 20,
1019			soloArrowLeftVOffset: 0,
1020			soloArrowRightHOffset: 20,
1021			soloArrowRightVOffset: 0,
1022			onHoverStop: "on", // Stop Banner Timet at Hover on Slide on/off
1023			fullWidth: "on",
1024			hideThumbs: false,
1025			shadow: 0 //0 = no Shadow, 1,2,3 = 3 Different Art of Shadows -  (No Shadow in Fullwidth Version !)
1026		});
1027		// Redrawing all the Revolution Sliders
1028		if (window.revapi3 !== undefined && window.revapi3.revredraw !== undefined) {
1029			$us.$window.on('resize', function(){
1030				window.revapi3.revredraw();
1031			});
1032		}
1033	}
1034
1035	$('.animate_fade, .animate_afc, .animate_afl, .animate_afr, .animate_aft, .animate_afb, .animate_wfc, ' +
1036		'.animate_hfc, .animate_rfc, .animate_rfl, .animate_rfr').each(function(){
1037		$us.scroll.addWaypoint($(this), '15%', function($elm){
1038			if (!$elm.hasClass('animate_start')) {
1039				setTimeout(function(){
1040					$elm.addClass('animate_start');
1041				}, 20);
1042			}
1043		});
1044	});
1045	$('.wpb_animate_when_almost_visible').each(function(){
1046		$us.scroll.addWaypoint($(this), '15%', function($elm){
1047			if (!$elm.hasClass('wpb_start_animation')) {
1048				setTimeout(function(){
1049					$elm.addClass('wpb_start_animation');
1050				}, 20);
1051			}
1052		});
1053	});
1054
1055	var $submainVideos = $('.l-section-video');
1056	var updateVideosSizes = function(){
1057		$submainVideos.each(function(){
1058			var $this = $(this),
1059				$video = $this.find('video'),
1060				player = $video.data('mediaelementplayer');
1061			// Hiding videos on small (some mobiles) resolutions
1062			if ($us.canvas.winWidth <= 1024) {
1063				if (player && player.pause && !player.media.paused) {
1064					player.pause();
1065				}
1066				return $this.hide();
1067			}
1068			var mejsContainer = $this.find('.mejs-container'),
1069				poster = $this.find('.mejs-mediaelement img'),
1070				videoWidth = $video.attr('width'),
1071				videoHeight = $video.attr('height'),
1072				videoProportion = videoWidth / videoHeight,
1073				parent = $this.parent(),
1074				parentWidth = parent.outerWidth(),
1075				parentHeight = parent.outerHeight(),
1076				proportion,
1077				centerX, centerY;
1078			if (mejsContainer.length == 0) return;
1079
1080			// Proper sizing
1081//			if (video.length > 0 && video[0].player && video[0].player.media) videoWidth = video[0].player.media.videoWidth;
1082//			if (video.length > 0 && video[0].player && video[0].player.media) videoHeight = video[0].player.media.videoHeight;
1083			if (player && player.play && player.media.paused) {
1084				player.play();
1085			}
1086			$this.show();
1087			parent.find('span.mejs-offscreen').hide();
1088
1089			proportion = (parentWidth / parentHeight > videoWidth / videoHeight) ? parentWidth / videoWidth : parentHeight / videoHeight;
1090			$this.width(proportion * videoWidth);
1091			$this.height(proportion * videoHeight);
1092
1093			poster.width(proportion * videoWidth);
1094			poster.height(proportion * videoHeight);
1095
1096			centerX = (parentWidth < videoWidth * proportion) ? (parentWidth - videoWidth * proportion) / 2 : 0;
1097			centerY = (parentHeight < videoHeight * proportion) ? (parentHeight - videoHeight * proportion) / 2 : 0;
1098
1099			$this.css({left: centerX, top: centerY});
1100
1101			mejsContainer.css({width: '100%', height: '100%'});
1102			$video.css({'object-fit': 'cover', display: 'inline-block'});
1103		});
1104	};
1105	if (window.MediaElementPlayer) {
1106		$('.l-section-video video').mediaelementplayer({
1107			enableKeyboard: false,
1108			iPadUseNativeControls: false,
1109			pauseOtherPlayers: false,
1110			iPhoneUseNativeControls: false,
1111			AndroidUseNativeControls: false,
1112			videoWidth: '100%',
1113			videoHeight: '100%',
1114			success: function(mediaElement, domObject){
1115				$(domObject).css('display', 'block');
1116				updateVideosSizes();
1117			}
1118		});
1119		setTimeout(updateVideosSizes, 75);
1120		$us.$window.on('resize load', updateVideosSizes);
1121	}
1122
1123	jQuery('input[type="text"], input[type="email"], textarea').each(function(index, input){
1124		var $input = $(input),
1125			$row = $input.closest('.w-form-row');
1126		if ($input.attr('type') == 'hidden') return;
1127		$row.toggleClass('not-empty', $input.val() != '');
1128		$input.on('input', function(){
1129			$row.toggleClass('not-empty', $input.val() != '');
1130		});
1131	});
1132
1133	jQuery('.l-section-img, .l-titlebar-img').each(function(){
1134		var $this = $(this),
1135			img = new Image();
1136
1137		img.onload = function(){
1138			if (!$this.hasClass('loaded')) {
1139				$this.addClass('loaded')
1140			}
1141		};
1142
1143		img.src = ($this.css('background-image') || '').replace(/url\(['"]*(.*?)['"]*\)/g, '$1');
1144	});
1145
1146	/* Ultimate Addons for Visual Composer integration */
1147	jQuery('.upb_bg_img, .upb_color, .upb_grad, .upb_content_iframe, .upb_content_video, .upb_no_bg').each(function(){
1148		var $bg = jQuery(this),
1149			$prev = $bg.prev();
1150
1151		if ($prev.length == 0) {
1152			var $parent = $bg.parent(),
1153				$parentParent = $parent.parent(),
1154				$prevParentParent = $parentParent.prev();
1155
1156			if ($prevParentParent.length) {
1157				$bg.insertAfter($prevParentParent);
1158
1159				if ($parent.children().length == 0) {
1160					$parentParent.remove();
1161				}
1162			}
1163		}
1164	});
1165	$('.g-cols > .ult-item-wrap').each(function(index, elm){
1166		var $elm = jQuery(elm);
1167		$elm.replaceWith($elm.children());
1168	});
1169	jQuery('.overlay-show').click(function(){
1170		window.setTimeout(function(){
1171			$us.$canvas.trigger('contentChange');
1172		}, 1000);
1173	});
1174
1175});
1176
1177/**
1178 * CSS-analog of jQuery slideDown/slideUp/fadeIn/fadeOut functions (for better rendering)
1179 */
1180!function(){
1181
1182	/**
1183	 * Remove the passed inline CSS attributes.
1184	 *
1185	 * Usage: $elm.resetInlineCSS('height', 'width');
1186	 */
1187	jQuery.fn.resetInlineCSS = function(){
1188		for (var index = 0; index < arguments.length; index++) {
1189			this.css(arguments[index], '');
1190		}
1191		return this;
1192	};
1193
1194	jQuery.fn.clearPreviousTransitions = function(){
1195		// Stopping previous events, if there were any
1196		var prevTimers = (this.data('animation-timers') || '').split(',');
1197		if (prevTimers.length >= 2) {
1198			this.resetInlineCSS('transition', '-webkit-transition');
1199			prevTimers.map(clearTimeout);
1200			this.removeData('animation-timers');
1201		}
1202		return this;
1203	};
1204	/**
1205	 *
1206	 * @param {Object} css key-value pairs of animated css
1207	 * @param {Number} duration in milliseconds
1208	 * @param {Function} onFinish
1209	 * @param {String} easing CSS easing name
1210	 * @param {Number} delay in milliseconds
1211	 */
1212	jQuery.fn.performCSSTransition = function(css, duration, onFinish, easing, delay){
1213		duration = duration || 250;
1214		delay = delay || 25;
1215		easing = easing || 'ease-in-out';
1216		var $this = this,
1217			transition = [];
1218
1219		this.clearPreviousTransitions();
1220
1221		for (var attr in css) {
1222			if (!css.hasOwnProperty(attr)) continue;
1223			transition.push(attr + ' ' + (duration / 1000) + 's ' + easing);
1224		}
1225		transition = transition.join(', ');
1226		$this.css({
1227			transition: transition,
1228			'-webkit-transition': transition
1229		});
1230
1231		// Starting the transition with a slight delay for the proper application of CSS transition properties
1232		var timer1 = setTimeout(function(){
1233			$this.css(css);
1234		}, delay);
1235
1236		var timer2 = setTimeout(function(){
1237			$this.resetInlineCSS('transition', '-webkit-transition');
1238			if (typeof onFinish == 'function') onFinish();
1239		}, duration + delay);
1240
1241		this.data('animation-timers', timer1 + ',' + timer2);
1242	};
1243	// Height animations
1244	jQuery.fn.slideDownCSS = function(duration, onFinish, easing, delay){
1245		if (this.length == 0) return;
1246		var $this = this;
1247		this.clearPreviousTransitions();
1248		// Grabbing paddings
1249		this.resetInlineCSS('padding-top', 'padding-bottom');
1250		var timer1 = setTimeout(function(){
1251			var paddingTop = parseInt($this.css('padding-top')),
1252				paddingBottom = parseInt($this.css('padding-bottom'));
1253			// Grabbing the "auto" height in px
1254			$this.css({
1255				visibility: 'hidden',
1256				position: 'absolute',
1257				height: 'auto',
1258				'padding-top': 0,
1259				'padding-bottom': 0,
1260				display: 'block'
1261			});
1262			var height = $this.height();
1263			$this.css({
1264				overflow: 'hidden',
1265				height: '0px',
1266				visibility: '',
1267				position: '',
1268				opacity: 0
1269			});
1270			$this.performCSSTransition({
1271				height: height + paddingTop + paddingBottom,
1272				opacity: 1,
1273				'padding-top': paddingTop,
1274				'padding-bottom': paddingBottom
1275			}, duration, function(){
1276				$this.resetInlineCSS('overflow').css('height', 'auto');
1277				if (typeof onFinish == 'function') onFinish();
1278			}, easing, delay);
1279		}, 25);
1280		this.data('animation-timers', timer1 + ',null');
1281	};
1282	jQuery.fn.slideUpCSS = function(duration, onFinish, easing, delay){
1283		if (this.length == 0) return;
1284		this.clearPreviousTransitions();
1285		this.css({
1286			height: this.outerHeight(),
1287			overflow: 'hidden',
1288			'padding-top': this.css('padding-top'),
1289			'padding-bottom': this.css('padding-bottom'),
1290			opacity: 1
1291		});
1292		var $this = this;
1293		this.performCSSTransition({
1294			height: 0,
1295			'padding-top': 0,
1296			'padding-bottom': 0,
1297			opacity: 0
1298		}, duration, function(){
1299			$this.resetInlineCSS('overflow', 'padding-top', 'padding-bottom', 'opacity').css({
1300				display: 'none'
1301			});
1302			if (typeof onFinish == 'function') onFinish();
1303		}, easing, delay);
1304	};
1305	// Opacity animations
1306	jQuery.fn.fadeInCSS = function(duration, onFinish, easing, delay){
1307		if (this.length == 0) return;
1308		this.clearPreviousTransitions();
1309		this.css({
1310			opacity: 0,
1311			display: 'block'
1312		});
1313		this.performCSSTransition({
1314			opacity: 1
1315		}, duration, onFinish, easing, delay);
1316	};
1317	jQuery.fn.fadeOutCSS = function(duration, onFinish, easing, delay){
1318		if (this.length == 0) return;
1319		var $this = this;
1320		this.performCSSTransition({
1321			opacity: 0
1322		}, duration, function(){
1323			$this.css('display', 'none');
1324			if (typeof onFinish == 'function') onFinish();
1325		}, easing, delay);
1326	};
1327	// Material design animations
1328	jQuery.fn.showMD = function(duration, onFinish, easing, delay){
1329		if (this.length == 0) return;
1330		this.clearPreviousTransitions();
1331		// Grabbing paddings
1332		this.resetInlineCSS('padding-top', 'padding-bottom');
1333		var paddingTop = parseInt(this.css('padding-top')),
1334			paddingBottom = parseInt(this.css('padding-bottom'));
1335		// Grabbing the "auto" height in px
1336		this.css({
1337			visibility: 'hidden',
1338			position: 'absolute',
1339			height: 'auto',
1340			'padding-top': 0,
1341			'padding-bottom': 0,
1342			'margin-top': -20,
1343			opacity: '',
1344			display: 'block'
1345		});
1346		var height = this.height();
1347		this.css({
1348			overflow: 'hidden',
1349			height: '0px'
1350		}).resetInlineCSS('visibility', 'position');
1351		var $this = this;
1352		this.performCSSTransition({
1353			height: height + paddingTop + paddingBottom,
1354			'margin-top': 0,
1355			'padding-top': paddingTop,
1356			'padding-bottom': paddingBottom
1357		}, duration || 350, function(){
1358			$this.resetInlineCSS('overflow', 'margin-top', 'padding-top', 'padding-bottom').css('height', 'auto');
1359			if (typeof onFinish == 'function') onFinish();
1360		}, easing || 'cubic-bezier(.23,1,.32,1)', delay || 150);
1361	};
1362	jQuery.fn.hideMD = function(duration, onFinish, easing, delay){
1363		if (this.length == 0) return;
1364		this.clearPreviousTransitions();
1365		var $this = this;
1366		this.resetInlineCSS('margin-top');
1367		this.performCSSTransition({
1368			opacity: 0
1369		}, duration || 100, function(){
1370			$this.css({
1371				display: 'none'
1372			}).resetInlineCSS('opacity');
1373			if (typeof onFinish == 'function') onFinish();
1374		}, easing, delay);
1375	};
1376	// Slide element left / right
1377	var slideIn = function($this, from){
1378			if ($this.length == 0) return;
1379			$this.clearPreviousTransitions();
1380			$this.css({width: 'auto', height: 'auto'});
1381			var width = $this.width(),
1382				height = $this.height();
1383			$this.css({
1384				width: width,
1385				height: height,
1386				position: 'relative',
1387				left: (from == 'right') ? '100%' : '-100%',
1388				opacity: 0,
1389				display: 'block'
1390			});
1391			$this.performCSSTransition({
1392				left: '0%',
1393				opacity: 1
1394			}, arguments[0] || 250, function(){
1395				$this.resetInlineCSS('position', 'left', 'opacity', 'display').css({width: 'auto', height: 'auto'});
1396			});
1397		},
1398		slideOut = function($this, to){
1399			if ($this.length == 0) return;
1400			$this.clearPreviousTransitions();
1401			$this.css({
1402				position: 'relative',
1403				left: 0,
1404				opacity: 1
1405			});
1406			$this.performCSSTransition({
1407				left: (to == 'left') ? '-100%' : '100%',
1408				opacity: 0
1409			}, arguments[0] || 250, function(){
1410				$this.css({
1411					display: 'none'
1412				}).resetInlineCSS('position', 'left', 'opacity');
1413			});
1414		};
1415	jQuery.fn.slideOutLeft = function(){
1416		slideOut(this, 'left');
1417	};
1418	jQuery.fn.slideOutRight = function(){
1419		slideOut(this, 'right');
1420	};
1421	jQuery.fn.slideInLeft = function(){
1422		slideIn(this, 'left');
1423	};
1424	jQuery.fn.slideInRight = function(){
1425		slideIn(this, 'right');
1426	};
1427}();

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.