PageSourceSearch

https://stoleshnica-fasad.ru/wp-content/themes/hauztheme/framework/js/us.core.js?ver=2.8.1

js stoleshnica-fasad.ru collected 2026-10-09 01:45:38 UTC 44,605 bytes, 1,385 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				this.switchTo(nextType, null);
549			}
550
551			// Max-height limitation for fixed header layouts
552			if (this.layout == 'hor' && this.type == 'mobile' && $us.canvas.headerPos == 'fixed'){
553				this.setFixedMobileMaxHeight();
554			}
555
556			this.$list.removeClass('hidden');
557		}
558	};
559
560	$(function(){
561		$us.nav = new USNav($us.navOptions || {});
562	});
563
564}(jQuery);
565
566
567/**
568 * $us.scroll
569 *
570 * ScrollSpy, Smooth scroll links and hash-based scrolling all-in-one
571 *
572 * @requires $us.canvas
573 */
574!function($){
575	"use strict";
576
577	function USScroll(options){
578
579		// Setting options
580		var defaults = {
581			/**
582			 * @param {String|jQuery} Selector or object of hash scroll anchors that should be attached on init
583			 */
584			attachOnInit: '.w-nav a[href*="#"], a.w-btn[href*="#"], .w-iconbox a[href*="#"], .w-image a[href*="#"], ' +
585			'.vc_icon_element a[href*="#"], .vc_custom_heading a[href*="#"], a.w-portfolio-item-anchor[href*="#"], .widget_nav_menu a[href*="#"], .w-toplink, ' +
586			'.w-blog-post-meta-comments a[href*="#"], .w-comments-title a[href*="#"], .w-comments-item-date, a.smooth-scroll[href*="#"]',
587			/**
588			 * @param {String} Classname that will be toggled on relevant buttons
589			 */
590			buttonActiveClass: 'active',
591			/**
592			 * @param {String} Classname that will be toggled on relevant menu items
593			 */
594			menuItemActiveClass: 'current-menu-item',
595			/**
596			 * @param {String} Classname that will be toggled on relevant menu ancestors
597			 */
598			menuItemAncestorActiveClass: 'current-menu-ancestor',
599			/**
600			 * @param {Number} Duration of scroll animation
601			 */
602			animationDuration: 1200,
603			/**
604			 * @param {String} Easing for scroll animation
605			 */
606			animationEasing: 'easeInOutQuint'
607		};
608		this.options = $.extend({}, defaults, options || {});
609
610		// Commonly used dom elements
611		this.$window = $(window);
612		this.$htmlBody = $('html, body');
613
614		// Hash blocks with targets and activity indicators
615		this.blocks = {};
616
617		// Is scrolling to some specific block at the moment?
618		this.isScrolling = false;
619
620		// Waypoints that will be called at certain scroll position
621		this.waypoints = [];
622
623		// Boundable events
624		this._events = {
625			cancel: this.cancel.usBind(this),
626			scroll: this.scroll.usBind(this),
627			resize: this.resize.usBind(this)
628		};
629
630		this._canvasTopOffset = 0;
631		this.$window.on('resize load', this._events.resize);
632		setTimeout(this._events.resize, 75);
633
634		this.$window.on('scroll', this._events.scroll);
635		setTimeout(this._events.scroll, 75);
636
637		if (this.options.attachOnInit){
638			this.attach(this.options.attachOnInit);
639		}
640
641		// Recount scroll positions on any content changes
642		$us.canvas.$container.on('contentChange', this._countAllPositions.usBind(this));
643
644		// Handling initial document hash
645		if (document.location.hash && document.location.hash.indexOf('#!') == -1){
646			var hash = document.location.hash,
647				scrollPlace = (this.blocks[hash] !== undefined) ? hash : undefined;
648			if (scrollPlace === undefined) {
649				try {
650					var $target = $(hash);
651					if ($target.length != 0){
652						scrollPlace = $target;
653					}
654				} catch(error) {
655					//Do not have to do anything here since scrollPlace is already undefined
656				}
657
658			}
659			if (scrollPlace !== undefined){
660				// While page loads, its content changes, and we'll keep the proper scroll on each sufficient content change
661				// until the page finishes loading or user scrolls the page manually
662				var keepScrollPositionTimer = setInterval(function(){
663					this.scrollTo(scrollPlace);
664				}.usBind(this), 100);
665				var clearHashEvents = function(){
666					// Content size still may change via other script right after page load
667					setTimeout(function(){
668						clearInterval(keepScrollPositionTimer);
669						$us.canvas.resize();
670						this._countAllPositions();
671						this.scrollTo(scrollPlace);
672					}.usBind(this), 100);
673					this.$window.off('load touchstart mousewheel DOMMouseScroll touchstart', clearHashEvents);
674				}.usBind(this);
675				this.$window.on('load touchstart mousewheel DOMMouseScroll touchstart', clearHashEvents);
676			}
677		}
678	}
679
680	USScroll.prototype = {
681
682		/**
683		 * Count hash's target position and store it properly
684		 *
685		 * @param {String} hash
686		 * @private
687		 */
688		_countPosition: function(hash){
689			this.blocks[hash].top = Math.ceil(this.blocks[hash].target.offset().top - $us.canvas.scrolledHeaderOccupiedHeight - this._canvasTopOffset);
690			this.blocks[hash].bottom = this.blocks[hash].top + this.blocks[hash].target.outerHeight(false);
691		},
692
693		/**
694		 * Count all targets' positions for proper scrolling
695		 *
696		 * @private
697		 */
698		_countAllPositions: function(){
699			// Take into account #wpadminbar (and others possible) offset
700			this._canvasTopOffset = $us.canvas.$container.offset().top;
701			for (var hash in this.blocks){
702				if ( ! this.blocks.hasOwnProperty(hash)) continue;
703				this._countPosition(hash);
704			}
705			// Counting waypoints
706			for (var i = 0; i < this.waypoints.length; i++){
707				this._countWaypoint(this.waypoints[i]);
708			}
709		},
710
711		/**
712		 * Indicate scroll position by hash
713		 *
714		 * @param {String} activeHash
715		 * @private
716		 */
717		_indicatePosition: function(activeHash){
718			var activeMenuAncestors = [];
719			for (var hash in this.blocks){
720				if ( ! this.blocks.hasOwnProperty(hash)) continue;
721				if (this.blocks[hash].buttons !== undefined){
722					this.blocks[hash].buttons.toggleClass(this.options.buttonActiveClass, hash === activeHash);
723				}
724				if (this.blocks[hash].menuItems !== undefined){
725					this.blocks[hash].menuItems.toggleClass(this.options.menuItemActiveClass, hash === activeHash);
726				}
727				if (this.blocks[hash].menuAncestors !== undefined){
728					this.blocks[hash].menuAncestors.removeClass(this.options.menuItemAncestorActiveClass);
729				}
730			}
731			if (this.blocks[activeHash] !== undefined && this.blocks[activeHash].menuAncestors !== undefined){
732				this.blocks[activeHash].menuAncestors.addClass(this.options.menuItemAncestorActiveClass);
733			}
734		},
735
736		/**
737		 * Attach anchors so their targets will be listened for possible scrolls
738		 *
739		 * @param {String|jQuery} anchors Selector or list of anchors to attach
740		 */
741		attach: function(anchors){
742			// Location pattern to check absolute URLs for current location
743			var locationPattern = new RegExp('^'+location.pathname.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")+'#');
744
745			var $anchors = $(anchors);
746			if ($anchors.length == 0) return;
747			$anchors.each(function(index, anchor){
748				var $anchor = $(anchor),
749					href = $anchor.attr('href'),
750					hash = $anchor.prop('hash');
751				// Ignoring ajax links
752				if (hash.indexOf('#!') != -1) return;
753				// Checking if the hash is connected with the current page
754				if ( ! (
755						// Link type: #something
756					href.charAt(0) == '#' ||
757						// Link type: /#something
758					(href.charAt(0) == '/' && locationPattern.test(href)) ||
759						// Link type: http://example.com/some/path/#something
760					href.indexOf(location.host+location.pathname+'#') > -1
761					)) return;
762				// Do we have an actual target, for which we'll need to count geometry?
763				if (hash != '' && hash != '#'){
764					// Attach target
765					if (this.blocks[hash] === undefined){
766						var $target = $(hash);
767						// Don't attach anchors that actually have no target
768						if ($target.length == 0) return;
769						// If it's the only row in a submain, than use submain instead
770						if ($target.hasClass('g-cols') && $target.parent().children().length == 1){
771							$target = $target.closest('.l-section');
772						}
773						this.blocks[hash] = {
774							target: $target
775						};
776						this._countPosition(hash);
777					}
778					// Attach activity indicator
779					if ($anchor.hasClass('w-nav-anchor')){
780						var $menuIndicator = $anchor.closest('.w-nav-item');
781						this.blocks[hash].menuItems = (this.blocks[hash].menuItems || $()).add($menuIndicator);
782						var $menuAncestors = $menuIndicator.parents('.menu-item-has-children');
783						if ($menuAncestors.length > 0){
784							this.blocks[hash].menuAncestors = (this.blocks[hash].menuAncestors || $()).add($menuAncestors);
785						}
786					}
787					else {
788						this.blocks[hash].buttons = (this.blocks[hash].buttons || $()).add($anchor);
789					}
790				}
791				$anchor.on('click', function(event){
792					event.preventDefault();
793					this.scrollTo(hash, true);
794				}.usBind(this));
795			}.usBind(this));
796		},
797
798		/**
799		 * Scroll page to a certain position or hash
800		 *
801		 * @param {Number|String|jQuery} place
802		 * @param {Boolean} animate
803		 */
804		scrollTo: function(place, animate){
805			var placeType,
806				newY;
807			// Scroll to top
808			if (place == '' || place == '#'){
809				newY = 0;
810				placeType = 'top';
811			}
812			// Scroll by hash
813			else if (this.blocks[place] !== undefined){
814				newY = this.blocks[place].top;
815				placeType = 'hash';
816			}
817			else if (place instanceof $){
818				newY = Math.floor(place.offset().top - $us.canvas.scrolledHeaderOccupiedHeight - this._canvasTopOffset);
819				placeType = 'element';
820			}
821			else {
822				newY = Math.floor(place - $us.canvas.scrolledHeaderOccupiedHeight - this._canvasTopOffset);
823			}
824			var indicateActive = function(){
825				if (placeType == 'hash'){
826					this._indicatePosition(place);
827				}
828				else {
829					this.scroll();
830				}
831			}.usBind(this);
832			if (animate){
833				this.isScrolling = true;
834				this.$htmlBody.stop(true, false).animate({
835					scrollTop: newY+'px'
836				}, {
837					duration: this.options.animationDuration,
838					easing: this.options.animationEasing,
839					always: function(){
840						this.$window.off('keydown mousewheel DOMMouseScroll touchstart', this._events.cancel);
841						this.isScrolling = false;
842						indicateActive();
843					}.usBind(this)
844				});
845				// Allow user to stop scrolling manually
846				this.$window.on('keydown mousewheel DOMMouseScroll touchstart', this._events.cancel);
847			}
848			else {
849				this.$htmlBody.stop(true, false).scrollTop(newY);
850				indicateActive();
851			}
852		},
853
854		/**
855		 * Cancel scroll
856		 */
857		cancel: function(){
858			this.$htmlBody.stop(true, false);
859		},
860
861		/**
862		 * Add new waypoint
863		 *
864		 * @param {jQuery} $elm object with the element
865		 * @param {mixed} offset Offset from bottom of screen in pixels ('100') or percents ('20%')
866		 * @param {Function} fn The function that will be called
867		 */
868		addWaypoint: function($elm, offset, fn){
869			$elm = ($elm instanceof $) ? $elm : $($elm);
870			if ($elm.length == 0) return;
871			if (typeof offset != 'string' || offset.indexOf('%') == -1){
872				// Not percent: using pixels
873				offset = parseInt(offset);
874			}
875			var waypoint = {
876				$elm: $elm,
877				offset: offset,
878				fn: fn
879			};
880			this._countWaypoint(waypoint);
881			this.waypoints.push(waypoint);
882		},
883
884		/**
885		 *
886		 * @param {Object} waypoint
887		 * @private
888		 */
889		_countWaypoint: function(waypoint){
890			var elmTop = waypoint.$elm.offset().top,
891				winHeight = this.$window.height();
892			if (typeof waypoint.offset == 'number'){
893				// Offset is defined in pixels
894				waypoint.scrollPos = elmTop - winHeight + waypoint.offset;
895			}else{
896				// Offset is defined in percents
897				waypoint.scrollPos = elmTop - winHeight + winHeight * parseInt(waypoint.offset) / 100;
898			}
899		},
900
901		/**
902		 * Scroll handler
903		 */
904		scroll: function(){
905			var scrollTop = parseInt(this.$window.scrollTop());
906			if ( ! this.isScrolling){
907				var activeHash;
908				for (var hash in this.blocks) {
909					if ( ! this.blocks.hasOwnProperty(hash)) continue;
910					if (scrollTop >= this.blocks[hash].top && scrollTop < this.blocks[hash].bottom){
911						activeHash = hash;
912						break;
913					}
914				}
915				this._indicatePosition(activeHash);
916			}
917			// Handling waypoints
918			for (var i = 0; i < this.waypoints.length; i++){
919				if (this.waypoints[i].scrollPos < scrollTop){
920					this.waypoints[i].fn(this.waypoints[i].$elm);
921					this.waypoints.splice(i, 1);
922					i--;
923				}
924			}
925		},
926
927		/**
928		 * Resize handler
929		 */
930		resize: function(){
931			// Delaying the resize event to prevent glitches
932			setTimeout(function(){
933				this._countAllPositions();
934				this.scroll();
935			}.usBind(this), 150);
936			this._countAllPositions();
937			this.scroll();
938		}
939	};
940
941	$(function(){
942		$us.scroll = new USScroll($us.scrollOptions || {});
943	});
944
945}(jQuery);
946
947
948jQuery(function($){
949	"use strict";
950
951	// TODO Move all of the below to us.widgets
952	if ($.fn.magnificPopup){
953
954		$('.product .images').magnificPopup({
955			type: 'image',
956			delegate: 'a',
957			gallery: {
958				enabled: true,
959				navigateByImgClick: true,
960				preload: [0, 1],
961				tPrev: $us.langOptions.magnificPopup.tPrev, // Alt text on left arrow
962				tNext: $us.langOptions.magnificPopup.tNext, // Alt text on right arrow
963				tCounter: $us.langOptions.magnificPopup.tCounter // Markup for "1 of 7" counter
964			},
965			removalDelay: 300,
966			mainClass: 'mfp-fade',
967			fixedContentPos: false
968
969		});
970
971		$('a[ref=magnificPopup][class!=direct-link]').magnificPopup({
972			type: 'image',
973			fixedContentPos: false
974		});
975	}
976
977	if ($.fn.revolution){
978		$('.fullwidthbanner').revolution({
979			delay: 9000,
980			startwidth: 1140,
981			startheight: 500,
982			soloArrowLeftHOffset: 20,
983			soloArrowLeftVOffset: 0,
984			soloArrowRightHOffset: 20,
985			soloArrowRightVOffset: 0,
986			onHoverStop: "on", // Stop Banner Timet at Hover on Slide on/off
987			fullWidth: "on",
988			hideThumbs: false,
989			shadow: 0 //0 = no Shadow, 1,2,3 = 3 Different Art of Shadows -  (No Shadow in Fullwidth Version !)
990		});
991		// Redrawing all the Revolution Sliders
992		if (window.revapi3 !== undefined && window.revapi3.revredraw !== undefined){
993			$us.canvas.$window.on('resize', function(){
994				window.revapi3.revredraw();
995			});
996		}
997	}
998
999	$('.animate_fade, .animate_afc, .animate_afl, .animate_afr, .animate_aft, .animate_afb, .animate_wfc, ' +
1000		'.animate_hfc, .animate_rfc, .animate_rfl, .animate_rfr').each(function(){
1001		$us.scroll.addWaypoint($(this), '15%', function($elm){
1002			if ( ! $elm.hasClass('animate_start')){
1003				setTimeout(function() {
1004					$elm.addClass('animate_start');
1005				}, 20);
1006			}
1007		});
1008	});
1009	$('.wpb_animate_when_almost_visible').each(function(){
1010		$us.scroll.addWaypoint($(this), '15%', function($elm){
1011			if ( ! $elm.hasClass('wpb_start_animation')){
1012				setTimeout(function() {
1013					$elm.addClass('wpb_start_animation');
1014				}, 20);
1015			}
1016		});
1017	});
1018
1019	var $submainVideos = $('.l-section-video');
1020	var updateVideosSizes = function(){
1021		$submainVideos.each(function(){
1022			var $this = $(this),
1023				$video = $this.find('video'),
1024				player = $video.data('mediaelementplayer');
1025			// Hiding videos on small (some mobiles) resolutions
1026			if ($us.canvas.winWidth <= 1024){
1027				if (player && player.pause && ! player.media.paused){
1028					player.pause();
1029				}
1030				return $this.hide();
1031			}
1032			var mejsContainer = $this.find('.mejs-container'),
1033				poster = $this.find('.mejs-mediaelement img'),
1034				videoWidth = $video.attr('width'),
1035				videoHeight = $video.attr('height'),
1036				videoProportion = videoWidth / videoHeight,
1037				parent = $this.parent(),
1038				parentWidth = parent.outerWidth(),
1039				parentHeight = parent.outerHeight(),
1040				proportion,
1041				centerX, centerY;
1042			if (mejsContainer.length == 0) return;
1043
1044			// Proper sizing
1045//			if (video.length > 0 && video[0].player && video[0].player.media) videoWidth = video[0].player.media.videoWidth;
1046//			if (video.length > 0 && video[0].player && video[0].player.media) videoHeight = video[0].player.media.videoHeight;
1047			if (player && player.play && player.media.paused){
1048				player.play();
1049			}
1050			$this.show();
1051			parent.find('span.mejs-offscreen').hide();
1052
1053			proportion = (parentWidth/parentHeight > videoWidth/videoHeight)?parentWidth/videoWidth:parentHeight/videoHeight;
1054			$this.width(proportion*videoWidth);
1055			$this.height(proportion*videoHeight);
1056
1057			poster.width(proportion*videoWidth);
1058			poster.height(proportion*videoHeight);
1059
1060			centerX = (parentWidth < videoWidth*proportion)?(parentWidth - videoWidth*proportion)/2:0;
1061			centerY = (parentHeight < videoHeight*proportion)?(parentHeight - videoHeight*proportion)/2:0;
1062
1063			$this.css({left: centerX, top: centerY});
1064
1065			mejsContainer.css({width: '100%', height: '100%'});
1066			$video.css({'object-fit': 'cover', display: 'inline-block'});
1067		});
1068	};
1069	if (window.MediaElementPlayer){
1070		$('.l-section-video video').mediaelementplayer({
1071			enableKeyboard: false,
1072			iPadUseNativeControls: false,
1073			pauseOtherPlayers: false,
1074			iPhoneUseNativeControls: false,
1075			AndroidUseNativeControls: false,
1076			videoWidth: '100%',
1077			videoHeight: '100%',
1078			success: function(mediaElement, domObject){
1079				$(domObject).css('display', 'block');
1080				updateVideosSizes();
1081			}
1082		});
1083		setTimeout(updateVideosSizes, 75);
1084		$us.canvas.$window.on('resize load', updateVideosSizes);
1085	}
1086
1087	jQuery('input[type="text"], input[type="email"], textarea').each(function(index, input){
1088		var $input = $(input),
1089			$row = $input.closest('.w-form-row');
1090		if ($input.attr('type') == 'hidden') return;
1091		$row.toggleClass('not-empty', $input.val() != '');
1092		$input.on('input', function(){
1093			$row.toggleClass('not-empty', $input.val() != '');
1094		});
1095	});
1096
1097	jQuery('.l-section-img, .l-titlebar-img').each(function(){
1098		var $this = $(this),
1099			img = new Image();
1100
1101		img.onload = function () {
1102			if ( ! $this.hasClass('loaded')) {
1103				$this.addClass('loaded')
1104			}
1105		};
1106
1107		img.src = ($this.css('background-image') || '').replace(/url\(['"]*(.*?)['"]*\)/g, '$1');
1108	});
1109
1110	/* Ultimate Addons for Visual Composer integration */
1111	jQuery('.upb_bg_img, .upb_color, .upb_grad, .upb_content_iframe, .upb_content_video, .upb_no_bg').each(function() {
1112		var $bg = jQuery(this),
1113			$prev = $bg.prev();
1114
1115		if ($prev.length == 0) {
1116			var $parent = $bg.parent(),
1117				$parentParent = $parent.parent(),
1118				$prevParentParent = $parentParent.prev();
1119
1120			if ($prevParentParent.length) {
1121				$bg.insertAfter($prevParentParent);
1122
1123				if ( $parent.children().length == 0 ) {
1124					$parentParent.remove();
1125				}
1126			}
1127		}
1128	});
1129	$('.g-cols > .ult-item-wrap').each(function(index, elm){
1130		var $elm = jQuery(elm);
1131		$elm.replaceWith($elm.children());
1132	});
1133	jQuery('.overlay-show').click(function(){
1134		window.setTimeout(function(){
1135			$us.canvas.$container.trigger('contentChange');
1136		}, 1000);
1137	});
1138
1139});
1140
1141/**
1142 * CSS-analog of jQuery slideDown/slideUp/fadeIn/fadeOut functions (for better rendering)
1143 */
1144!function(){
1145
1146	/**
1147	 * Remove the passed inline CSS attributes.
1148	 *
1149	 * Usage: $elm.resetInlineCSS('height', 'width');
1150	 */
1151	jQuery.fn.resetInlineCSS = function(){
1152		for (var index = 0; index < arguments.length; index++){
1153			var name = arguments[index],
1154				value = '';
1155			this.css(name, value);
1156		}
1157		return this;
1158	};
1159
1160	jQuery.fn.clearPreviousTransitions = function(){
1161		// Stopping previous events, if there were any
1162		var prevTimers = (this.data('animation-timers') || '').split(',');
1163		if (prevTimers.length >= 2){
1164			this.resetInlineCSS('transition', '-webkit-transition');
1165			prevTimers.map(clearTimeout);
1166			this.removeData('animation-timers');
1167		}
1168		return this;
1169	};
1170	/**
1171	 *
1172	 * @param {Object} css key-value pairs of animated css
1173	 * @param {Number} duration in milliseconds
1174	 * @param {Function} onFinish
1175	 * @param {String} easing CSS easing name
1176	 * @param {Number} delay in milliseconds
1177	 */
1178	jQuery.fn.performCSSTransition = function(css, duration, onFinish, easing, delay){
1179		duration = duration || 250;
1180		delay = delay || 25;
1181		easing = easing || 'ease-in-out';
1182		var $this = this,
1183			transition = [];
1184
1185		this.clearPreviousTransitions();
1186
1187		for (var attr in css){
1188			if ( ! css.hasOwnProperty(attr)) continue;
1189			transition.push(attr+' '+(duration/1000)+'s '+easing);
1190		}
1191		transition = transition.join(', ');
1192		$this.css({
1193			transition: transition,
1194			'-webkit-transition': transition
1195		});
1196
1197		// Starting the transition with a slight delay for the proper application of CSS transition properties
1198		var timer1 = setTimeout(function(){
1199			$this.css(css);
1200		}, delay);
1201
1202		var timer2 = setTimeout(function(){
1203			if (typeof onFinish == 'function') onFinish();
1204			$this.resetInlineCSS('transition', '-webkit-transition');
1205		}, duration + delay);
1206
1207		this.data('animation-timers', timer1+','+timer2);
1208	};
1209	// Height animations
1210	jQuery.fn.slideDownCSS = function(duration, onFinish, easing, delay){
1211		if (this.length == 0) return;
1212		var $this = this;
1213		this.clearPreviousTransitions();
1214		// Grabbing paddings
1215		this.resetInlineCSS('padding-top', 'padding-bottom');
1216		var timer1 = setTimeout(function(){
1217			var paddingTop = parseInt($this.css('padding-top')),
1218				paddingBottom = parseInt($this.css('padding-bottom'));
1219			// Grabbing the "auto" height in px
1220			$this.css({
1221				visibility: 'hidden',
1222				position: 'absolute',
1223				height: 'auto',
1224				'padding-top': 0,
1225				'padding-bottom': 0,
1226				display: 'block'
1227			});
1228			var height = $this.height();
1229			$this.css({
1230				overflow: 'hidden',
1231				height: '0px',
1232				visibility: '',
1233				position: '',
1234				opacity: 0
1235			});
1236			$this.performCSSTransition({
1237				height: height + paddingTop + paddingBottom,
1238				opacity: 1,
1239				'padding-top': paddingTop,
1240				'padding-bottom': paddingBottom
1241			}, duration, function(){
1242				$this.resetInlineCSS('overflow').css('height', 'auto');
1243				if (typeof onFinish == 'function') onFinish();
1244			}, easing, delay);
1245		}, 25);
1246		this.data('animation-timers', timer1+',null');
1247	};
1248	jQuery.fn.slideUpCSS = function(duration, onFinish, easing, delay){
1249		if (this.length == 0) return;
1250		this.clearPreviousTransitions();
1251		this.css({
1252			height: this.outerHeight(),
1253			overflow: 'hidden',
1254			'padding-top': this.css('padding-top'),
1255			'padding-bottom': this.css('padding-bottom'),
1256			opacity: 1
1257		});
1258		var $this = this;
1259		this.performCSSTransition({
1260			height: 0,
1261			'padding-top': 0,
1262			'padding-bottom': 0,
1263			opacity: 0
1264		}, duration, function(){
1265			$this.resetInlineCSS('overflow', 'padding-top', 'padding-bottom').css({
1266				display: 'none'
1267			});
1268			if (typeof onFinish == 'function') onFinish();
1269		}, easing, delay);
1270	};
1271	// Opacity animations
1272	jQuery.fn.fadeInCSS = function(duration, onFinish, easing, delay){
1273		if (this.length == 0) return;
1274		this.clearPreviousTransitions();
1275		this.css({
1276			opacity: 0,
1277			display: 'block'
1278		});
1279		this.performCSSTransition({
1280			opacity: 1
1281		}, duration, onFinish, easing, delay);
1282	};
1283	jQuery.fn.fadeOutCSS = function(duration, onFinish, easing, delay){
1284		if (this.length == 0) return;
1285		var $this = this;
1286		this.performCSSTransition({
1287			opacity: 0
1288		}, duration, function(){
1289			$this.css('display', 'none');
1290			if (typeof onFinish == 'function') onFinish();
1291		}, easing, delay);
1292	};
1293	// Material design animations
1294	jQuery.fn.showMD = function(duration, onFinish, easing, delay){
1295		if (this.length == 0) return;
1296		this.clearPreviousTransitions();
1297		// Grabbing paddings
1298		this.resetInlineCSS('padding-top', 'padding-bottom');
1299		var paddingTop = parseInt(this.css('padding-top')),
1300			paddingBottom = parseInt(this.css('padding-bottom'));
1301		// Grabbing the "auto" height in px
1302		this.css({
1303			visibility: 'hidden',
1304			position: 'absolute',
1305			height: 'auto',
1306			'padding-top': 0,
1307			'padding-bottom': 0,
1308			'margin-top': -20,
1309			opacity: '',
1310			display: 'block'
1311		});
1312		var height = this.height();
1313		this.css({
1314			overflow: 'hidden',
1315			height: '0px'
1316		}).resetInlineCSS('visibility', 'position');
1317		var $this = this;
1318		this.performCSSTransition({
1319			height: height + paddingTop + paddingBottom,
1320			'margin-top': 0,
1321			'padding-top': paddingTop,
1322			'padding-bottom': paddingBottom
1323		}, duration || 350, function(){
1324			$this.resetInlineCSS('overflow', 'margin-top', 'padding-top', 'padding-bottom').css('height', 'auto');
1325			if (typeof onFinish == 'function') onFinish();
1326		}, easing || 'cubic-bezier(.23,1,.32,1)', delay || 150);
1327	};
1328	jQuery.fn.hideMD = function(duration, onFinish, easing, delay){
1329		if (this.length == 0) return;
1330		this.clearPreviousTransitions();
1331		var $this = this;
1332		this.resetInlineCSS('margin-top');
1333		this.performCSSTransition({
1334			opacity: 0
1335		}, duration || 100, function(){
1336			$this.css({
1337				display: 'none'
1338			}).resetInlineCSS('opacity');
1339			if (typeof onFinish == 'function') onFinish();
1340		}, easing, delay);
1341	};
1342	// Slide element left / right
1343	var slideIn = function($this, from){
1344			if ($this.length == 0) return;
1345			$this.clearPreviousTransitions();
1346			$this.css({width: 'auto', height: 'auto'});
1347			var width = $this.width(),
1348				height = $this.height();
1349			$this.css({
1350				width: width,
1351				height: height,
1352				position: 'relative',
1353				left: (from == 'right') ? '100%' : '-100%',
1354				opacity: 0,
1355				display: 'block'
1356			});
1357			$this.performCSSTransition({
1358				left: '0%',
1359				opacity: 1
1360			}, arguments[0] || 250, function(){
1361				$this.resetInlineCSS('position', 'left', 'opacity', 'display').css({width: 'auto', height: 'auto'});
1362			});
1363		},
1364		slideOut = function($this, to){
1365			if ($this.length == 0) return;
1366			$this.clearPreviousTransitions();
1367			$this.css({
1368				position: 'relative',
1369				left: 0,
1370				opacity: 1
1371			});
1372			$this.performCSSTransition({
1373				left: (to == 'left') ? '-100%' : '100%',
1374				opacity: 0
1375			}, arguments[0] || 250, function(){
1376				$this.css({
1377					display: 'none'
1378				}).resetInlineCSS('position', 'left', 'opacity');
1379			});
1380		};
1381	jQuery.fn.slideOutLeft = function(){ slideOut(this, 'left'); };
1382	jQuery.fn.slideOutRight = function(){ slideOut(this, 'right'); };
1383	jQuery.fn.slideInLeft = function(){ slideIn(this, 'left'); };
1384	jQuery.fn.slideInRight = function(){ slideIn(this, 'right'); };
1385}();

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.