PageSourceSearch

https://cruisespeakeracademy.com/wp-content/themes/Impreza/framework/js/us.core.js?ver=2.10

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

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.