PageSourceSearch

https://cityco.com/app/themes/cityco/js/jquery.main.js?ver=12.2

js cityco.com collected 2026-10-02 06:18:15 UTC 86,394 bytes, 2,534 lines download raw bytes

1jQuery(document).ready(function($){
2	// Autohide header
3	var hiddenClass = 'header-hidden';
4	var header = $('#header')
5	var lastY;
6
7	$(window).bind('touchmove scroll', function (e){
8		var currentY = $(window).scrollTop();;
9
10		if( currentY > lastY && currentY > 100 ){
11			// moved down
12			header.addClass( hiddenClass );
13		} else if( currentY < lastY ){
14			// moved up
15			header.removeClass( hiddenClass );
16		}
17		lastY = currentY;
18	});
19
20	// Carousel
21    if( $('.bxslider').children().length > 1){
22
23        $('.bxslider').bxSlider({
24            mode: 'horizontal',
25            slideMargin: 10,
26            pagerCustom: '#bx-pager',
27            captions: true,
28            controls: false,
29            responsive: true,
30            useCSS: false,
31            auto: true,
32        });
33    }
34
35	var sliderArray = new Array();
36	function initMediaSliders(){
37		$('.media-slider').each( function(){
38			sliderArray.push($(this).bxSlider({
39			    mode: 'horizontal',
40			    slideMargin: 10,
41			    captions: true,
42			    responsive: true,
43			    useCSS: false,
44		        auto: false,
45		        pager: false,
46				nextText: ' ',
47				prevText: ' '
48			}));
49		});
50	}
51
52	initMediaSliders();
53	// Media Gallery section
54	$('.link-list li').eq(0).addClass('active');
55	$('.media-gallery .slider').not('.media-gallery .slider:first-child').hide();
56
57	$('.link-list a').click(function(){
58		if(!$(this).parent('li').hasClass('active')){
59			// Get height
60			$('.slider').css("height", $('.timeline-detail').height() + 'px' );
61
62			$('.link-list li').removeClass('active');
63			$(this).parent('li').addClass('active');
64
65			var index = $(this).data('tab');
66			// Make disappear
67			$('.media-gallery .slider').not($('.tab-' + index)).css('position','absolute').fadeOut('slow',function(){
68				$('.tab-' + index).addClass('active').fadeIn('slow',function(){
69					$('.media-gallery .slider').css('height','auto');
70					$('.media-slider').each(function(){
71						$.each(sliderArray, function(index, value){
72							value.reloadSlider();
73						});
74					});
75				});
76			});
77		}
78		return false;
79	});
80
81   	// Generic load more
82	$('.load-more').click( function(){
83
84		// Set up items
85		button = $(this).addClass('active');
86		containerId = '#' + $(this).data('target');
87		container = $(containerId);
88
89		// Increment the page
90		amount = container.attr('data-amount');
91		page = parseInt(container.attr('data-page')) + 1;
92		container.attr('data-page', page);
93
94		// Query
95		queryString = 'ajax=1&paged=' + page;
96		if($('.filter-form') && $('.filter-form').serialize() != ''){
97			queryString = queryString + '&' + $('.filter-form').serialize();
98		}
99
100		// Ajax call
101		$.get( '', queryString , function(data){
102
103			// Append data
104			newData = $(data).find(containerId + ' > div');
105			newData.hide().fadeIn(1000).css('display','inline-block');
106			newData.appendTo( container );
107			initSameHeight();
108			// Append data
109			button.removeClass('active');
110			if(newData.length < amount){
111				button.fadeOut(500);
112			}
113
114		});
115		return false;
116	});
117
118    // Toggle the map
119	$('.show-map').click( function(){
120        $(this).toggleClass('active');
121        $(".acf-map").toggle();
122        google.maps.event.trigger( map, 'resize' );
123        map.setZoom( map.getZoom() );
124        center_map( map );
125
126        return false;
127    });
128
129	// Find all iframes
130	var $iframes = $( "#content iframe" );
131
132	// Find &#x26; save the aspect ratio for all iframes
133	$iframes.each(function () {
134		$( this ).data( "ratio", this.height / this.width )
135				// Remove the hardcoded width &#x26; height attributes
136				.removeAttr( "width" )
137				.removeAttr( "height" );
138	});
139
140	// Resize the iframes when the window is resized
141	$( window ).resize( function () {
142		$iframes.each( function() {
143			// Get the parent container&#x27;s width
144			var width = $( this ).parent().width();
145			$( this ).width( width )
146					.height( width * $( this ).data( "ratio" ) );
147		});
148		// Resize to fix all iframes on page load.
149	}).resize();
150
151    /*
152    *  new_map
153    *
154    *  This function will render a Google Map onto the selected jQuery element
155    *
156    *  @type	function
157    *  @date	8/11/2013
158    *  @since	4.3.0
159    *
160    *  @param	$el (jQuery element)
161    *  @return	n/a
162    */
163    function new_map( $el ) {
164        // var
165        var $markers = $el.find('.marker');
166        // vars
167        var args = {
168            zoom		: 16,
169            center		: new google.maps.LatLng(0, 0),
170            mapTypeId	: google.maps.MapTypeId.ROADMAP,
171            scrollwheel : false,
172        };
173
174        // create map
175        var map = new google.maps.Map( $el[0], args);
176        // add a markers reference
177        map.markers = [];
178        // add markers
179        $markers.each(function(){
180            add_marker( $(this), map );
181        });
182        // center map
183        center_map( map );
184        // return
185        return map;
186    }
187
188
189    /*
190    *  add_marker
191    *
192    *  This function will add a marker to the selected Google Map
193    *
194    *  @type	function
195    *  @date	8/11/2013
196    *  @since	4.3.0
197    *
198    *  @param	$marker (jQuery element)
199    *  @param	map (Google Map object)
200    *  @return	n/a
201    */
202
203    function add_marker( $marker, map ) {
204
205        // var
206        var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );
207
208        // create marker
209        var marker = new google.maps.Marker({
210            position	: latlng,
211            map			: map
212        });
213
214        // add to array
215        map.markers.push( marker );
216
217        // if marker contains HTML, add it to an infoWindow
218        if( $marker.html() )
219        {
220            // create info window
221            var infowindow = new google.maps.InfoWindow({
222                content		: $marker.html()
223            });
224
225            // show info window when marker is clicked
226            google.maps.event.addListener(marker, 'click', function() {
227
228                infowindow.open( map, marker );
229
230            });
231        }
232
233    }
234    /*
235    *  center_map
236    *
237    *  This function will center the map, showing all markers attached to this map
238    *
239    *  @type	function
240    *  @date	8/11/2013
241    *  @since	4.3.0
242    *
243    *  @param	map (Google Map object)
244    *  @return	n/a
245    */
246    function center_map( map ) {
247        // vars
248        var bounds = new google.maps.LatLngBounds();
249
250        // loop through all markers and create bounds
251        $.each( map.markers, function( i, marker ){
252
253            var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
254
255            bounds.extend( latlng );
256
257        });
258
259        // only 1 marker?
260        if( map.markers.length == 1 )
261        {
262            // set center of map
263            map.setCenter( bounds.getCenter() );
264            map.setZoom( 16 );
265        }
266        else
267        {
268            // fit to bounds
269            map.fitBounds( bounds );
270        }
271
272    }
273
274    $('.acf-map').each(function(){
275		// create map
276		map = new_map( $(this) );
277	});
278});
279
280// page init
281jQuery(function(){
282	initCustomForms();
283	initTouchNav();
284	initMobileNav();
285	initSameHeight();
286	initDropDownClasses();
287	initRetinaCover();
288});
289
290// initialize custom form elements
291function initCustomForms() {
292	jcf.setOptions('Select', {
293		wrapNative: false,
294		wrapNativeOnMobile: false
295	});
296	jcf.replaceAll();
297}
298
299
300
301function initRetinaCover() {
302	jQuery('.bg-stretch').retinaCover();
303}
304
305
306// mobile menu init
307function initMobileNav() {
308	jQuery('body').mobileNav({
309		hideOnClickOutside: true,
310		menuActiveClass: 'nav-active',
311		menuOpener: '.nav-opener',
312		menuDrop: '.nav-drop'
313	});
314	jQuery('body').mobileNav({
315		hideOnClickOutside: true,
316		menuActiveClass: 'link-active',
317		menuOpener: '.link-opener',
318		menuDrop: '.link-drop'
319	});
320	jQuery('.filter').mobileNav({
321		hideOnClickOutside: false,
322		menuActiveClass: 'filter-active',
323		menuOpener: '.filter-opener',
324		menuDrop: '.filter-drop'
325	});
326}
327
328// align blocks height
329function initSameHeight() {
330	jQuery('.row').sameHeight({
331		elements: '.person-block',
332		flexible: true,
333		multiLine: true
334	});
335	jQuery('.row').sameHeight({
336		elements: '.stock a',
337		flexible: true,
338		multiLine: true
339	});
340	jQuery('.row').sameHeight({
341		elements: '.item-block a .text',
342		flexible: true,
343		multiLine: true
344	});
345	jQuery('.row').sameHeight({
346		elements: '.calendar',
347		flexible: true,
348		multiLine: true
349	});
350	// jQuery('.row').sameHeight({
351	// 	elements: '.event a',
352	// 	flexible: true,
353	// 	multiLine: true
354	// });
355	jQuery('.twitter-feeds').sameHeight({
356		elements: '.twitter-feed .img',
357		flexible: true,
358		multiLine: true
359	});
360	jQuery('.text-area').sameHeight({
361		elements: '.article .news-title',
362		flexible: true,
363		multiLine: true,
364		biggestHeight: true
365	});
366	jQuery('.text-area').sameHeight({
367		elements: '.col',
368		flexible: true,
369		multiLine: true
370	});
371	jQuery('.section.blue .row').sameHeight({
372		elements: '.col-4',
373		flexible: true,
374		multiLine: true
375	});
376}
377
378// handle dropdowns on mobile devices
379function initTouchNav() {
380	jQuery('#nav').each(function(){
381		new TouchNav({
382			navBlock: this
383		});
384	});
385}
386
387// add classes if item has dropdown
388function initDropDownClasses() {
389	jQuery('#nav li').each(function() {
390		var item = jQuery(this);
391		var drop = item.find('ul, form');
392		var link = item.find('a').eq(0);
393		if(drop.length && !item.hasClass('no-dropdown')) {
394			item.addClass('has-drop-down');
395			if(link.length) link.addClass('has-drop-down-a');
396		}
397	});
398}
399
400/*
401 * Simple Mobile Navigation
402 */
403 ;(function($) {
404 	function MobileNav(options) {
405 		this.options = $.extend({
406 			container: null,
407 			hideOnClickOutside: false,
408 			menuActiveClass: 'nav-active',
409 			menuOpener: '.nav-opener',
410 			menuDrop: '.nav-drop',
411 			toggleEvent: 'click',
412 			outsideClickEvent: 'click touchstart pointerdown MSPointerDown'
413 		}, options);
414 		this.initStructure();
415 		this.attachEvents();
416 	}
417 	MobileNav.prototype = {
418 		initStructure: function() {
419 			this.page = $('html');
420 			this.container = $(this.options.container);
421 			this.opener = this.container.find(this.options.menuOpener);
422 			this.drop = this.container.find(this.options.menuDrop);
423 		},
424 		attachEvents: function() {
425 			var self = this;
426
427 			if(activateResizeHandler) {
428 				activateResizeHandler();
429 				activateResizeHandler = null;
430 			}
431
432 			this.outsideClickHandler = function(e) {
433 				if(self.isOpened()) {
434 					var target = $(e.target);
435 					if(!target.closest(self.opener).length && !target.closest(self.drop).length) {
436 						self.hide();
437 					}
438 				}
439 			};
440
441 			this.openerClickHandler = function(e) {
442 				e.preventDefault();
443 				self.toggle();
444 			};
445
446 			this.opener.on(this.options.toggleEvent, this.openerClickHandler);
447 		},
448 		isOpened: function() {
449 			return this.container.hasClass(this.options.menuActiveClass);
450 		},
451 		show: function() {
452 			this.container.addClass(this.options.menuActiveClass);
453 			if(this.options.hideOnClickOutside) {
454 				this.page.on(this.options.outsideClickEvent, this.outsideClickHandler);
455 			}
456 		},
457 		hide: function() {
458 			this.container.removeClass(this.options.menuActiveClass);
459 			if(this.options.hideOnClickOutside) {
460 				this.page.off(this.options.outsideClickEvent, this.outsideClickHandler);
461 			}
462 		},
463 		toggle: function() {
464 			if(this.isOpened()) {
465 				this.hide();
466 			} else {
467 				this.show();
468 			}
469 		},
470 		destroy: function() {
471 			this.container.removeClass(this.options.menuActiveClass);
472 			this.opener.off(this.options.toggleEvent, this.clickHandler);
473 			this.page.off(this.options.outsideClickEvent, this.outsideClickHandler);
474 		}
475 	};
476
477 	var activateResizeHandler = function() {
478 		var win = $(window),
479 		doc = $('html'),
480 		resizeClass = 'resize-active',
481 		flag, timer;
482 		var removeClassHandler = function() {
483 			flag = false;
484 			doc.removeClass(resizeClass);
485 		};
486 		var resizeHandler = function() {
487 			if(!flag) {
488 				flag = true;
489 				doc.addClass(resizeClass);
490 			}
491 			clearTimeout(timer);
492 			timer = setTimeout(removeClassHandler, 500);
493 		};
494 		win.on('resize orientationchange', resizeHandler);
495 	};
496
497 	$.fn.mobileNav = function(options) {
498 		return this.each(function() {
499 			var params = $.extend({}, options, {container: this}),
500 			instance = new MobileNav(params);
501 			$.data(this, 'MobileNav', instance);
502 		});
503 	};
504 }(jQuery));
505
506/*
507 * jQuery SameHeight plugin
508 */
509 ;(function($){
510 	$.fn.sameHeight = function(opt) {
511 		var options = $.extend({
512 			skipClass: 'same-height-ignore',
513 			leftEdgeClass: 'same-height-left',
514 			rightEdgeClass: 'same-height-right',
515 			elements: '>*',
516 			flexible: false,
517 			multiLine: false,
518 			useMinHeight: false,
519 			biggestHeight: false
520 		},opt);
521 		return this.each(function(){
522 			var holder = $(this), postResizeTimer, ignoreResize;
523 			var elements = holder.find(options.elements).not('.' + options.skipClass);
524 			if(!elements.length) return;
525
526			// resize handler
527			function doResize() {
528				elements.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', '');
529				if(options.multiLine) {
530					// resize elements row by row
531					resizeElementsByRows(elements, options);
532				} else {
533					// resize elements by holder
534					resizeElements(elements, holder, options);
535				}
536			}
537			doResize();
538
539			// handle flexible layout / font resize
540			var delayedResizeHandler = function() {
541				if(!ignoreResize) {
542					ignoreResize = true;
543					doResize();
544					clearTimeout(postResizeTimer);
545					postResizeTimer = setTimeout(function() {
546						doResize();
547						setTimeout(function(){
548							ignoreResize = false;
549						}, 10);
550					}, 100);
551				}
552			};
553
554			// handle flexible/responsive layout
555			if(options.flexible) {
556				$(window).bind('resize orientationchange fontresize', delayedResizeHandler);
557			}
558
559			// handle complete page load including images and fonts
560			$(window).bind('load', delayedResizeHandler);
561		});
562 	};
563
564	// detect css min-height support
565	var supportMinHeight = typeof document.documentElement.style.maxHeight !== 'undefined';
566
567	// get elements by rows
568	function resizeElementsByRows(boxes, options) {
569		var currentRow = $(), maxHeight, maxCalcHeight = 0, firstOffset = boxes.eq(0).offset().top;
570		boxes.each(function(ind){
571			var curItem = $(this);
572			if(curItem.offset().top === firstOffset) {
573				currentRow = currentRow.add(this);
574			} else {
575				maxHeight = getMaxHeight(currentRow);
576				maxCalcHeight = Math.max(maxCalcHeight, resizeElements(currentRow, maxHeight, options));
577				currentRow = curItem;
578				firstOffset = curItem.offset().top;
579			}
580		});
581		if(currentRow.length) {
582			maxHeight = getMaxHeight(currentRow);
583			maxCalcHeight = Math.max(maxCalcHeight, resizeElements(currentRow, maxHeight, options));
584		}
585		if(options.biggestHeight) {
586			boxes.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', maxCalcHeight);
587		}
588	}
589
590	// calculate max element height
591	function getMaxHeight(boxes) {
592		var maxHeight = 0;
593		boxes.each(function(){
594			maxHeight = Math.max(maxHeight, $(this).outerHeight());
595		});
596		return maxHeight;
597	}
598
599	// resize helper function
600	function resizeElements(boxes, parent, options) {
601		var calcHeight;
602		var parentHeight = typeof parent === 'number' ? parent : parent.height();
603		boxes.removeClass(options.leftEdgeClass).removeClass(options.rightEdgeClass).each(function(i){
604			var element = $(this);
605			var depthDiffHeight = 0;
606			var isBorderBox = element.css('boxSizing') === 'border-box' || element.css('-moz-box-sizing') === 'border-box' || element.css('-webkit-box-sizing') === 'border-box';
607
608			if(typeof parent !== 'number') {
609				element.parents().each(function(){
610					var tmpParent = $(this);
611					if(parent.is(this)) {
612						return false;
613					} else {
614						depthDiffHeight += tmpParent.outerHeight() - tmpParent.height();
615					}
616				});
617			}
618			calcHeight = parentHeight - depthDiffHeight;
619			calcHeight -= isBorderBox ? 0 : element.outerHeight() - element.height();
620
621			if(calcHeight > 0) {
622				element.css(options.useMinHeight && supportMinHeight ? 'minHeight' : 'height', calcHeight);
623			}
624		});
625		boxes.filter(':first').addClass(options.leftEdgeClass);
626		boxes.filter(':last').addClass(options.rightEdgeClass);
627		return calcHeight;
628	}
629}(jQuery));
630
631/*
632 * jQuery FontResize Event
633 */
634 jQuery.onFontResize = (function($) {
635 	$(function() {
636 		var randomID = 'font-resize-frame-' + Math.floor(Math.random() * 1000);
637 		var resizeFrame = $('<iframe>').attr('id', randomID).addClass('font-resize-helper');
638
639		// required styles
640		resizeFrame.css({
641			width: '100em',
642			height: '10px',
643			position: 'absolute',
644			borderWidth: 0,
645			top: '-9999px',
646			left: '-9999px'
647		}).appendTo('body');
648
649		// use native IE resize event if possible
650		if (window.attachEvent && !window.addEventListener) {
651			resizeFrame.bind('resize', function () {
652				$.onFontResize.trigger(resizeFrame[0].offsetWidth / 100);
653			});
654		}
655		// use script inside the iframe to detect resize for other browsers
656		else {
657			var doc = resizeFrame[0].contentWindow.document;
658			doc.open();
659			doc.write('<scri' + 'pt>window.onload = function(){var em = parent.jQuery("#' + randomID + '")[0];window.onresize = function(){if(parent.jQuery.onFontResize){parent.jQuery.onFontResize.trigger(em.offsetWidth / 100);}}};</scri' + 'pt>');
660			doc.close();
661		}
662		jQuery.onFontResize.initialSize = resizeFrame[0].offsetWidth / 100;
663	});
664 	return {
665		// public method, so it can be called from within the iframe
666		trigger: function (em) {
667			$(window).trigger("fontresize", [em]);
668		}
669	};
670}(jQuery));
671
672/*!
673 * JavaScript Custom Forms
674 *
675 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
676 * Released under the MIT license (LICENSE.txt)
677 *
678 * Version: 1.1.3
679 */
680 ;(function(root, factory) {
681 	'use strict';
682 	if (typeof define === 'function' && define.amd) {
683 		define(['jquery'], factory);
684 	} else if (typeof exports === 'object') {
685 		module.exports = factory(require('jquery'));
686 	} else {
687 		root.jcf = factory(jQuery);
688 	}
689 }(this, function($) {
690 	'use strict';
691
692	// define version
693	var version = '1.1.3';
694
695	// private variables
696	var customInstances = [];
697
698	// default global options
699	var commonOptions = {
700		optionsKey: 'jcf',
701		dataKey: 'jcf-instance',
702		rtlClass: 'jcf-rtl',
703		focusClass: 'jcf-focus',
704		pressedClass: 'jcf-pressed',
705		disabledClass: 'jcf-disabled',
706		hiddenClass: 'jcf-hidden',
707		resetAppearanceClass: 'jcf-reset-appearance',
708		unselectableClass: 'jcf-unselectable'
709	};
710
711	// detect device type
712	var isTouchDevice = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch,
713	isWinPhoneDevice = /Windows Phone/.test(navigator.userAgent);
714	commonOptions.isMobileDevice = !!(isTouchDevice || isWinPhoneDevice);
715
716	// create global stylesheet if custom forms are used
717	var createStyleSheet = function() {
718		var styleTag = $('<style>').appendTo('head'),
719		styleSheet = styleTag.prop('sheet') || styleTag.prop('styleSheet');
720
721		// crossbrowser style handling
722        var addCSSRule = function(selector, rules, index) {
723			if( typeof index == 'undefined' ) index = 0;
724
725            if (styleSheet.insertRule) {
726				styleSheet.insertRule(selector + '{' + rules + '}', index);
727			} else {
728				styleSheet.addRule(selector, rules, index);
729			}
730		};
731
732		// add special rules
733		addCSSRule('.' + commonOptions.hiddenClass, 'position:absolute !important;left:-9999px !important;height:1px !important;width:1px !important;margin:0 !important;border-width:0 !important;-webkit-appearance:none;-moz-appearance:none;appearance:none');
734		addCSSRule('.' + commonOptions.rtlClass + ' .' + commonOptions.hiddenClass, 'right:-9999px !important; left: auto !important');
735		addCSSRule('.' + commonOptions.unselectableClass, '-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0);');
736		addCSSRule('.' + commonOptions.resetAppearanceClass, 'background: none; border: none; -webkit-appearance: none; appearance: none; opacity: 0; filter: alpha(opacity=0);');
737
738		// detect rtl pages
739		var html = $('html'), body = $('body');
740		if (html.css('direction') === 'rtl' || body.css('direction') === 'rtl') {
741			html.addClass(commonOptions.rtlClass);
742		}
743
744		// handle form reset event
745		html.on('reset', function() {
746			setTimeout(function() {
747				api.refreshAll();
748			}, 0);
749		});
750
751		// mark stylesheet as created
752		commonOptions.styleSheetCreated = true;
753	};
754
755	// simplified pointer events handler
756	(function() {
757		var pointerEventsSupported = navigator.pointerEnabled || navigator.msPointerEnabled,
758		touchEventsSupported = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch,
759		eventList, eventMap = {}, eventPrefix = 'jcf-';
760
761		// detect events to attach
762		if (pointerEventsSupported) {
763			eventList = {
764				pointerover: navigator.pointerEnabled ? 'pointerover' : 'MSPointerOver',
765				pointerdown: navigator.pointerEnabled ? 'pointerdown' : 'MSPointerDown',
766				pointermove: navigator.pointerEnabled ? 'pointermove' : 'MSPointerMove',
767				pointerup: navigator.pointerEnabled ? 'pointerup' : 'MSPointerUp'
768			};
769		} else {
770			eventList = {
771				pointerover: 'mouseover',
772				pointerdown: 'mousedown' + (touchEventsSupported ? ' touchstart' : ''),
773				pointermove: 'mousemove' + (touchEventsSupported ? ' touchmove' : ''),
774				pointerup: 'mouseup' + (touchEventsSupported ? ' touchend' : '')
775			};
776		}
777
778		// create event map
779		$.each(eventList, function(targetEventName, fakeEventList) {
780			$.each(fakeEventList.split(' '), function(index, fakeEventName) {
781				eventMap[fakeEventName] = targetEventName;
782			});
783		});
784
785		// jQuery event hooks
786		$.each(eventList, function(eventName, eventHandlers) {
787			eventHandlers = eventHandlers.split(' ');
788			$.event.special[eventPrefix + eventName] = {
789				setup: function() {
790					var self = this;
791					$.each(eventHandlers, function(index, fallbackEvent) {
792						if (self.addEventListener) self.addEventListener(fallbackEvent, fixEvent, false);
793						else self['on' + fallbackEvent] = fixEvent;
794					});
795				},
796				teardown: function() {
797					var self = this;
798					$.each(eventHandlers, function(index, fallbackEvent) {
799						if (self.addEventListener) self.removeEventListener(fallbackEvent, fixEvent, false);
800						else self['on' + fallbackEvent] = null;
801					});
802				}
803			};
804		});
805
806		// check that mouse event are not simulated by mobile browsers
807		var lastTouch = null;
808		var mouseEventSimulated = function(e) {
809			var dx = Math.abs(e.pageX - lastTouch.x),
810			dy = Math.abs(e.pageY - lastTouch.y),
811			rangeDistance = 25;
812
813			if (dx <= rangeDistance && dy <= rangeDistance) {
814				return true;
815			}
816		};
817
818		// normalize event
819		var fixEvent = function(e) {
820			var origEvent = e || window.event,
821			touchEventData = null,
822			targetEventName = eventMap[origEvent.type];
823
824			e = $.event.fix(origEvent);
825			e.type = eventPrefix + targetEventName;
826
827			if (origEvent.pointerType) {
828				switch (origEvent.pointerType) {
829					case 2: e.pointerType = 'touch'; break;
830					case 3: e.pointerType = 'pen'; break;
831					case 4: e.pointerType = 'mouse'; break;
832					default: e.pointerType = origEvent.pointerType;
833				}
834			} else {
835				e.pointerType = origEvent.type.substr(0, 5); // "mouse" or "touch" word length
836			}
837
838			if (!e.pageX && !e.pageY) {
839				touchEventData = origEvent.changedTouches ? origEvent.changedTouches[0] : origEvent;
840				e.pageX = touchEventData.pageX;
841				e.pageY = touchEventData.pageY;
842			}
843
844			if (origEvent.type === 'touchend') {
845				lastTouch = { x: e.pageX, y: e.pageY };
846			}
847			if (e.pointerType === 'mouse' && lastTouch && mouseEventSimulated(e)) {
848				return;
849			} else {
850				return ($.event.dispatch || $.event.handle).call(this, e);
851			}
852		};
853	}());
854
855	// custom mousewheel/trackpad handler
856	(function() {
857		var wheelEvents = ('onwheel' in document || document.documentMode >= 9 ? 'wheel' : 'mousewheel DOMMouseScroll').split(' '),
858		shimEventName = 'jcf-mousewheel';
859
860		$.event.special[shimEventName] = {
861			setup: function() {
862				var self = this;
863				$.each(wheelEvents, function(index, fallbackEvent) {
864					if (self.addEventListener) self.addEventListener(fallbackEvent, fixEvent, false);
865					else self['on' + fallbackEvent] = fixEvent;
866				});
867			},
868			teardown: function() {
869				var self = this;
870				$.each(wheelEvents, function(index, fallbackEvent) {
871					if (self.addEventListener) self.removeEventListener(fallbackEvent, fixEvent, false);
872					else self['on' + fallbackEvent] = null;
873				});
874			}
875		};
876
877		var fixEvent = function(e) {
878			var origEvent = e || window.event;
879			e = $.event.fix(origEvent);
880			e.type = shimEventName;
881
882			// old wheel events handler
883			if ('detail'      in origEvent) { e.deltaY = -origEvent.detail;      }
884			if ('wheelDelta'  in origEvent) { e.deltaY = -origEvent.wheelDelta;  }
885			if ('wheelDeltaY' in origEvent) { e.deltaY = -origEvent.wheelDeltaY; }
886			if ('wheelDeltaX' in origEvent) { e.deltaX = -origEvent.wheelDeltaX; }
887
888			// modern wheel event handler
889			if ('deltaY' in origEvent) {
890				e.deltaY = origEvent.deltaY;
891			}
892			if ('deltaX' in origEvent) {
893				e.deltaX = origEvent.deltaX;
894			}
895
896			// handle deltaMode for mouse wheel
897			e.delta = e.deltaY || e.deltaX;
898			if (origEvent.deltaMode === 1) {
899				var lineHeight = 16;
900				e.delta *= lineHeight;
901				e.deltaY *= lineHeight;
902				e.deltaX *= lineHeight;
903			}
904
905			return ($.event.dispatch || $.event.handle).call(this, e);
906		};
907	}());
908
909	// extra module methods
910	var moduleMixin = {
911		// provide function for firing native events
912		fireNativeEvent: function(elements, eventName) {
913			$(elements).each(function() {
914				var element = this, eventObject;
915				if (element.dispatchEvent) {
916					eventObject = document.createEvent('HTMLEvents');
917					eventObject.initEvent(eventName, true, true);
918					element.dispatchEvent(eventObject);
919				} else if (document.createEventObject) {
920					eventObject = document.createEventObject();
921					eventObject.target = element;
922					element.fireEvent('on' + eventName, eventObject);
923				}
924			});
925		},
926		// bind event handlers for module instance (functions beggining with "on")
927		bindHandlers: function() {
928			var self = this;
929			$.each(self, function(propName, propValue) {
930				if (propName.indexOf('on') === 0 && $.isFunction(propValue)) {
931					// dont use $.proxy here because it doesn't create unique handler
932					self[propName] = function() {
933						return propValue.apply(self, arguments);
934					};
935				}
936			});
937		}
938	};
939
940	// public API
941	var api = {
942		version: version,
943		modules: {},
944		getOptions: function() {
945			return $.extend({}, commonOptions);
946		},
947		setOptions: function(moduleName, moduleOptions) {
948			if (arguments.length > 1) {
949				// set module options
950				if (this.modules[moduleName]) {
951					$.extend(this.modules[moduleName].prototype.options, moduleOptions);
952				}
953			} else {
954				// set common options
955				$.extend(commonOptions, moduleName);
956			}
957		},
958		addModule: function(proto) {
959			// add module to list
960			var Module = function(options) {
961				// save instance to collection
962				if (!options.element.data(commonOptions.dataKey)) {
963					options.element.data(commonOptions.dataKey, this);
964				}
965				customInstances.push(this);
966
967				// save options
968				this.options = $.extend({}, commonOptions, this.options, getInlineOptions(options.element), options);
969
970				// bind event handlers to instance
971				this.bindHandlers();
972
973				// call constructor
974				this.init.apply(this, arguments);
975			};
976
977			// parse options from HTML attribute
978			var getInlineOptions = function(element) {
979				var dataOptions = element.data(commonOptions.optionsKey),
980				attrOptions = element.attr(commonOptions.optionsKey);
981
982				if (dataOptions) {
983					return dataOptions;
984				} else if (attrOptions) {
985					try {
986						return $.parseJSON(attrOptions);
987					} catch (e) {
988						// ignore invalid attributes
989					}
990				}
991			};
992
993			// set proto as prototype for new module
994			Module.prototype = proto;
995
996			// add mixin methods to module proto
997			$.extend(proto, moduleMixin);
998			if (proto.plugins) {
999				$.each(proto.plugins, function(pluginName, plugin) {
1000					$.extend(plugin.prototype, moduleMixin);
1001				});
1002			}
1003
1004			// override destroy method
1005			var originalDestroy = Module.prototype.destroy;
1006			Module.prototype.destroy = function() {
1007				this.options.element.removeData(this.options.dataKey);
1008
1009				for (var i = customInstances.length - 1; i >= 0; i--) {
1010					if (customInstances[i] === this) {
1011						customInstances.splice(i, 1);
1012						break;
1013					}
1014				}
1015
1016				if (originalDestroy) {
1017					originalDestroy.apply(this, arguments);
1018				}
1019			};
1020
1021			// save module to list
1022			this.modules[proto.name] = Module;
1023		},
1024		getInstance: function(element) {
1025			return $(element).data(commonOptions.dataKey);
1026		},
1027		replace: function(elements, moduleName, customOptions) {
1028			var self = this,
1029			instance;
1030
1031			if (!commonOptions.styleSheetCreated) {
1032				createStyleSheet();
1033			}
1034
1035			$(elements).each(function() {
1036				var moduleOptions,
1037				element = $(this);
1038
1039				instance = element.data(commonOptions.dataKey);
1040				if (instance) {
1041					instance.refresh();
1042				} else {
1043					if (!moduleName) {
1044						$.each(self.modules, function(currentModuleName, module) {
1045							if (module.prototype.matchElement.call(module.prototype, element)) {
1046								moduleName = currentModuleName;
1047								return false;
1048							}
1049						});
1050					}
1051					if (moduleName) {
1052						moduleOptions = $.extend({ element: element }, customOptions);
1053						instance = new self.modules[moduleName](moduleOptions);
1054					}
1055				}
1056			});
1057			return instance;
1058		},
1059		refresh: function(elements) {
1060			$(elements).each(function() {
1061				var instance = $(this).data(commonOptions.dataKey);
1062				if (instance) {
1063					instance.refresh();
1064				}
1065			});
1066		},
1067		destroy: function(elements) {
1068			$(elements).each(function() {
1069				var instance = $(this).data(commonOptions.dataKey);
1070				if (instance) {
1071					instance.destroy();
1072				}
1073			});
1074		},
1075		replaceAll: function(context) {
1076			var self = this;
1077			$.each(this.modules, function(moduleName, module) {
1078				$(module.prototype.selector, context).each(function() {
1079					if (this.className.indexOf('jcf-ignore') < 0) {
1080						self.replace(this, moduleName);
1081					}
1082				});
1083			});
1084		},
1085		refreshAll: function(context) {
1086			if (context) {
1087				$.each(this.modules, function(moduleName, module) {
1088					$(module.prototype.selector, context).each(function() {
1089						var instance = $(this).data(commonOptions.dataKey);
1090						if (instance) {
1091							instance.refresh();
1092						}
1093					});
1094				});
1095			} else {
1096				for (var i = customInstances.length - 1; i >= 0; i--) {
1097					customInstances[i].refresh();
1098				}
1099			}
1100		},
1101		destroyAll: function(context) {
1102			if (context) {
1103				$.each(this.modules, function(moduleName, module) {
1104					$(module.prototype.selector, context).each(function(index, element) {
1105						var instance = $(element).data(commonOptions.dataKey);
1106						if (instance) {
1107							instance.destroy();
1108						}
1109					});
1110				});
1111			} else {
1112				while (customInstances.length) {
1113					customInstances[0].destroy();
1114				}
1115			}
1116		}
1117	};
1118
1119	// always export API to the global window object
1120	window.jcf = api;
1121
1122	return api;
1123}));
1124
1125/*!
1126 * JavaScript Custom Forms : Select Module
1127 *
1128 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
1129 * Released under the MIT license (LICENSE.txt)
1130 *
1131 * Version: 1.1.3
1132 */
1133 ;(function($, window) {
1134 	'use strict';
1135
1136 	jcf.addModule({
1137 		name: 'Select',
1138 		selector: 'select',
1139 		options: {
1140 			element: null,
1141 			multipleCompactStyle: false
1142 		},
1143 		plugins: {
1144 			ListBox: ListBox,
1145 			ComboBox: ComboBox,
1146 			SelectList: SelectList
1147 		},
1148 		matchElement: function(element) {
1149 			return element.is('select');
1150 		},
1151 		init: function() {
1152 			this.element = $(this.options.element);
1153 			this.createInstance();
1154 		},
1155 		isListBox: function() {
1156 			return this.element.is('[size]:not([jcf-size]), [multiple]');
1157 		},
1158 		createInstance: function() {
1159 			if (this.instance) {
1160 				this.instance.destroy();
1161 			}
1162 			if (this.isListBox() && !this.options.multipleCompactStyle) {
1163 				this.instance = new ListBox(this.options);
1164 			} else {
1165 				this.instance = new ComboBox(this.options);
1166 			}
1167 		},
1168 		refresh: function() {
1169 			var typeMismatch = (this.isListBox() && this.instance instanceof ComboBox) ||
1170 			(!this.isListBox() && this.instance instanceof ListBox);
1171
1172 			if (typeMismatch) {
1173 				this.createInstance();
1174 			} else {
1175 				this.instance.refresh();
1176 			}
1177 		},
1178 		destroy: function() {
1179 			this.instance.destroy();
1180 		}
1181 	});
1182
1183	// combobox module
1184	function ComboBox(options) {
1185		this.options = $.extend({
1186			wrapNative: true,
1187			wrapNativeOnMobile: true,
1188			fakeDropInBody: true,
1189			useCustomScroll: true,
1190			flipDropToFit: true,
1191			maxVisibleItems: 10,
1192			fakeAreaStructure: '<span class="jcf-select"><span class="jcf-select-text"></span><span class="jcf-select-opener"></span></span>',
1193			fakeDropStructure: '<div class="jcf-select-drop"><div class="jcf-select-drop-content"></div></div>',
1194			optionClassPrefix: 'jcf-option-',
1195			selectClassPrefix: 'jcf-select-',
1196			dropContentSelector: '.jcf-select-drop-content',
1197			selectTextSelector: '.jcf-select-text',
1198			dropActiveClass: 'jcf-drop-active',
1199			flipDropClass: 'jcf-drop-flipped'
1200		}, options);
1201		this.init();
1202	}
1203	$.extend(ComboBox.prototype, {
1204		init: function() {
1205			this.initStructure();
1206			this.bindHandlers();
1207			this.attachEvents();
1208			this.refresh();
1209		},
1210		initStructure: function() {
1211			// prepare structure
1212			this.win = $(window);
1213			this.doc = $(document);
1214			this.realElement = $(this.options.element);
1215			this.fakeElement = $(this.options.fakeAreaStructure).insertAfter(this.realElement);
1216			this.selectTextContainer = this.fakeElement.find(this.options.selectTextSelector);
1217			this.selectText = $('<span></span>').appendTo(this.selectTextContainer);
1218			makeUnselectable(this.fakeElement);
1219
1220			// copy classes from original select
1221			this.fakeElement.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
1222
1223			// handle compact multiple style
1224			if (this.realElement.prop('multiple')) {
1225				this.fakeElement.addClass('jcf-compact-multiple');
1226			}
1227
1228			// detect device type and dropdown behavior
1229			if (this.options.isMobileDevice && this.options.wrapNativeOnMobile && !this.options.wrapNative) {
1230				this.options.wrapNative = true;
1231			}
1232
1233			if (this.options.wrapNative) {
1234				// wrap native select inside fake block
1235				this.realElement.prependTo(this.fakeElement).css({
1236					position: 'absolute',
1237					height: '100%',
1238					width: '100%'
1239				}).addClass(this.options.resetAppearanceClass);
1240			} else {
1241				// just hide native select
1242				this.realElement.addClass(this.options.hiddenClass);
1243				this.fakeElement.attr('title', this.realElement.attr('title'));
1244				this.fakeDropTarget = this.options.fakeDropInBody ? $('body') : this.fakeElement;
1245			}
1246		},
1247		attachEvents: function() {
1248			// delayed refresh handler
1249			var self = this;
1250			this.delayedRefresh = function() {
1251				setTimeout(function() {
1252					self.refresh();
1253					if (self.list) {
1254						self.list.refresh();
1255						self.list.scrollToActiveOption();
1256					}
1257				}, 1);
1258			};
1259
1260			// native dropdown event handlers
1261			if (this.options.wrapNative) {
1262				this.realElement.on({
1263					focus: this.onFocus,
1264					change: this.onChange,
1265					click: this.onChange,
1266					keydown: this.onChange
1267				});
1268			} else {
1269				// custom dropdown event handlers
1270				this.realElement.on({
1271					focus: this.onFocus,
1272					change: this.onChange,
1273					keydown: this.onKeyDown
1274				});
1275				this.fakeElement.on({
1276					'jcf-pointerdown': this.onSelectAreaPress
1277				});
1278			}
1279		},
1280		onKeyDown: function(e) {
1281			if (e.which === 13) {
1282				this.toggleDropdown();
1283			} else if (this.dropActive) {
1284				this.delayedRefresh();
1285			}
1286		},
1287		onChange: function() {
1288			this.refresh();
1289		},
1290		onFocus: function() {
1291			if (!this.pressedFlag || !this.focusedFlag) {
1292				this.fakeElement.addClass(this.options.focusClass);
1293				this.realElement.on('blur', this.onBlur);
1294				this.toggleListMode(true);
1295				this.focusedFlag = true;
1296			}
1297		},
1298		onBlur: function() {
1299			if (!this.pressedFlag) {
1300				this.fakeElement.removeClass(this.options.focusClass);
1301				this.realElement.off('blur', this.onBlur);
1302				this.toggleListMode(false);
1303				this.focusedFlag = false;
1304			}
1305		},
1306		onResize: function() {
1307			if (this.dropActive) {
1308				this.hideDropdown();
1309			}
1310		},
1311		onSelectDropPress: function() {
1312			this.pressedFlag = true;
1313		},
1314		onSelectDropRelease: function(e, pointerEvent) {
1315			this.pressedFlag = false;
1316			if (pointerEvent.pointerType === 'mouse') {
1317				this.realElement.focus();
1318			}
1319		},
1320		onSelectAreaPress: function(e) {
1321			// skip click if drop inside fake element or real select is disabled
1322			var dropClickedInsideFakeElement = !this.options.fakeDropInBody && $(e.target).closest(this.dropdown).length;
1323			if (dropClickedInsideFakeElement || e.button > 1 || this.realElement.is(':disabled')) {
1324				return;
1325			}
1326
1327			// toggle dropdown visibility
1328			this.selectOpenedByEvent = e.pointerType;
1329			this.toggleDropdown();
1330
1331			// misc handlers
1332			if (!this.focusedFlag) {
1333				if (e.pointerType === 'mouse') {
1334					this.realElement.focus();
1335				} else {
1336					this.onFocus(e);
1337				}
1338			}
1339			this.pressedFlag = true;
1340			this.fakeElement.addClass(this.options.pressedClass);
1341			this.doc.on('jcf-pointerup', this.onSelectAreaRelease);
1342		},
1343		onSelectAreaRelease: function(e) {
1344			if (this.focusedFlag && e.pointerType === 'mouse') {
1345				this.realElement.focus();
1346			}
1347			this.pressedFlag = false;
1348			this.fakeElement.removeClass(this.options.pressedClass);
1349			this.doc.off('jcf-pointerup', this.onSelectAreaRelease);
1350		},
1351		onOutsideClick: function(e) {
1352			var target = $(e.target),
1353			clickedInsideSelect = target.closest(this.fakeElement).length || target.closest(this.dropdown).length;
1354
1355			if (!clickedInsideSelect) {
1356				this.hideDropdown();
1357			}
1358		},
1359		onSelect: function() {
1360			this.refresh();
1361
1362			if (this.realElement.prop('multiple')) {
1363				this.repositionDropdown();
1364			} else {
1365				this.hideDropdown();
1366			}
1367
1368			this.fireNativeEvent(this.realElement, 'change');
1369		},
1370		toggleListMode: function(state) {
1371			if (!this.options.wrapNative) {
1372				if (state) {
1373					// temporary change select to list to avoid appearing of native dropdown
1374					this.realElement.attr({
1375						size: 4,
1376						'jcf-size': ''
1377					});
1378				} else {
1379					// restore select from list mode to dropdown select
1380					if (!this.options.wrapNative) {
1381						this.realElement.removeAttr('size jcf-size');
1382					}
1383				}
1384			}
1385		},
1386		createDropdown: function() {
1387			// destroy previous dropdown if needed
1388			if (this.dropdown) {
1389				this.list.destroy();
1390				this.dropdown.remove();
1391			}
1392
1393			// create new drop container
1394			this.dropdown = $(this.options.fakeDropStructure).appendTo(this.fakeDropTarget);
1395			this.dropdown.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
1396			makeUnselectable(this.dropdown);
1397
1398			// handle compact multiple style
1399			if (this.realElement.prop('multiple')) {
1400				this.dropdown.addClass('jcf-compact-multiple');
1401			}
1402
1403			// set initial styles for dropdown in body
1404			if (this.options.fakeDropInBody) {
1405				this.dropdown.css({
1406					position: 'absolute',
1407					top: -9999
1408				});
1409			}
1410
1411			// create new select list instance
1412			this.list = new SelectList({
1413				useHoverClass: true,
1414				handleResize: false,
1415				alwaysPreventMouseWheel: true,
1416				maxVisibleItems: this.options.maxVisibleItems,
1417				useCustomScroll: this.options.useCustomScroll,
1418				holder: this.dropdown.find(this.options.dropContentSelector),
1419				multipleSelectWithoutKey: this.realElement.prop('multiple'),
1420				element: this.realElement
1421			});
1422			$(this.list).on({
1423				select: this.onSelect,
1424				press: this.onSelectDropPress,
1425				release: this.onSelectDropRelease
1426			});
1427		},
1428		repositionDropdown: function() {
1429			var selectOffset = this.fakeElement.offset(),
1430			selectWidth = this.fakeElement.outerWidth(),
1431			selectHeight = this.fakeElement.outerHeight(),
1432			dropHeight = this.dropdown.css('width', selectWidth).outerHeight(),
1433			winScrollTop = this.win.scrollTop(),
1434			winHeight = this.win.height(),
1435			calcTop, calcLeft, bodyOffset, needFlipDrop = false;
1436
1437			// check flip drop position
1438			if (selectOffset.top + selectHeight + dropHeight > winScrollTop + winHeight && selectOffset.top - dropHeight > winScrollTop) {
1439				needFlipDrop = true;
1440			}
1441
1442			if (this.options.fakeDropInBody) {
1443				bodyOffset = this.fakeDropTarget.css('position') !== 'static' ? this.fakeDropTarget.offset().top : 0;
1444				if (this.options.flipDropToFit && needFlipDrop) {
1445					// calculate flipped dropdown position
1446					calcLeft = selectOffset.left;
1447					calcTop = selectOffset.top - dropHeight - bodyOffset;
1448				} else {
1449					// calculate default drop position
1450					calcLeft = selectOffset.left;
1451					calcTop = selectOffset.top + selectHeight - bodyOffset;
1452				}
1453
1454				// update drop styles
1455				this.dropdown.css({
1456					width: selectWidth,
1457					left: calcLeft,
1458					top: calcTop
1459				});
1460			}
1461
1462			// refresh flipped class
1463			this.dropdown.add(this.fakeElement).toggleClass(this.options.flipDropClass, this.options.flipDropToFit && needFlipDrop);
1464		},
1465		showDropdown: function() {
1466			// do not show empty custom dropdown
1467			if (!this.realElement.prop('options').length) {
1468				return;
1469			}
1470
1471			// create options list if not created
1472			if (!this.dropdown) {
1473				this.createDropdown();
1474			}
1475
1476			// show dropdown
1477			this.dropActive = true;
1478			this.dropdown.appendTo(this.fakeDropTarget);
1479			this.fakeElement.addClass(this.options.dropActiveClass);
1480			this.refreshSelectedText();
1481			this.repositionDropdown();
1482			this.list.setScrollTop(this.savedScrollTop);
1483			this.list.refresh();
1484
1485			// add temporary event handlers
1486			this.win.on('resize', this.onResize);
1487			this.doc.on('jcf-pointerdown', this.onOutsideClick);
1488		},
1489		hideDropdown: function() {
1490			if (this.dropdown) {
1491				this.savedScrollTop = this.list.getScrollTop();
1492				this.fakeElement.removeClass(this.options.dropActiveClass + ' ' + this.options.flipDropClass);
1493				this.dropdown.removeClass(this.options.flipDropClass).detach();
1494				this.doc.off('jcf-pointerdown', this.onOutsideClick);
1495				this.win.off('resize', this.onResize);
1496				this.dropActive = false;
1497				if (this.selectOpenedByEvent === 'touch') {
1498					this.onBlur();
1499				}
1500			}
1501		},
1502		toggleDropdown: function() {
1503			if (this.dropActive) {
1504				this.hideDropdown();
1505			} else {
1506				this.showDropdown();
1507			}
1508		},
1509		refreshSelectedText: function() {
1510			// redraw selected area
1511			var selectedIndex = this.realElement.prop('selectedIndex'),
1512			selectedOption = this.realElement.prop('options')[selectedIndex],
1513			selectedOptionImage = selectedOption ? selectedOption.getAttribute('data-image') : null,
1514			selectedOptionText = '',
1515			selectedOptionClasses,
1516			self = this;
1517
1518			if (this.realElement.prop('multiple')) {
1519				$.each(this.realElement.prop('options'), function(index, option) {
1520					if (option.selected) {
1521						selectedOptionText += (selectedOptionText ? ', ' : '') + option.innerHTML;
1522					}
1523				});
1524				if (!selectedOptionText) {
1525					selectedOptionText = self.realElement.attr('placeholder') || '';
1526				}
1527				this.selectText.removeAttr('class').html(selectedOptionText);
1528			} else if (!selectedOption) {
1529				if (this.selectImage) {
1530					this.selectImage.hide();
1531				}
1532				this.selectText.removeAttr('class').empty();
1533			} else if (this.currentSelectedText !== selectedOption.innerHTML || this.currentSelectedImage !== selectedOptionImage) {
1534				selectedOptionClasses = getPrefixedClasses(selectedOption.className, this.options.optionClassPrefix);
1535				this.selectText.attr('class', selectedOptionClasses).html(selectedOption.innerHTML);
1536
1537				if (selectedOptionImage) {
1538					if (!this.selectImage) {
1539						this.selectImage = $('<img>').prependTo(this.selectTextContainer).hide();
1540					}
1541					this.selectImage.attr('src', selectedOptionImage).show();
1542				} else if (this.selectImage) {
1543					this.selectImage.hide();
1544				}
1545
1546				this.currentSelectedText = selectedOption.innerHTML;
1547				this.currentSelectedImage = selectedOptionImage;
1548			}
1549		},
1550		refresh: function() {
1551			// refresh fake select visibility
1552			if (this.realElement.prop('style').display === 'none') {
1553				this.fakeElement.hide();
1554			} else {
1555				this.fakeElement.show();
1556			}
1557
1558			// refresh selected text
1559			this.refreshSelectedText();
1560
1561			// handle disabled state
1562			this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled'));
1563		},
1564		destroy: function() {
1565			// restore structure
1566			if (this.options.wrapNative) {
1567				this.realElement.insertBefore(this.fakeElement).css({
1568					position: '',
1569					height: '',
1570					width: ''
1571				}).removeClass(this.options.resetAppearanceClass);
1572			} else {
1573				this.realElement.removeClass(this.options.hiddenClass);
1574				if (this.realElement.is('[jcf-size]')) {
1575					this.realElement.removeAttr('size jcf-size');
1576				}
1577			}
1578
1579			// removing element will also remove its event handlers
1580			this.fakeElement.remove();
1581
1582			// remove other event handlers
1583			this.doc.off('jcf-pointerup', this.onSelectAreaRelease);
1584			this.realElement.off({
1585				focus: this.onFocus
1586			});
1587		}
1588	});
1589
1590	// listbox module
1591	function ListBox(options) {
1592		this.options = $.extend({
1593			wrapNative: true,
1594			useCustomScroll: true,
1595			fakeStructure: '<span class="jcf-list-box"><span class="jcf-list-wrapper"></span></span>',
1596			selectClassPrefix: 'jcf-select-',
1597			listHolder: '.jcf-list-wrapper'
1598		}, options);
1599		this.init();
1600	}
1601	$.extend(ListBox.prototype, {
1602		init: function() {
1603			this.bindHandlers();
1604			this.initStructure();
1605			this.attachEvents();
1606		},
1607		initStructure: function() {
1608			this.realElement = $(this.options.element);
1609			this.fakeElement = $(this.options.fakeStructure).insertAfter(this.realElement);
1610			this.listHolder = this.fakeElement.find(this.options.listHolder);
1611			makeUnselectable(this.fakeElement);
1612
1613			// copy classes from original select
1614			this.fakeElement.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
1615			this.realElement.addClass(this.options.hiddenClass);
1616
1617			this.list = new SelectList({
1618				useCustomScroll: this.options.useCustomScroll,
1619				holder: this.listHolder,
1620				selectOnClick: false,
1621				element: this.realElement
1622			});
1623		},
1624		attachEvents: function() {
1625			// delayed refresh handler
1626			var self = this;
1627			this.delayedRefresh = function(e) {
1628				if (e && e.which === 16) {
1629					// ignore SHIFT key
1630					return;
1631				} else {
1632					clearTimeout(self.refreshTimer);
1633					self.refreshTimer = setTimeout(function() {
1634						self.refresh();
1635						self.list.scrollToActiveOption();
1636					}, 1);
1637				}
1638			};
1639
1640			// other event handlers
1641			this.realElement.on({
1642				focus: this.onFocus,
1643				click: this.delayedRefresh,
1644				keydown: this.delayedRefresh
1645			});
1646
1647			// select list event handlers
1648			$(this.list).on({
1649				select: this.onSelect,
1650				press: this.onFakeOptionsPress,
1651				release: this.onFakeOptionsRelease
1652			});
1653		},
1654		onFakeOptionsPress: function(e, pointerEvent) {
1655			this.pressedFlag = true;
1656			if (pointerEvent.pointerType === 'mouse') {
1657				this.realElement.focus();
1658			}
1659		},
1660		onFakeOptionsRelease: function(e, pointerEvent) {
1661			this.pressedFlag = false;
1662			if (pointerEvent.pointerType === 'mouse') {
1663				this.realElement.focus();
1664			}
1665		},
1666		onSelect: function() {
1667			this.fireNativeEvent(this.realElement, 'change');
1668			this.fireNativeEvent(this.realElement, 'click');
1669		},
1670		onFocus: function() {
1671			if (!this.pressedFlag || !this.focusedFlag) {
1672				this.fakeElement.addClass(this.options.focusClass);
1673				this.realElement.on('blur', this.onBlur);
1674				this.focusedFlag = true;
1675			}
1676		},
1677		onBlur: function() {
1678			if (!this.pressedFlag) {
1679				this.fakeElement.removeClass(this.options.focusClass);
1680				this.realElement.off('blur', this.onBlur);
1681				this.focusedFlag = false;
1682			}
1683		},
1684		refresh: function() {
1685			this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled'));
1686			this.list.refresh();
1687		},
1688		destroy: function() {
1689			this.list.destroy();
1690			this.realElement.insertBefore(this.fakeElement).removeClass(this.options.hiddenClass);
1691			this.fakeElement.remove();
1692		}
1693	});
1694
1695	// options list module
1696	function SelectList(options) {
1697		this.options = $.extend({
1698			holder: null,
1699			maxVisibleItems: 10,
1700			selectOnClick: true,
1701			useHoverClass: false,
1702			useCustomScroll: false,
1703			handleResize: true,
1704			multipleSelectWithoutKey: false,
1705			alwaysPreventMouseWheel: false,
1706			indexAttribute: 'data-index',
1707			cloneClassPrefix: 'jcf-option-',
1708			containerStructure: '<span class="jcf-list"><span class="jcf-list-content"></span></span>',
1709			containerSelector: '.jcf-list-content',
1710			captionClass: 'jcf-optgroup-caption',
1711			disabledClass: 'jcf-disabled',
1712			optionClass: 'jcf-option',
1713			groupClass: 'jcf-optgroup',
1714			hoverClass: 'jcf-hover',
1715			selectedClass: 'jcf-selected',
1716			scrollClass: 'jcf-scroll-active'
1717		}, options);
1718		this.init();
1719	}
1720	$.extend(SelectList.prototype, {
1721		init: function() {
1722			this.initStructure();
1723			this.refreshSelectedClass();
1724			this.attachEvents();
1725		},
1726		initStructure: function() {
1727			this.element = $(this.options.element);
1728			this.indexSelector = '[' + this.options.indexAttribute + ']';
1729			this.container = $(this.options.containerStructure).appendTo(this.options.holder);
1730			this.listHolder = this.container.find(this.options.containerSelector);
1731			this.lastClickedIndex = this.element.prop('selectedIndex');
1732			this.rebuildList();
1733		},
1734		attachEvents: function() {
1735			this.bindHandlers();
1736			this.listHolder.on('jcf-pointerdown', this.indexSelector, this.onItemPress);
1737			this.listHolder.on('jcf-pointerdown', this.onPress);
1738
1739			if (this.options.useHoverClass) {
1740				this.listHolder.on('jcf-pointerover', this.indexSelector, this.onHoverItem);
1741			}
1742		},
1743		onPress: function(e) {
1744			$(this).trigger('press', e);
1745			this.listHolder.on('jcf-pointerup', this.onRelease);
1746		},
1747		onRelease: function(e) {
1748			$(this).trigger('release', e);
1749			this.listHolder.off('jcf-pointerup', this.onRelease);
1750		},
1751		onHoverItem: function(e) {
1752			var hoverIndex = parseFloat(e.currentTarget.getAttribute(this.options.indexAttribute));
1753			this.fakeOptions.removeClass(this.options.hoverClass).eq(hoverIndex).addClass(this.options.hoverClass);
1754		},
1755		onItemPress: function(e) {
1756			if (e.pointerType === 'touch' || this.options.selectOnClick) {
1757				// select option after "click"
1758				this.tmpListOffsetTop = this.list.offset().top;
1759				this.listHolder.on('jcf-pointerup', this.indexSelector, this.onItemRelease);
1760			} else {
1761				// select option immediately
1762				this.onSelectItem(e);
1763			}
1764		},
1765		onItemRelease: function(e) {
1766			// remove event handlers and temporary data
1767			this.listHolder.off('jcf-pointerup', this.indexSelector, this.onItemRelease);
1768
1769			// simulate item selection
1770			if (this.tmpListOffsetTop === this.list.offset().top) {
1771				this.listHolder.on('click', this.indexSelector, { savedPointerType: e.pointerType }, this.onSelectItem);
1772			}
1773			delete this.tmpListOffsetTop;
1774		},
1775		onSelectItem: function(e) {
1776			var clickedIndex = parseFloat(e.currentTarget.getAttribute(this.options.indexAttribute)),
1777			pointerType = e.data && e.data.savedPointerType || e.pointerType || 'mouse',
1778			range;
1779
1780			// remove click event handler
1781			this.listHolder.off('click', this.indexSelector, this.onSelectItem);
1782
1783			// ignore clicks on disabled options
1784			if (e.button > 1 || this.realOptions[clickedIndex].disabled) {
1785				return;
1786			}
1787
1788			if (this.element.prop('multiple')) {
1789				if (e.metaKey || e.ctrlKey || pointerType === 'touch' || this.options.multipleSelectWithoutKey) {
1790					// if CTRL/CMD pressed or touch devices - toggle selected option
1791					this.realOptions[clickedIndex].selected = !this.realOptions[clickedIndex].selected;
1792				} else if (e.shiftKey) {
1793					// if SHIFT pressed - update selection
1794					range = [this.lastClickedIndex, clickedIndex].sort(function(a, b) {
1795						return a - b;
1796					});
1797					this.realOptions.each(function(index, option) {
1798						option.selected = (index >= range[0] && index <= range[1]);
1799					});
1800				} else {
1801					// set single selected index
1802					this.element.prop('selectedIndex', clickedIndex);
1803				}
1804			} else {
1805				this.element.prop('selectedIndex', clickedIndex);
1806			}
1807
1808			// save last clicked option
1809			if (!e.shiftKey) {
1810				this.lastClickedIndex = clickedIndex;
1811			}
1812
1813			// refresh classes
1814			this.refreshSelectedClass();
1815
1816			// scroll to active item in desktop browsers
1817			if (pointerType === 'mouse') {
1818				this.scrollToActiveOption();
1819			}
1820
1821			// make callback when item selected
1822			$(this).trigger('select');
1823		},
1824		rebuildList: function() {
1825			// rebuild options
1826			var self = this,
1827			rootElement = this.element[0];
1828
1829			// recursively create fake options
1830			this.storedSelectHTML = rootElement.innerHTML;
1831			this.optionIndex = 0;
1832			this.list = $(this.createOptionsList(rootElement));
1833			this.listHolder.empty().append(this.list);
1834			this.realOptions = this.element.find('option');
1835			this.fakeOptions = this.list.find(this.indexSelector);
1836			this.fakeListItems = this.list.find('.' + this.options.captionClass + ',' + this.indexSelector);
1837			delete this.optionIndex;
1838
1839			// detect max visible items
1840			var maxCount = this.options.maxVisibleItems,
1841			sizeValue = this.element.prop('size');
1842			if (sizeValue > 1 && !this.element.is('[jcf-size]')) {
1843				maxCount = sizeValue;
1844			}
1845
1846			// handle scrollbar
1847			var needScrollBar = this.fakeOptions.length > maxCount;
1848			this.container.toggleClass(this.options.scrollClass, needScrollBar);
1849			if (needScrollBar) {
1850				// change max-height
1851				this.listHolder.css({
1852					maxHeight: this.getOverflowHeight(maxCount),
1853					overflow: 'auto'
1854				});
1855
1856				if (this.options.useCustomScroll && jcf.modules.Scrollable) {
1857					// add custom scrollbar if specified in options
1858					jcf.replace(this.listHolder, 'Scrollable', {
1859						handleResize: this.options.handleResize,
1860						alwaysPreventMouseWheel: this.options.alwaysPreventMouseWheel
1861					});
1862					return;
1863				}
1864			}
1865
1866			// disable edge wheel scrolling
1867			if (this.options.alwaysPreventMouseWheel) {
1868				this.preventWheelHandler = function(e) {
1869					var currentScrollTop = self.listHolder.scrollTop(),
1870					maxScrollTop = self.listHolder.prop('scrollHeight') - self.listHolder.innerHe
1870ight();
1871
1872					// check edge cases
1873					if ((currentScrollTop <= 0 && e.deltaY < 0) || (currentScrollTop >= maxScrollTop && e.deltaY > 0)) {
1874						e.preventDefault();
1875					}
1876				};
1877				this.listHolder.on('jcf-mousewheel', this.preventWheelHandler);
1878			}
1879		},
1880		refreshSelectedClass: function() {
1881			var self = this,
1882			selectedItem,
1883			isMultiple = this.element.prop('multiple'),
1884			selectedIndex = this.element.prop('selectedIndex');
1885
1886			if (isMultiple) {
1887				this.realOptions.each(function(index, option) {
1888					self.fakeOptions.eq(index).toggleClass(self.options.selectedClass, !!option.selected);
1889				});
1890			} else {
1891				this.fakeOptions.removeClass(this.options.selectedClass + ' ' + this.options.hoverClass);
1892				selectedItem = this.fakeOptions.eq(selectedIndex).addClass(this.options.selectedClass);
1893				if (this.options.useHoverClass) {
1894					selectedItem.addClass(this.options.hoverClass);
1895				}
1896			}
1897		},
1898		scrollToActiveOption: function() {
1899			// scroll to target option
1900			var targetOffset = this.getActiveOptionOffset();
1901			if (typeof targetOffset === 'number') {
1902				this.listHolder.prop('scrollTop', targetOffset);
1903			}
1904		},
1905		getSelectedIndexRange: function() {
1906			var firstSelected = -1, lastSelected = -1;
1907			this.realOptions.each(function(index, option) {
1908				if (option.selected) {
1909					if (firstSelected < 0) {
1910						firstSelected = index;
1911					}
1912					lastSelected = index;
1913				}
1914			});
1915			return [firstSelected, lastSelected];
1916		},
1917		getChangedSelectedIndex: function() {
1918			var selectedIndex = this.element.prop('selectedIndex'),
1919			targetIndex;
1920
1921			if (this.element.prop('multiple')) {
1922				// multiple selects handling
1923				if (!this.previousRange) {
1924					this.previousRange = [selectedIndex, selectedIndex];
1925				}
1926				this.currentRange = this.getSelectedIndexRange();
1927				targetIndex = this.currentRange[this.currentRange[0] !== this.previousRange[0] ? 0 : 1];
1928				this.previousRange = this.currentRange;
1929				return targetIndex;
1930			} else {
1931				// single choice selects handling
1932				return selectedIndex;
1933			}
1934		},
1935		getActiveOptionOffset: function() {
1936			// calc values
1937			var dropHeight = this.listHolder.height(),
1938			dropScrollTop = this.listHolder.prop('scrollTop'),
1939			currentIndex = this.getChangedSelectedIndex(),
1940			fakeOption = this.fakeOptions.eq(currentIndex),
1941			fakeOptionOffset = fakeOption.offset().top - this.list.offset().top,
1942			fakeOptionHeight = fakeOption.innerHeight();
1943
1944			// scroll list
1945			if (fakeOptionOffset + fakeOptionHeight >= dropScrollTop + dropHeight) {
1946				// scroll down (always scroll to option)
1947				return fakeOptionOffset - dropHeight + fakeOptionHeight;
1948			} else if (fakeOptionOffset < dropScrollTop) {
1949				// scroll up to option
1950				return fakeOptionOffset;
1951			}
1952		},
1953		getOverflowHeight: function(sizeValue) {
1954			var item = this.fakeListItems.eq(sizeValue - 1),
1955			listOffset = this.list.offset().top,
1956			itemOffset = item.offset().top,
1957			itemHeight = item.innerHeight();
1958
1959			return itemOffset + itemHeight - listOffset;
1960		},
1961		getScrollTop: function() {
1962			return this.listHolder.scrollTop();
1963		},
1964		setScrollTop: function(value) {
1965			this.listHolder.scrollTop(value);
1966		},
1967		createOption: function(option) {
1968			var newOption = document.createElement('span');
1969			newOption.className = this.options.optionClass;
1970			newOption.innerHTML = option.innerHTML;
1971			newOption.setAttribute(this.options.indexAttribute, this.optionIndex++);
1972
1973			var optionImage, optionImageSrc = option.getAttribute('data-image');
1974			if (optionImageSrc) {
1975				optionImage = document.createElement('img');
1976				optionImage.src = optionImageSrc;
1977				newOption.insertBefore(optionImage, newOption.childNodes[0]);
1978			}
1979			if (option.disabled) {
1980				newOption.className += ' ' + this.options.disabledClass;
1981			}
1982			if (option.className) {
1983				newOption.className += ' ' + getPrefixedClasses(option.className, this.options.cloneClassPrefix);
1984			}
1985			return newOption;
1986		},
1987		createOptGroup: function(optgroup) {
1988			var optGroupContainer = document.createElement('span'),
1989			optGroupName = optgroup.getAttribute('label'),
1990			optGroupCaption, optGroupList;
1991
1992			// create caption
1993			optGroupCaption = document.createElement('span');
1994			optGroupCaption.className = this.options.captionClass;
1995			optGroupCaption.innerHTML = optGroupName;
1996			optGroupContainer.appendChild(optGroupCaption);
1997
1998			// create list of options
1999			if (optgroup.children.length) {
2000				optGroupList = this.createOptionsList(optgroup);
2001				optGroupContainer.appendChild(optGroupList);
2002			}
2003
2004			optGroupContainer.className = this.options.groupClass;
2005			return optGroupContainer;
2006		},
2007		createOptionContainer: function() {
2008			var optionContainer = document.createElement('li');
2009			return optionContainer;
2010		},
2011		createOptionsList: function(container) {
2012			var self = this,
2013			list = document.createElement('ul');
2014
2015			$.each(container.children, function(index, currentNode) {
2016				var item = self.createOptionContainer(currentNode),
2017				newNode;
2018
2019				switch (currentNode.tagName.toLowerCase()) {
2020					case 'option': newNode = self.createOption(currentNode); break;
2021					case 'optgroup': newNode = self.createOptGroup(currentNode); break;
2022				}
2023				list.appendChild(item).appendChild(newNode);
2024			});
2025			return list;
2026		},
2027		refresh: function() {
2028			// check for select innerHTML changes
2029			if (this.storedSelectHTML !== this.element.prop('innerHTML')) {
2030				this.rebuildList();
2031			}
2032
2033			// refresh custom scrollbar
2034			var scrollInstance = jcf.getInstance(this.listHolder);
2035			if (scrollInstance) {
2036				scrollInstance.refresh();
2037			}
2038
2039			// refresh selectes classes
2040			this.refreshSelectedClass();
2041		},
2042		destroy: function() {
2043			this.listHolder.off('jcf-mousewheel', this.preventWheelHandler);
2044			this.listHolder.off('jcf-pointerdown', this.indexSelector, this.onSelectItem);
2045			this.listHolder.off('jcf-pointerover', this.indexSelector, this.onHoverItem);
2046			this.listHolder.off('jcf-pointerdown', this.onPress);
2047		}
2048	});
2049
2050	// helper functions
2051	var getPrefixedClasses = function(className, prefixToAdd) {
2052		return className ? className.replace(/[\s]*([\S]+)+[\s]*/gi, prefixToAdd + '$1 ') : '';
2053	};
2054	var makeUnselectable = (function() {
2055		var unselectableClass = jcf.getOptions().unselectableClass;
2056		function preventHandler(e) {
2057			e.preventDefault();
2058		}
2059		return function(node) {
2060			node.addClass(unselectableClass).on('selectstart', preventHandler);
2061		};
2062	}());
2063
2064}(jQuery, this));
2065
2066
2067// navigation accesibility module
2068function TouchNav(opt) {
2069	this.options = {
2070		hoverClass: 'hover',
2071		menuItems: 'li',
2072		menuOpener: 'a',
2073		menuDrop: 'ul, form',
2074		navBlock: null
2075	};
2076	for(var p in opt) {
2077		if(opt.hasOwnProperty(p)) {
2078			this.options[p] = opt[p];
2079		}
2080	}
2081	this.init();
2082}
2083TouchNav.isActiveOn = function(elem) {
2084	return elem && elem.touchNavActive;
2085};
2086TouchNav.prototype = {
2087	init: function() {
2088		if(typeof this.options.navBlock === 'string') {
2089			this.menu = document.getElementById(this.options.navBlock);
2090		} else if(typeof this.options.navBlock === 'object') {
2091			this.menu = this.options.navBlock;
2092		}
2093		if(this.menu) {
2094			this.addEvents();
2095		}
2096	},
2097	addEvents: function() {
2098		// attach event handlers
2099		var self = this;
2100		var touchEvent = (navigator.pointerEnabled && 'pointerdown') || (navigator.msPointerEnabled && 'MSPointerDown') || (this.isTouchDevice && 'touchstart');
2101		this.menuItems = lib.queryElementsBySelector(this.options.menuItems, this.menu);
2102
2103		var initMenuItem = function(item) {
2104			var currentDrop = lib.queryElementsBySelector(self.options.menuDrop, item)[0],
2105			currentOpener = lib.queryElementsBySelector(self.options.menuOpener, item)[0];
2106
2107			// only for touch input devices
2108			if( currentDrop && currentOpener && (self.isTouchDevice || self.isPointerDevice) ) {
2109				lib.event.add(currentOpener, 'click', lib.bind(self.clickHandler, self));
2110				lib.event.add(currentOpener, 'mousedown', lib.bind(self.mousedownHandler, self));
2111				lib.event.add(currentOpener, touchEvent, function(e){
2112					if( !self.isTouchPointerEvent(e) ) {
2113						self.preventCurrentClick = false;
2114						return;
2115					}
2116					self.touchFlag = true;
2117					self.currentItem = item;
2118					self.currentLink = currentOpener;
2119					self.pressHandler.apply(self, arguments);
2120				});
2121			}
2122			// for desktop computers and touch devices
2123			jQuery(item).bind('mouseenter', function(){
2124				if(!self.touchFlag) {
2125					self.currentItem = item;
2126					self.mouseoverHandler();
2127				}
2128			});
2129			jQuery(item).bind('mouseleave', function(){
2130				if(!self.touchFlag) {
2131					self.currentItem = item;
2132					self.mouseoutHandler();
2133				}
2134			});
2135			item.touchNavActive = true;
2136		};
2137
2138		// addd handlers for all menu items
2139		for(var i = 0; i < this.menuItems.length; i++) {
2140			initMenuItem(self.menuItems[i]);
2141		}
2142
2143		// hide dropdowns when clicking outside navigation
2144		if(this.isTouchDevice || this.isPointerDevice) {
2145			lib.event.add(document.documentElement, 'mousedown', lib.bind(this.clickOutsideHandler, this));
2146			lib.event.add(document.documentElement, touchEvent, lib.bind(this.clickOutsideHandler, this));
2147		}
2148	},
2149	mousedownHandler: function(e) {
2150		if(this.touchFlag) {
2151			e.preventDefault();
2152			this.touchFlag = false;
2153			this.preventCurrentClick = false;
2154		}
2155	},
2156	mouseoverHandler: function() {
2157		lib.addClass(this.currentItem, this.options.hoverClass);
2158		jQuery(this.currentItem).trigger('itemhover');
2159	},
2160	mouseoutHandler: function() {
2161		lib.removeClass(this.currentItem, this.options.hoverClass);
2162		jQuery(this.currentItem).trigger('itemleave');
2163	},
2164	hideActiveDropdown: function() {
2165		for(var i = 0; i < this.menuItems.length; i++) {
2166			if(lib.hasClass(this.menuItems[i], this.options.hoverClass)) {
2167				lib.removeClass(this.menuItems[i], this.options.hoverClass);
2168				jQuery(this.menuItems[i]).trigger('itemleave');
2169			}
2170		}
2171		this.activeParent = null;
2172	},
2173	pressHandler: function(e) {
2174		// hide previous drop (if active)
2175		if(this.currentItem !== this.activeParent) {
2176			if(this.activeParent && this.currentItem.parentNode === this.activeParent.parentNode) {
2177				lib.removeClass(this.activeParent, this.options.hoverClass);
2178			} else if(!this.isParent(this.activeParent, this.currentLink)) {
2179				this.hideActiveDropdown();
2180			}
2181		}
2182		// handle current drop
2183		this.activeParent = this.currentItem;
2184		if(lib.hasClass(this.currentItem, this.options.hoverClass)) {
2185			this.preventCurrentClick = false;
2186		} else {
2187			e.preventDefault();
2188			this.preventCurrentClick = true;
2189			lib.addClass(this.currentItem, this.options.hoverClass);
2190			jQuery(this.currentItem).trigger('itemhover');
2191		}
2192	},
2193	clickHandler: function(e) {
2194		// prevent first click on link
2195		if(this.preventCurrentClick) {
2196			e.preventDefault();
2197		}
2198	},
2199	clickOutsideHandler: function(event) {
2200		var e = event.changedTouches ? event.changedTouches[0] : event;
2201		if(this.activeParent && !this.isParent(this.menu, e.target)) {
2202			this.hideActiveDropdown();
2203			this.touchFlag = false;
2204		}
2205	},
2206	isParent: function(parent, child) {
2207		while(child.parentNode) {
2208			if(child.parentNode == parent) {
2209				return true;
2210			}
2211			child = child.parentNode;
2212		}
2213		return false;
2214	},
2215	isTouchPointerEvent: function(e) {
2216		return (e.type.indexOf('touch') > -1) ||
2217		(navigator.pointerEnabled && e.pointerType === 'touch') ||
2218		(navigator.msPointerEnabled && e.pointerType == e.MSPOINTER_TYPE_TOUCH);
2219	},
2220	isPointerDevice: (function() {
2221		return !!(navigator.pointerEnabled || navigator.msPointerEnabled);
2222	}()),
2223	isTouchDevice: (function() {
2224		return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
2225	}())
2226};
2227
2228/*
2229 * Utility module
2230 */
2231 lib = {
2232 	hasClass: function(el,cls) {
2233 		return el && el.className ? el.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')) : false;
2234 	},
2235 	addClass: function(el,cls) {
2236 		if (el && !this.hasClass(el,cls)) el.className += " "+cls;
2237 	},
2238 	removeClass: function(el,cls) {
2239 		if (el && this.hasClass(el,cls)) {el.className=el.className.replace(new RegExp('(\\s|^)'+cls+'(\\s|$)'),' ');}
2240 	},
2241 	extend: function(obj) {
2242 		for(var i = 1; i < arguments.length; i++) {
2243 			for(var p in arguments[i]) {
2244 				if(arguments[i].hasOwnProperty(p)) {
2245 					obj[p] = arguments[i][p];
2246 				}
2247 			}
2248 		}
2249 		return obj;
2250 	},
2251 	each: function(obj, callback) {
2252 		var property, len;
2253 		if(typeof obj.length === 'number') {
2254 			for(property = 0, len = obj.length; property < len; property++) {
2255 				if(callback.call(obj[property], property, obj[property]) === false) {
2256 					break;
2257 				}
2258 			}
2259 		} else {
2260 			for(property in obj) {
2261 				if(obj.hasOwnProperty(property)) {
2262 					if(callback.call(obj[property], property, obj[property]) === false) {
2263 						break;
2264 					}
2265 				}
2266 			}
2267 		}
2268 	},
2269 	event: (function() {
2270 		var fixEvent = function(e) {
2271 			e = e || window.event;
2272 			if(e.isFixed) return e; else e.isFixed = true;
2273 			if(!e.target) e.target = e.srcElement;
2274 			e.preventDefault = e.preventDefault || function() {this.returnValue = false;};
2275 			e.stopPropagation = e.stopPropagation || function() {this.cancelBubble = true;};
2276 			return e;
2277 		};
2278 		return {
2279 			add: function(elem, event, handler) {
2280 				if(!elem.events) {
2281 					elem.events = {};
2282 					elem.handle = function(e) {
2283 						var ret, handlers = elem.events[e.type];
2284 						e = fixEvent(e);
2285 						for(var i = 0, len = handlers.length; i < len; i++) {
2286 							if(handlers[i]) {
2287 								ret = handlers[i].call(elem, e);
2288 								if(ret === false) {
2289 									e.preventDefault();
2290 									e.stopPropagation();
2291 								}
2292 							}
2293 						}
2294 					};
2295 				}
2296 				if(!elem.events[event]) {
2297 					elem.events[event] = [];
2298 					if(elem.addEventListener) elem.addEventListener(event, elem.handle, false);
2299 					else if(elem.attachEvent) elem.attachEvent('on'+event, elem.handle);
2300 				}
2301 				elem.events[event].push(handler);
2302 			},
2303 			remove: function(elem, event, handler) {
2304 				var handlers = elem.events[event];
2305 				for(var i = handlers.length - 1; i >= 0; i--) {
2306 					if(handlers[i] === handler) {
2307 						handlers.splice(i,1);
2308 					}
2309 				}
2310 				if(!handlers.length) {
2311 					delete elem.events[event];
2312 					if(elem.removeEventListener) elem.removeEventListener(event, elem.handle, false);
2313 					else if(elem.detachEvent) elem.detachEvent('on'+event, elem.handle);
2314 				}
2315 			}
2316 		};
2317 	}()),
2318 	queryElementsBySelector: function(selector, scope) {
2319 		scope = scope || document;
2320 		if(!selector) return [];
2321 		if(selector === '>*') return scope.children;
2322 		if(typeof document.querySelectorAll === 'function') {
2323 			return scope.querySelectorAll(selector);
2324 		}
2325 		var selectors = selector.split(',');
2326 		var resultList = [];
2327 		for(var s = 0; s < selectors.length; s++) {
2328 			var currentContext = [scope || document];
2329 			var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' ');
2330 			for (var i = 0; i < tokens.length; i++) {
2331 				token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
2332 				if (token.indexOf('#') > -1) {
2333 					var bits = token.split('#'), tagName = bits[0], id = bits[1];
2334 					var element = document.getElementById(id);
2335 					if (element && tagName && element.nodeName.toLowerCase() != tagName) {
2336 						return [];
2337 					}
2338 					currentContext = element ? [element] : [];
2339 					continue;
2340 				}
2341 				if (token.indexOf('.') > -1) {
2342 					var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0;
2343 					for (var h = 0; h < currentContext.length; h++) {
2344 						var elements;
2345 						if (tagName == '*') {
2346 							elements = currentContext[h].getElementsByTagName('*');
2347 						} else {
2348 							elements = currentContext[h].getElementsByTagName(tagName);
2349 						}
2350 						for (var j = 0; j < elements.length; j++) {
2351 							found[foundCount++] = elements[j];
2352 						}
2353 					}
2354 					currentContext = [];
2355 					var currentContextIndex = 0;
2356 					for (var k = 0; k < found.length; k++) {
2357 						if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) {
2358 							currentContext[currentContextIndex++] = found[k];
2359 						}
2360 					}
2361 					continue;
2362 				}
2363 				if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
2364 					var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4;
2365 					if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) {
2366 						attrName = 'htmlFor';
2367 					}
2368 					var found = [], foundCount = 0;
2369 					for (var h = 0; h < currentContext.length; h++) {
2370 						var elements;
2371 						if (tagName == '*') {
2372 							elements = currentContext[h].getElementsByTagName('*');
2373 						} else {
2374 							elements = currentContext[h].getElementsByTagName(tagName);
2375 						}
2376 						for (var j = 0; elements[j]; j++) {
2377 							found[foundCount++] = elements[j];
2378 						}
2379 					}
2380 					currentContext = [];
2381 					var currentContextIndex = 0, checkFunction;
2382 					switch (attrOperator) {
2383 						case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break;
2384 						case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break;
2385 						case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break;
2386 						case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break;
2387 						case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break;
2388 						case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break;
2389 						default : checkFunction = function(e) { return e.getAttribute(attrName) };
2390 					}
2391 					currentContext = [];
2392 					var currentContextIndex = 0;
2393 					for (var k = 0; k < found.length; k++) {
2394 						if (checkFunction(found[k])) {
2395 							currentContext[currentContextIndex++] = found[k];
2396 						}
2397 					}
2398 					continue;
2399 				}
2400 				tagName = token;
2401 				var found = [], foundCount = 0;
2402 				for (var h = 0; h < currentContext.length; h++) {
2403 					var elements = currentContext[h].getElementsByTagName(tagName);
2404 					for (var j = 0; j < elements.length; j++) {
2405 						found[foundCount++] = elements[j];
2406 					}
2407 				}
2408 				currentContext = found;
2409 			}
2410 			resultList = [].concat(resultList,currentContext);
2411 		}
2412 		return resultList;
2413 	},
2414 	trim: function (str) {
2415 		return str.replace(/^\s+/, '').replace(/\s+$/, '');
2416 	},
2417 	bind: function(f, scope, forceArgs){
2418 		return function() {return f.apply(scope, typeof forceArgs !== 'undefined' ? [forceArgs] : arguments);};
2419 	}
2420 };
2421
2422 /*
2423 * jQuery retina cover plugin
2424 */
2425 ;(function($) {
2426 	'use strict';
2427
2428 	var styleRules = {};
2429 	var templates = {
2430 		'2x': [
2431 		'(-webkit-min-device-pixel-ratio: 1.5)',
2432 		'(min-resolution: 192dpi)',
2433 		'(min-device-pixel-ratio: 1.5)',
2434 		'(min-resolution: 1.5dppx)'
2435 		],
2436 		'3x': [
2437 		'(-webkit-min-device-pixel-ratio: 3)',
2438 		'(min-resolution: 384dpi)',
2439 		'(min-device-pixel-ratio: 3)',
2440 		'(min-resolution: 3dppx)'
2441 		]
2442 	};
2443
2444 	function addSimple(imageSrc, media, id) {
2445 		var style = buildRule(id, imageSrc);
2446
2447 		addRule(media, style);
2448 	}
2449
2450 	function addRetina(imageData, media, id) {
2451 		var currentRules = templates[imageData[1]].slice();
2452 		var patchedRules = currentRules;
2453 		var style = buildRule(id, imageData[0]);
2454
2455 		if (media !== 'default') {
2456 			patchedRules = $.map(currentRules, function(ele, i) {
2457 				return ele + ' and ' + media;
2458 			});
2459 		}
2460
2461 		media = patchedRules.join(',');
2462
2463 		addRule(media, style);
2464 	}
2465
2466 	function buildRule(id, src) {
2467 		return '#' + id + '{background-image: url("' + src + '");}';
2468 	}
2469
2470 	function addRule(media, rule) {
2471 		var $styleTag = styleRules[media];
2472 		var styleTagData;
2473 		var rules = '';
2474
2475 		if (media === 'default') {
2476 			rules = rule + ' ';
2477 		} else {
2478 			rules = '@media ' + media + '{' + rule + '}';
2479 		}
2480
2481 		if (!$styleTag) {
2482 			styleRules[media] = $('<style>').text(rules).appendTo('head');
2483 		} else {
2484 			styleTagData = $styleTag.text();
2485 			styleTagData = styleTagData.substring(0, styleTagData.length - 2) + ' }' + rule + '}';
2486 			$styleTag.text(styleTagData);
2487 		}
2488 	}
2489
2490 	$.fn.retinaCover = function() {
2491 		return this.each(function() {
2492 			var $block = $(this);
2493 			var $items = $block.children('[data-srcset]');
2494 			var id = 'bg-stretch' + Date.now() + (Math.random() * 1000).toFixed(0);
2495
2496 			if ($items.length) {
2497 				$block.attr('id', id);
2498
2499 				$items.each(function() {
2500 					var $item = $(this);
2501 					var data = $item.data('srcset').split(', ');
2502 					var media = $item.data('media') || 'default';
2503 					var dataLength = data.length;
2504 					var itemData;
2505 					var i;
2506
2507 					for (i = 0; i < dataLength; i++) {
2508 						itemData = data[i].split(' ');
2509
2510 						if (itemData.length === 1) {
2511 							addSimple(itemData[0], media, id);
2512 						} else {
2513 							addRetina(itemData, media, id);
2514 						}
2515 					}
2516 				});
2517 			}
2518
2519 			$items.detach();
2520 		});
2521 	};
2522 }(jQuery));
2523
2524/*! Picturefill - v3.0.1 - 2015-09-30
2525 * http://scottjehl.github.io/picturefill
2526 * Copyright (c) 2015 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; Licensed MIT
2527 */
2528 !function(a){var b=navigator.userAgent;a.HTMLPictureElement&&/ecko/.test(b)&&b.match(/rv\:(\d+)/)&&RegExp.$1<41&&addEventListener("resize",function(){var b,c=document.createElement("source"),d=function(a){var b,d,e=a.parentNode;
vendor: 4,515 bytes, line 2528
2528"PICTURE"===e.nodeName.toUpperCase()?(b=c.cloneNode(),e.insertBefore(b,e.firstElementChild),setTimeout(function(){e.removeChild(b)})):(!a._pfLastSize||a.offsetWidth>a._pfLastSize)&&(a._pfLastSize=a.offsetWidth,d=a.sizes,a.sizes+=",100vw",setTimeout(function(){a.sizes=d}))},e=function(){var a,b=document.querySelectorAll("picture > img, img[srcset][sizes]");for(a=0;a<b.length;a++)d(b[a])},f=function(){clearTimeout(b),b=setTimeout(e,99)},g=a.matchMedia&&matchMedia("(orientation: landscape)"),h=function(){f(),g&&g.addListener&&g.addListener(f)};return c.srcset="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",/^[c|i]|d$/.test(document.readyState||"")?h():document.addEventListener("DOMContentLoaded",h),f}())}(window),function(a,b,c){"use strict";function d(a){return" "===a||"	"===a||"\n"===a||"\f"===a||"\r"===a}function e(b,c){var d=new a.Image;return d.onerror=function(){z[b]=!1,aa()},d.onload=function(){z[b]=1===d.width,aa()},d.src=c,"pending"}function f(){L=!1,O=a.devicePixelRatio,M={},N={},s.DPR=O||1,P.width=Math.max(a.innerWidth||0,y.clientWidth),P.height=Math.max(a.innerHeight||0,y.clientHeight),P.vw=P.width/100,P.vh=P.height/100,r=[P.height,P.width,O].join("-"),P.em=s.getEmValue(),P.rem=P.em}function g(a,b,c,d){var e,f,g,h;return"saveData"===A.algorithm?a>2.7?h=c+1:(f=b-c,e=Math.pow(a-.6,1.5),g=f*e,d&&(g+=.1*e),h=a+g):h=c>1?Math.sqrt(a*b):a,h>c}function h(a){var b,c=s.getSet(a),d=!1;"pending"!==c&&(d=r,c&&(b=s.setRes(c),s.applySetCandidate(b,a))),a[s.ns].evaled=d}function i(a,b){return a.res-b.res}function j(a,b,c){var d;return!c&&b&&(c=a[s.ns].sets,c=c&&c[c.length-1]),d=k(b,c),d&&(b=s.makeUrl(b),a[s.ns].curSrc=b,a[s.ns].curCan=d,d.res||_(d,d.set.sizes)),d}function k(a,b){var c,d,e;if(a&&b)for(e=s.parseSet(b),a=s.makeUrl(a),c=0;c<e.length;c++)if(a===s.makeUrl(e[c].url)){d=e[c];break}return d}function l(a,b){var c,d,e,f,g=a.getElementsByTagName("source");for(c=0,d=g.length;d>c;c++)e=g[c],e[s.ns]=!0,f=e.getAttribute("srcset"),f&&b.push({srcset:f,media:e.getAttribute("media"),type:e.getAttribute("type"),sizes:e.getAttribute("sizes")})}function m(a,b){function c(b){var c,d=b.exec(a.substring(m));return d?(c=d[0],m+=c.length,c):void 0}function e(){var a,c,d,e,f,i,j,k,l,m=!1,o={};for(e=0;e<h.length;e++)f=h[e],i=f[f.length-1],j=f.substring(0,f.length-1),k=parseInt(j,10),l=parseFloat(j),W.test(j)&&"w"===i?((a||c)&&(m=!0),0===k?m=!0:a=k):X.test(j)&&"x"===i?((a||c||d)&&(m=!0),0>l?m=!0:c=l):W.test(j)&&"h"===i?((d||c)&&(m=!0),0===k?m=!0:d=k):m=!0;m||(o.url=g,a&&(o.w=a),c&&(o.d=c),d&&(o.h=d),d||c||a||(o.d=1),1===o.d&&(b.has1x=!0),o.set=b,n.push(o))}function f(){for(c(S),i="",j="in descriptor";;){if(k=a.charAt(m),"in descriptor"===j)if(d(k))i&&(h.push(i),i="",j="after descriptor");else{if(","===k)return m+=1,i&&h.push(i),void e();if("("===k)i+=k,j="in parens";else{if(""===k)return i&&h.push(i),void e();i+=k}}else if("in parens"===j)if(")"===k)i+=k,j="in descriptor";else{if(""===k)return h.push(i),void e();i+=k}else if("after descriptor"===j)if(d(k));else{if(""===k)return void e();j="in descriptor",m-=1}m+=1}}for(var g,h,i,j,k,l=a.length,m=0,n=[];;){if(c(T),m>=l)return n;g=c(U),h=[],","===g.slice(-1)?(g=g.replace(V,""),e()):f()}}function n(a){function b(a){function b(){f&&(g.push(f),f="")}function c(){g[0]&&(h.push(g),g=[])}for(var e,f="",g=[],h=[],i=0,j=0,k=!1;;){if(e=a.charAt(j),""===e)return b(),c(),h;if(k){if("*"===e&&"/"===a[j+1]){k=!1,j+=2,b();continue}j+=1}else{if(d(e)){if(a.charAt(j-1)&&d(a.charAt(j-1))||!f){j+=1;continue}if(0===i){b(),j+=1;continue}e=" "}else if("("===e)i+=1;else if(")"===e)i-=1;else{if(","===e){b(),c(),j+=1;continue}if("/"===e&&"*"===a.charAt(j+1)){k=!0,j+=2;continue}}f+=e,j+=1}}}function c(a){return k.test(a)&&parseFloat(a)>=0?!0:l.test(a)?!0:"0"===a||"-0"===a||"+0"===a?!0:!1}var e,f,g,h,i,j,k=/^(?:[+-]?[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?(?:ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmin|vmax|vw)$/i,l=/^calc\((?:[0-9a-z \.\+\-\*\/\(\)]+)\)$/i;for(f=b(a),g=f.length,e=0;g>e;e++)if(h=f[e],i=h[h.length-1],c(i)){if(j=i,h.pop(),0===h.length)return j;if(h=h.join(" "),s.matchesMedia(h))return j}return"100vw"}b.createElement("picture");var o,p,q,r,s={},t=function(){},u=b.createElement("img"),v=u.getAttribute,w=u.setAttribute,x=u.removeAttribute,y=b.documentElement,z={},A={algorithm:""},B="data-pfsrc",C=B+"set",D=navigator.userAgent,E=/rident/.test(D)||/ecko/.test(D)&&D.match(/rv\:(\d+)/)&&RegExp.$1>35,F="currentSrc",G=/\s+\+?\d+(e\d+)?w/,H=/(\([^)]+\))?\s*(.+)/,I=a.picturefillCFG,J="position:absolute;
2528left:0;visibility:hidden;display:block;padding:0;border:none;font-size:1em;width:1em;overflow:hidden;clip:rect(0px, 0px, 0px, 0px)",K="font-size:100%!important;",L=!0,M={},N={},O=a.devicePixelRatio,P={px:1,"in":96},Q=b.createElement("a"),R=!1,S=/^[ \t\n\r\u000c]+/,T=/^[, \t\n\r\u000c]+/,U=/^[^ \t\n\r\u000c]+/,V=/[,]+$/,W=/^\d+$/,X=/^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/,Y=function(a,b,c,d){a.addEventListener?a.addEventListener(b,c,d||!1):a.attachEvent&&a.attachEvent("on"+b,c)},Z=function(a){var b={};return function(c){return c in b||(b[c]=a(c)),b[c]}},$=function(){var a=/^([\d\.]+)(em|vw|px)$/,b=function(){for(var a=arguments,b=0,c=a[0];++b in a;)c=c.replace(a[b],a[++b]);return c},c=Z(function(a){return"return "+b((a||"").toLowerCase(),/\band\b/g,"&&",/,/g,"||",/min-([a-z-\s]+):/g,"e.$1>=",/max-([a-z-\s]+):/g,"e.$1<=",/calc([^)]+)/g,"($1)",/(\d+[\.]*[\d]*)([a-z]+)/g,"($1 * e.$2)",/^(?!(e.[a-z]|[0-9\.&=|><\+\-\*\(\)\/])).*/gi,"")+";"});return function(b,d){var e;if(!(b in M))if(M[b]=!1,d&&(e=b.match(a)))M[b]=e[1]*P[e[2]];else try{M[b]=new Function("e",c(b))(P)}catch(f){}return M[b]}}(),_=function(a,b){return a.w?(a.cWidth=s.calcListLength(b||"100vw"),a.res=a.w/a.cWidth):a.res=a.d,a},aa=function(a){var c,d,e,f=a||{};if(f.elements&&1===f.elements.nodeType&&("IMG"===f.elements.nodeName.toUpperCase()?f.elements=[f.elements]:(f.context=f.elements,f.elements=null)),c=f.elements||s.qsa(f.context||b,f.reevaluate||f.reselect?s.sel:s.selShort),e=c.length){for(s.setupRun(f),R=!0,d=0;e>d;d++)s.fillImg(c[d],f);s.teardownRun(f)}};o=a.console&&console.warn?function(a){console.warn(a)}:t,F in u||(F="src"),z["image/jpeg"]=!0,z["image/gif"]=!0,z["image/png"]=!0,z["image/svg+xml"]=b.implementation.hasFeature("http://wwwindow.w3.org/TR/SVG11/feature#Image","1.1"),s.ns=("pf"+(new Date).getTime()).substr(0,9),s.supSrcset="srcset"in u,s.supSizes="sizes"in u,s.supPicture=!!a.HTMLPictureElement,s.supSrcset&&s.supPicture&&!s.supSizes&&!function(a){u.srcset="data:,a",a.src="data:,a",s.supSrcset=u.complete===a.complete,s.supPicture=s.supSrcset&&s.supPicture}(b.createElement("img")),s.selShort="picture>img,img[srcset]",s.sel=s.selShort,s.cfg=A,s.supSrcset&&(s.sel+=",img["+C+"]"),s.DPR=O||1,s.u=P,s.types=z,q=s.supSrcset&&!s.supSizes,s.setSize=t,s.makeUrl=Z(function(a){return Q.href=a,Q.href}),s.qsa=function(a,b){return a.querySelectorAll(b)},s.matchesMedia=function(){return a.matchMedia&&(matchMedia("(min-width: 0.1em)")||{}).matches?s.matchesMedia=function(a){return!a||matchMedia(a).matches}:s.matchesMedia=s.mMQ,s.matchesMedia.apply(this,arguments)},s.mMQ=function(a){return a?$(a):!0},s.calcLength=function(a){var b=$(a,!0)||!1;return 0>b&&(b=!1),b},s.supportsType=function(a){return a?z[a]:!0},s.parseSize=Z(function(a){var b=(a||"").match(H);return{media:b&&b[1],length:b&&b[2]}}),s.parseSet=function(a){return a.cands||(a.cands=m(a.srcset,a)),a.cands},s.getEmValue=function(){var a;if(!p&&(a=b.body)){var c=b.createElement("div"),d=y.style.cssText,e=a.style.cssText;c.style.cssText=J,y.style.cssText=K,a.style.cssText=K,a.appendChild(c),p=c.offsetWidth,a.removeChild(c),p=parseFloat(p,10),y.style.cssText=d,a.style.cssText=e}return p||16},s.calcListLength=function(a){if(!(a in N)||A.uT){var b=s.calcLength(n(a));N[a]=b?b:P.width}return N[a]},s.setRes=function(a){var b;if(a){b=s.parseSet(a);for(var c=0,d=b.length;d>c;c++)_(b[c],a.sizes)}return b},s.setRes.res=_,s.applySetCandidate=function(a,b){if(a.length){var c,d,e,f,h,k,l,m,n,o=b[s.ns],p=s.DPR;if(k=o.curSrc||b[F],l=o.curCan||j(b,k,a[0].set),l&&l.set===a[0].set&&(n=E&&!b.complete&&l.res-.1>p,n||(l.cached=!0,l.res>=p&&(h=l))),!h)for(a.sort(i),f=a.length,h=a[f-1],d=0;f>d;d++)if(c=a[d],c.res>=p){e=d-1,h=a[e]&&(n||k!==s.makeUrl(c.url))&&g(a[e].res,c.res,p,a[e].cached)?a[e]:c;break}h&&(m=s.makeUrl(h.url),o.curSrc=m,o.curCan=h,m!==k&&s.setSrc(b,h),s.setSize(b))}},s.setSrc=function(a,b){var c;a.src=b.url,"image/svg+xml"===b.set.type&&(c=a.style.width,a.style.width=a.offsetWidth+1+"px",a.offsetWidth+1&&(a.style.width=c))},s.getSet=function(a){var b,c,d,e=!1,f=a[s.ns].sets;for(b=0;b<f.length&&!e;b++)if(c=f[b],c.srcset&&s.matchesMedia(c.media)&&(d=s.supportsType(c.type))){"pending"===d&&(c=d),e=c;break}return e},s.parseSets=function(a,b,d){var e,f,g,h,i=b&&"PICTURE"===b.nodeName.toUpperCase(),j=a[s.ns];(j.src===c||d.src)&&(j.src=v.call(a,"src"),j.src?w.call(a,B,j.src):x.call(a,B)),(j.srcset===c||d.srcset||!s.supSrcset||a.srcset)&&(e=v.call(a,"srcset"),j.srcset=e,h=!0),j.sets=[],i&&(j.pic=!0,l(b,j.set
vendor: 2,198 bytes, lines 2528-2534
2528s)),j.srcset?(f={srcset:j.srcset,sizes:v.call(a,"sizes")},j.sets.push(f),g=(q||j.src)&&G.test(j.srcset||""),g||!j.src||k(j.src,f)||f.has1x||(f.srcset+=", "+j.src,f.cands.push({url:j.src,d:1,set:f}))):j.src&&j.sets.push({srcset:j.src,sizes:null}),j.curCan=null,j.curSrc=c,j.supported=!(i||f&&!s.supSrcset||g),h&&s.supSrcset&&!j.supported&&(e?(w.call(a,C,e),a.srcset=""):x.call(a,C)),j.supported&&!j.srcset&&(!j.src&&a.src||a.src!==s.makeUrl(j.src))&&(null===j.src?a.removeAttribute("src"):a.src=j.src),j.parsed=!0},s.fillImg=function(a,b){var c,d=b.reselect||b.reevaluate;a[s.ns]||(a[s.ns]={}),c=a[s.ns],(d||c.evaled!==r)&&((!c.parsed||b.reevaluate)&&s.parseSets(a,a.parentNode,b),c.supported?c.evaled=r:h(a))},s.setupRun=function(){(!R||L||O!==a.devicePixelRatio)&&f()},s.supPicture?(aa=t,s.fillImg=t):!function(){var c,d=a.attachEvent?/d$|^c/:/d$|^c|^i/,e=function(){var a=b.readyState||"";f=setTimeout(e,"loading"===a?200:999),b.body&&(s.fillImgs(),c=c||d.test(a),c&&clearTimeout(f))},f=setTimeout(e,b.body?9:99),g=function(a,b){var c,d,e=function(){var f=new Date-d;b>f?c=setTimeout(e,b-f):(c=null,a())};return function(){d=new Date,c||(c=setTimeout(e,b))}},h=y.clientHeight,i=function(){L=Math.max(a.innerWidth||0,y.clientWidth)!==P.width||y.clientHeight!==h,h=y.clientHeight,L&&s.fillImgs()};Y(a,"resize",g(i,99)),Y(b,"readystatechange",e)}(),s.picturefill=aa,s.fillImgs=aa,s.teardownRun=t,aa._=s,a.picturefillCFG={pf:s,push:function(a){var b=a.shift();"function"==typeof s[b]?s[b].apply(s,a):(A[b]=a[0],R&&s.fillImgs({reselect:!0}))}};for(;I&&I.length;)a.picturefillCFG.push(I.shift());a.picturefill=aa,"object"==typeof module&&"object"==typeof module.exports?module.exports=aa:"function"==typeof define&&define.amd&&define("picturefill",function(){return aa}),s.supPicture||(z["image/webp"]=e("image/webp","data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA=="))}(window,document);
2529
2530 if(!('backgroundBlendMode' in document.body.style)) {
2531    // No support for background-blend-mode
2532    var html = document.getElementsByTagName("html")[0];
2533    html.className = html.className + " no-background-blend-mode";
2534}

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.