/* ========================================================================
 * Bootstrap: scrollspy.js v3.3.2
 * http://getbootstrap.com/javascript/#scrollspy
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
	'use strict';

	// SCROLLSPY CLASS DEFINITION
	// ==========================

	function ScrollSpy(element, options) {
		var process  = $.proxy(this.process, this);

		this.$body          = $('body');
		this.$scrollElement = $(element).is('body') ? $(window) : $(element);
		this.options        = $.extend({}, ScrollSpy.DEFAULTS, options);
		this.selector       = (this.options.target || '') + ' li > a';
		this.offsets        = [];
		this.targets        = [];
		this.activeTarget   = null;
		this.scrollHeight   = 0;

		this.$scrollElement.on('scroll.bs.scrollspy', process);
		this.refresh();
		this.process();
	}

	ScrollSpy.VERSION  = '3.3.2';

	ScrollSpy.DEFAULTS = {
		offset: 10
	};

	ScrollSpy.prototype.getScrollHeight = function () {
		return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight);
	};

	ScrollSpy.prototype.refresh = function () {
		var offsetMethod = 'offset';
		var offsetBase   = 0;

		if (!$.isWindow(this.$scrollElement[0])) {
			offsetMethod = 'position';
			offsetBase   = this.$scrollElement.scrollTop();
		};

		this.offsets = [];
		this.targets = [];
		this.scrollHeight = this.getScrollHeight();

		var self     = this;

		this.$body
			.find(this.selector)
			.map(function () {
				var $el   = $(this);
				var href  = $el.data('target') || $el.attr('href');
				var $href = /^#./.test(href) && $(href);

				return ($href
					&& $href.length
					&& $href.is(':visible')
					&& [[$href[offsetMethod]().top + offsetBase, href]]) || null;
			})
			.sort(function (a, b) { return a[0] - b[0]; })
			.each(function () {
				self.offsets.push(this[0]);
				self.targets.push(this[1]);
			});
	};

	ScrollSpy.prototype.process = function () {
		var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset;
		var scrollHeight = this.getScrollHeight();
		var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height();
		var offsets      = this.offsets;
		var targets      = this.targets;
		var activeTarget = this.activeTarget;
		var i;

		if (this.scrollHeight != scrollHeight) {
			this.refresh();
		};

		if (scrollTop >= maxScroll) {
			return activeTarget != (i = targets[targets.length - 1]) && this.activate(i);
		};

		if (activeTarget && scrollTop < offsets[0]) {
			this.activeTarget = null;
			return this.clear();
		};

		for (i = offsets.length; i--;) {
			activeTarget != targets[i]
				&& scrollTop >= offsets[i]
				&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
				&& this.activate(targets[i]);
		};
	};

	ScrollSpy.prototype.activate = function (target) {
		this.activeTarget = target;

		this.clear();

	// ThemeFusion edit for Avada theme: added the full url anchors to the selector to make sure highlighting works correctly
	var $current_href = window.location.href.split( '#' ),
		$current_path = ( $current_href[0].charAt( $current_href[0].length - 1 ) == '/' ) ? $current_href[0] : $current_href[0] + '/';

	var selector = this.selector +
		'[data-target="' + target + '"],' +
		this.selector + '[href="' + target + '"],' +
		this.selector + '[href="' + $current_path + target + '"]';

	var active = $(selector)
		.parents('li')
		.addClass('current-menu-item');

	if (active.parent('.sub-menu').length) {
		active = active
		.closest('li.fusion-dropdown-menu')
		.addClass('current-menu-item');
	};

		active.trigger('activate.bs.scrollspy');
	};

	ScrollSpy.prototype.clear = function () {
		$(this.selector)
			.parentsUntil(this.options.target, '.current-menu-item')
			.removeClass('current-menu-item');

	$(this.selector).parentsUntil(this.options.target, '.current-menu-parent').removeClass( 'current-menu-parent' );

	};


	// SCROLLSPY PLUGIN DEFINITION
	// ===========================

	function Plugin(option) {
		return this.each(function () {
			var $this   = $(this);
			var data    = $this.data('bs.scrollspy');
			var options = typeof option == 'object' && option;

			if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)));
			if (typeof option == 'string') data[option]();
		});
	};

	var old = $.fn.scrollspy;

	$.fn.scrollspy             = Plugin;
	$.fn.scrollspy.Constructor = ScrollSpy;


	// SCROLLSPY NO CONFLICT
	// =====================

	$.fn.scrollspy.noConflict = function () {
		$.fn.scrollspy = old;
		return this;
	};


	// SCROLLSPY DATA-API
	// ==================

	$(window).on('load.bs.scrollspy.data-api', function () {
		$('[data-spy="scroll"]').each(function () {
			var $spy = $(this);
			Plugin.call($spy, $spy.data());
		});
	});

}(jQuery);

/* ========================================================================
 * Bootstrap: transition.js v3.3.6
 * http://getbootstrap.com/javascript/#transitions
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */

+function ($) {
  'use strict';

  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  // ============================================================

  function transitionEnd() {
    var el = document.createElement('bootstrap');

    var transEndEventNames = {
      WebkitTransition : 'webkitTransitionEnd',
      MozTransition    : 'transitionend',
      OTransition      : 'oTransitionEnd otransitionend',
      transition       : 'transitionend'
    };

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return { end: transEndEventNames[name] };
      }
    }

    return false; // explicit for ie8 (  ._.)
  }

  // http://blog.alexmaccaw.com/css-transitions
  $.fn.emulateTransitionEnd = function (duration) {
    var called = false;
    var $el = this;
    $(this).one('bsTransitionEnd', function () { called = true });
    var callback = function () { if (!called) $($el).trigger($.support.transition.end) };
    setTimeout(callback, duration);
    return this;
  };

  $(function () {
    $.support.transition = transitionEnd();

    if (!$.support.transition) return;

    $.event.special.bsTransitionEnd = {
      bindType: $.support.transition.end,
      delegateType: $.support.transition.end,
      handle: function (e) {
        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments);
      }
    };
  });

}(jQuery);

/* ========================================================================
 * Bootstrap: collapse.js v3.1.1
 * http://getbootstrap.com/javascript/#collapse
 * ========================================================================
 * Copyright 2011-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
	'use strict';

	// COLLAPSE PUBLIC CLASS DEFINITION
	// ================================

	var Collapse = function (element, options) {
	this.$element	  = $(element);
	this.options	   = $.extend({}, Collapse.DEFAULTS, options);
	this.transitioning = null;

	if (this.options.parent) this.$parent = $(this.options.parent);
	if (this.options.toggle) this.toggle();
	};

	Collapse.DEFAULTS = {
	toggle: true
	};

	Collapse.prototype.dimension = function () {
	var hasWidth = this.$element.hasClass('width');
	return hasWidth ? 'width' : 'height';
	};

	Collapse.prototype.show = function () {
	if (this.transitioning || this.$element.hasClass('in')) return;

	var startEvent = $.Event('show.bs.collapse');
	this.$element.trigger(startEvent);
	if (startEvent.isDefaultPrevented()) return;

	var actives = this.$parent && this.$parent.find('> .fusion-panel > .in');

	if (actives && actives.length) {
		var hasData = actives.data('bs.collapse');
		if (hasData && hasData.transitioning) return;
		actives.collapse('hide');
		hasData || actives.data('bs.collapse', null)
	}

	var dimension = this.dimension();

	this.$element
		.removeClass('collapse')
		.addClass('collapsing')
		[dimension](0);

	this.transitioning = 1;

	var complete = function () {
		this.$element
		.removeClass('collapsing')
		.addClass('collapse in')
		[dimension]('auto');
		this.transitioning = 0;
		this.$element.trigger('shown.bs.collapse');
	};

	if (!$.support.transition) return complete.call(this);

	var scrollSize = $.camelCase(['scroll', dimension].join('-'));

	this.$element
		.one($.support.transition.end, $.proxy(complete, this))
		.emulateTransitionEnd(350)
		[dimension](this.$element[0][scrollSize]);
	};

	Collapse.prototype.hide = function () {
	if (this.transitioning || !this.$element.hasClass('in')) return;

	var startEvent = $.Event('hide.bs.collapse');
	this.$element.trigger(startEvent);
	if (startEvent.isDefaultPrevented()) return;

	var dimension = this.dimension();

	this.$element
		[dimension](this.$element[dimension]())
		[0].offsetHeight;

	this.$element
		.addClass('collapsing')
		.removeClass('collapse')
		.removeClass('in');

	this.transitioning = 1;

	var complete = function () {
		this.transitioning = 0;
		this.$element
		.trigger('hidden.bs.collapse')
		.removeClass('collapsing')
		.addClass('collapse');
	};

	if (!$.support.transition) return complete.call(this);

	this.$element
		[dimension](0)
		.one($.support.transition.end, $.proxy(complete, this))
		.emulateTransitionEnd(350);
	};

	Collapse.prototype.toggle = function () {
	this[this.$element.hasClass('in') ? 'hide' : 'show']();
	};


	// COLLAPSE PLUGIN DEFINITION
	// ==========================

	var old = $.fn.collapse;

	$.fn.collapse = function (option) {
	return this.each(function () {
		var $this   = $(this);
		var data	= $this.data('bs.collapse');
		var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option);

		if (!data && options.toggle && option == 'show') option = !option;
		if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)));
		if (typeof option == 'string') data[option]();
	})
	};

	$.fn.collapse.Constructor = Collapse;


	// COLLAPSE NO CONFLICT
	// ====================

	$.fn.collapse.noConflict = function () {
	$.fn.collapse = old;
	return this;
	};


	// COLLAPSE DATA-API
	// =================

	$(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
	var $this   = $(this), href;
	var target  = $this.attr('data-target')
		|| e.preventDefault()
		|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, ''); //strip for ie7
	var $target = $(target);
	var data	= $target.data('bs.collapse');
	var option  = data ? 'toggle' : $this.data();
	var parent  = $this.attr('data-parent');
	var $parent = parent && $(parent);

	if (!data || !data.transitioning) {
		if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed');
		$this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed');
	}

	$target.collapse(option);
	});

	jQuery('click.bs.collapse.data-api, [data-toggle=collapse]').each(function() {
		var parent = jQuery(this).attr('data-parent');

	if(jQuery(this).parents('.panel-group').length == 0) {
		var random = Math.floor((Math.random() * 10) + 1);
		var single_panel = jQuery(this).parents('.fusion-panel');
		jQuery(this).attr('data-parent', 'accordian-' + random);
		jQuery(single_panel).wrap('<div class="accordian fusion-accordian fusion-single-accordian"><div class="panel-group" id="accordion-' + random + '"></div></div>');
	}
	});

}(jQuery);


/* ========================================================================
 * Bootstrap: modal.js v3.1.1
 * http://getbootstrap.com/javascript/#modals
 * ========================================================================
 * Copyright 2011-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
	'use strict';

	// MODAL CLASS DEFINITION
	// ======================

	var Modal = function (element, options) {
	this.options   = options;
	this.$element  = $(element);
	this.$backdrop = '';
	this.isShown   = null;

	if (this.options.remote) {
		this.$element
		.find('.modal-content')
		.load(this.options.remote, $.proxy(function () {
			this.$element.trigger('loaded.bs.modal');
		}, this));
	}
	};

	Modal.DEFAULTS = {
	backdrop: true,
	keyboard: true,
	show: true
	};

	Modal.prototype.toggle = function (_relatedTarget) {
	return this[!this.isShown ? 'show' : 'hide'](_relatedTarget);
	};

	Modal.prototype.show = function (_relatedTarget) {
	var that = this;
	var e	= $.Event('show.bs.modal', { relatedTarget: _relatedTarget });

	this.$element.trigger(e);

	if (this.isShown || e.isDefaultPrevented()) return;

	this.isShown = true;

	this.escape();

	this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this));

	this.backdrop(function () {
		var transition = $.support.transition && that.$element.hasClass('fade');

		if (!that.$element.parent().length) {
		that.$element.appendTo(document.body); // don't move modals dom position
		}

		that.$element
		.show()
		.scrollTop(0);

		if (transition) {
		that.$element[0].offsetWidth; // force reflow
		}

		that.$element
		.addClass('in')
		.attr('aria-hidden', false);

		that.enforceFocus();

		var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget });

		transition ?
		that.$element.find('.modal-dialog') // wait for modal to slide in
			.one($.support.transition.end, function () {
			that.$element.focus().trigger(e);
			})
			.emulateTransitionEnd(300) :
		that.$element.focus().trigger(e);
	})
	};

	Modal.prototype.hide = function (e) {
	if (e) e.preventDefault();

	e = $.Event('hide.bs.modal');

	this.$element.trigger(e);

	if (!this.isShown || e.isDefaultPrevented()) return;

	this.isShown = false;

	this.escape();

	$(document).off('focusin.bs.modal');

	this.$element
		.removeClass('in')
		.attr('aria-hidden', true)
		.off('click.dismiss.bs.modal');

	$.support.transition && this.$element.hasClass('fade') ?
		this.$element
		.one($.support.transition.end, $.proxy(this.hideModal, this))
		.emulateTransitionEnd(300) :
		this.hideModal();
	};

	Modal.prototype.enforceFocus = function () {
	$(document)
		.off('focusin.bs.modal') // guard against infinite focus loop
		.on('focusin.bs.modal', $.proxy(function (e) {
		if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
			this.$element.focus();
		}
		}, this));
	};

	Modal.prototype.escape = function () {
	if (this.isShown && this.options.keyboard) {
		this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
		e.which == 27 && this.hide();
		}, this));
	} else if (!this.isShown) {
		this.$element.off('keyup.dismiss.bs.modal');
	}
	};

	Modal.prototype.hideModal = function () {
	var that = this;
	this.$element.hide();
	this.backdrop(function () {
		that.removeBackdrop();
		that.$element.trigger('hidden.bs.modal');
	});
	};

	Modal.prototype.removeBackdrop = function () {
	this.$backdrop && this.$backdrop.remove();
	this.$backdrop = null;
	};

	Modal.prototype.backdrop = function (callback) {
	var animate = this.$element.hasClass('fade') ? 'fade' : '';

	if (this.isShown && this.options.backdrop) {
		var doAnimate = $.support.transition && animate;

		this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
		.appendTo(document.body);

		this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
		if (e.target !== e.currentTarget) return;
		this.options.backdrop == 'static'
			? this.$element[0].focus.call(this.$element[0])
			: this.hide.call(this);
		}, this));

		if (doAnimate) this.$backdrop[0].offsetWidth; // force reflow

		this.$backdrop.addClass('in');

		if (!callback) return;

		doAnimate ?
		this.$backdrop
			.one($.support.transition.end, callback)
			.emulateTransitionEnd(150) :
		callback();

	} else if (!this.isShown && this.$backdrop) {
		this.$backdrop.removeClass('in');

		$.support.transition && this.$element.hasClass('fade') ?
		this.$backdrop
			.one($.support.transition.end, callback)
			.emulateTransitionEnd(150) :
		callback();

	} else if (callback) {
		callback();
	}
	};


	// MODAL PLUGIN DEFINITION
	// =======================

	var old = $.fn.modal;

	$.fn.modal = function (option, _relatedTarget) {
	return this.each(function () {
		var $this   = $(this);
		var data	= $this.data('bs.modal');
		var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option);

		if (!data) $this.data('bs.modal', (data = new Modal(this, options)));
		if (typeof option == 'string') data[option](_relatedTarget);
		else if (options.show) data.show(_relatedTarget);
	});
	};

	$.fn.modal.Constructor = Modal;


	// MODAL NO CONFLICT
	// =================

	$.fn.modal.noConflict = function () {
	$.fn.modal = old;
	return this;
	};


	// MODAL DATA-API
	// ==============

	$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
	var $this   = $(this);
	var href	= $this.attr('href');
	var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))); //strip for ie7
	var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());

	if ($this.is('a')) e.preventDefault();

	$target
		.modal(option, this)
		.one('hide', function () {
		$this.is(':visible') && $this.focus();
		});
	});

	$(document)
	.on('show.bs.modal', '.modal', function () { $(document.body).addClass('modal-open') })
	.on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') });

}(jQuery);

/* ========================================================================
 * Bootstrap: tab.js v3.1.1
 * http://getbootstrap.com/javascript/#tabs
 * ========================================================================
 * Copyright 2011-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
	'use strict';

	// TAB CLASS DEFINITION
	// ====================

	var Tab = function (element) {
	this.element = $(element);
	};

	Tab.prototype.show = function () {
	var $this	= this.element;
	var $ul	  = $this.closest('ul:not(.dropdown-menu)');
	var selector = $this.data('target');

	if (!selector) {
		selector = $this.attr('href');
		selector = selector && selector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7
	}

	if ($this.parent('li').hasClass('active')) return;

	var previous = $ul.find('.active:last a')[0];
	var e		= $.Event('show.bs.tab', {
		relatedTarget: previous
	});

	$this.trigger(e);

	if (e.isDefaultPrevented()) return;

	var $target = $(selector);

	this.activate($this.parent('li'), $ul);

	this.activate($target, $target.parent(), function () {
		$this.trigger({
		type: 'shown.bs.tab',
		relatedTarget: previous
		});
	});
	};

	Tab.prototype.activate = function (element, container, callback) {
		var $active	= container.find('> .active');
		var transition = callback
			&& $.support.transition
			&& $active.hasClass('fade');

		function next() {
			$active
			.removeClass('active')
			.find('> .dropdown-menu > .active')
			.removeClass('active');

			element.addClass('active');

			// ThemeFusion edit for Avada theme: needed for mobile tabs setup
			if ( element.parent( '.nav-tabs' ).length ) {
				element.parents( '.fusion-tabs' ).find( '.nav' ).find( 'a[href="' + element.find( 'a' ).attr( 'href' ) + '"]' ).parent().addClass( 'active' );
			}

			if (transition) {
				element[0].offsetWidth; // reflow for transition
				element.addClass('in');
			} else {
				element.removeClass('fade');
			}

			if (element.parent('.dropdown-menu')) {
				element.closest('li.dropdown').addClass('active');
			}

			callback && callback();
		}

		transition ?
			$active
			.one($.support.transition.end, next)
			.emulateTransitionEnd(150) :
			next();

		$active.removeClass('in');
	};


	// TAB PLUGIN DEFINITION
	// =====================

	var old = $.fn.tab;

	$.fn.tab = function ( option ) {
	return this.each(function () {
		var $this = $(this);
		var data  = $this.data('bs.tab');

		if (!data) $this.data('bs.tab', (data = new Tab(this)));
		if (typeof option == 'string') data[option]();
	});
	};

	$.fn.tab.Constructor = Tab;


	// TAB NO CONFLICT
	// ===============

	$.fn.tab.noConflict = function () {
	$.fn.tab = old;
	return this;
	};


	// TAB DATA-API
	// ============

	$(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
	e.preventDefault();
	$(this).tab('show');
	});

}(jQuery);


/* ========================================================================
 * Bootstrap: tooltip.js v3.3.5
 * http://getbootstrap.com/javascript/#tooltip
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
	'use strict';

	// TOOLTIP PUBLIC CLASS DEFINITION
	// ===============================

	var Tooltip = function (element, options) {
		this.type       = null;
		this.options    = null;
		this.enabled    = null;
		this.timeout    = null;
		this.hoverState = null;
		this.$element   = null;
		this.inState    = null;

		this.init('tooltip', element, options);
	};

	Tooltip.VERSION  = '3.3.5';

	Tooltip.TRANSITION_DURATION = 150;

	Tooltip.DEFAULTS = {
		animation: true,
		placement: 'top',
		selector: false,
		template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
		trigger: 'hover focus',
		title: '',
		delay: 0,
		html: false,
		container: false,
		viewport: {
			selector: 'body',
			padding: 0
		}
	};

	Tooltip.prototype.init = function (type, element, options) {
		this.enabled   = true;
		this.type      = type;
		this.$element  = $(element);
		this.options   = this.getOptions(options);
		this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport));
		this.inState   = { click: false, hover: false, focus: false };

		if (this.$element[0] instanceof document.constructor && !this.options.selector) {
			throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!');
		}

		var triggers = this.options.trigger.split(' ');

		for (var i = triggers.length; i--;) {
			var trigger = triggers[i];

			if (trigger == 'click') {
				this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this));
			} else if (trigger != 'manual') {
				var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin';
				var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout';

				this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this));
				this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this));
			}
		}

		this.options.selector ?
			(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
			this.fixTitle();
	};

	Tooltip.prototype.getDefaults = function () {
		return Tooltip.DEFAULTS;
	};

	Tooltip.prototype.getOptions = function (options) {
		options = $.extend({}, this.getDefaults(), this.$element.data(), options);

		if (options.delay && typeof options.delay == 'number') {
			options.delay = {
				show: options.delay,
				hide: options.delay
			}
		}

		return options;
	};

	Tooltip.prototype.getDelegateOptions = function () {
		var options  = {};
		var defaults = this.getDefaults();

		this._options && $.each(this._options, function (key, value) {
			if (defaults[key] != value) options[key] = value;
		});

		return options;
	};

	Tooltip.prototype.enter = function (obj) {
		var self = obj instanceof this.constructor ?
			obj : $(obj.currentTarget).data('bs.' + this.type);

		if (!self) {
			self = new this.constructor(obj.currentTarget, this.getDelegateOptions());
			$(obj.currentTarget).data('bs.' + this.type, self);
		}

		if (obj instanceof $.Event) {
			self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true;
		}

		if (self.tip().hasClass('in') || self.hoverState == 'in') {
			self.hoverState = 'in';
			return;
		}

		clearTimeout(self.timeout);

		self.hoverState = 'in';

		if (!self.options.delay || !self.options.delay.show) return self.show();

		self.timeout = setTimeout(function () {
			if (self.hoverState == 'in') { self.show(); }
		}, self.options.delay.show);
	};

	Tooltip.prototype.isInStateTrue = function () {
		for (var key in this.inState) {
			if (this.inState[key]) { return true; }
		};

		return false;
	};

	Tooltip.prototype.leave = function (obj) {
		var self = obj instanceof this.constructor ?
			obj : $(obj.currentTarget).data('bs.' + this.type);

		if (!self) {
			self = new this.constructor(obj.currentTarget, this.getDelegateOptions());
			$(obj.currentTarget).data('bs.' + this.type, self);
		}

		if (obj instanceof $.Event) {
			self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false;
		}

		if (self.isInStateTrue()) return;

		clearTimeout(self.timeout);

		self.hoverState = 'out';

		if (!self.options.delay || !self.options.delay.hide) return self.hide();

		self.timeout = setTimeout(function () {
			if (self.hoverState == 'out') self.hide();
		}, self.options.delay.hide);
	};

	Tooltip.prototype.show = function () {
		var e = $.Event('show.bs.' + this.type);

		if (this.hasContent() && this.enabled) {
			this.$element.trigger(e);

			var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]);
			if (e.isDefaultPrevented() || !inDom) return;
			var that = this;

			var $tip = this.tip();

			var tipId = this.getUID(this.type);

			this.setContent();
			$tip.attr('id', tipId);
			this.$element.attr('aria-describedby', tipId);

			if (this.options.animation) $tip.addClass('fade');

			var placement = typeof this.options.placement == 'function' ?
				this.options.placement.call(this, $tip[0], this.$element[0]) :
				this.options.placement;

			var autoToken = /\s?auto?\s?/i;
			var autoPlace = autoToken.test(placement);
			if (autoPlace) placement = placement.replace(autoToken, '') || 'top';

			$tip
				.detach()
				.css({ top: 0, left: 0, display: 'block' })
				.addClass(placement)
				.data('bs.' + this.type, this)
				.addClass(this.$element.data('class')); // ThemeFusion edit for Avada theme

			this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element);
			this.$element.trigger('inserted.bs.' + this.type);

			var pos          = this.getPosition();
			var actualWidth  = $tip[0].offsetWidth;
			var actualHeight = $tip[0].offsetHeight;

			if (autoPlace) {
				var orgPlacement = placement;
				var viewportDim = this.getPosition(this.$viewport);

				placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :
										placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :
										placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :
										placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :
										placement;

				$tip
					.removeClass(orgPlacement)
					.addClass(placement);
			}

			var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight);

			this.applyPlacement(calculatedOffset, placement);

			var complete = function () {
				var prevHoverState = that.hoverState;
				that.$element.trigger('shown.bs.' + that.type);
				that.hoverState = null;

				if (prevHoverState == 'out') that.leave(that);
			};

			$.support.transition && this.$tip.hasClass('fade') ?
				$tip
					.one('bsTransitionEnd', complete)
					.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
				complete();
		}
	};

	Tooltip.prototype.applyPlacement = function (offset, placement) {
		var $tip   = this.tip();
		var width  = $tip[0].offsetWidth;
		var height = $tip[0].offsetHeight;

		// manually read margins because getBoundingClientRect includes difference
		var marginTop = parseInt($tip.css('margin-top'), 10);
		var marginLeft = parseInt($tip.css('margin-left'), 10);

		// we must check for NaN for ie 8/9
		if (isNaN(marginTop))  marginTop  = 0;
		if (isNaN(marginLeft)) marginLeft = 0;

		offset.top  += marginTop;
		offset.left += marginLeft;

		// $.fn.offset doesn't round pixel values
		// so we use setOffset directly with our own function B-0
		$.offset.setOffset($tip[0], $.extend({
			using: function (props) {
				$tip.css({
					top: Math.round(props.top),
					left: Math.round(props.left)
				});
			}
		}, offset), 0);

		$tip.addClass('in');

		// check to see if placing tip in new offset caused the tip to resize itself
		var actualWidth  = $tip[0].offsetWidth;
		var actualHeight = $tip[0].offsetHeight;

		if (placement == 'top' && actualHeight != height) {
			offset.top = offset.top + height - actualHeight;
		}

		var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight);

		if (delta.left) {
		offset.left += delta.left;
	} else {
			offset.top += delta.top;
	}

		var isVertical          = /top|bottom/.test(placement);
		var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight;
		var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight';

		$tip.offset(offset);
		this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical);
	};

	Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
		this.arrow()
			.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
			.css(isVertical ? 'top' : 'left', '');
	};

	Tooltip.prototype.setContent = function () {
		var $tip  = this.tip();
		var title = this.getTitle();

		$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title);
		$tip.removeClass('fade in top bottom left right');
	};

	Tooltip.prototype.hide = function (callback) {
		var that = this;
		var $tip = $(this.$tip);
		var e    = $.Event('hide.bs.' + this.type);

		function complete() {
			if (that.hoverState != 'in') $tip.detach();
			that.$element
				.removeAttr('aria-describedby')
				.trigger('hidden.bs.' + that.type);
			callback && callback();
		};

		this.$element.trigger(e);

		if (e.isDefaultPrevented()) return;

		$tip.removeClass('in');

		$.support.transition && $tip.hasClass('fade') ?
			$tip
				.one('bsTransitionEnd', complete)
				.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
			complete();

		this.hoverState = null;

		return this;
	};

	Tooltip.prototype.fixTitle = function () {
		var $e = this.$element;
		if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
			$e.attr('data-original-title', $e.attr('title') || '').attr('title', '');
		}
	};

	Tooltip.prototype.hasContent = function () {
		return this.getTitle();
	};

	Tooltip.prototype.getPosition = function ($element) {
		$element   = $element || this.$element;

		var el     = $element[0];
		var isBody = el.tagName == 'BODY';

		var elRect    = el.getBoundingClientRect();
		if (elRect.width == null) {
			// width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
			elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top });
		}
		var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset();
		var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() };
		var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null;

		return $.extend({}, elRect, scroll, outerDims, elOffset);
	};

	Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
		return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
					 placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
					 placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
				/* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width };

	};

	Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
		var delta = { top: 0, left: 0 };
		if (!this.$viewport) return delta;

		var viewportPadding = this.options.viewport && this.options.viewport.padding || 0;
		var viewportDimensions = this.getPosition(this.$viewport);

		if (/right|left/.test(placement)) {
			var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll;
			var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight;
			if (topEdgeOffset < viewportDimensions.top) { // top overflow
				delta.top = viewportDimensions.top - topEdgeOffset;
			} else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
				delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset;
			}
		} else {
			var leftEdgeOffset  = pos.left - viewportPadding;
			var rightEdgeOffset = pos.left + viewportPadding + actualWidth;
			if (leftEdgeOffset < viewportDimensions.left) { // left overflow
				delta.left = viewportDimensions.left - leftEdgeOffset;
			} else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
				delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset;
			}
		}

		return delta;
	};

	Tooltip.prototype.getTitle = function () {
		var title;
		var $e = this.$element;
		var o  = this.options;

		title = $e.attr('data-original-title')
			|| (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title);

		return title;
	};

	Tooltip.prototype.getUID = function (prefix) {
		do {
		prefix += ~~(Math.random() * 1000000);
		}
		while (document.getElementById(prefix));
		return prefix;
	};

	Tooltip.prototype.tip = function () {
		if (!this.$tip) {
			this.$tip = $(this.options.template);
			if (this.$tip.length != 1) {
				throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!');
			}
		}
		return this.$tip;
	};

	Tooltip.prototype.arrow = function () {
		return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'));
	};

	Tooltip.prototype.enable = function () {
		this.enabled = true;
	};

	Tooltip.prototype.disable = function () {
		this.enabled = false;
	};

	Tooltip.prototype.toggleEnabled = function () {
		this.enabled = !this.enabled;
	};

	Tooltip.prototype.toggle = function (e) {
		var self = this;
		if (e) {
			self = $(e.currentTarget).data('bs.' + this.type);
			if (!self) {
				self = new this.constructor(e.currentTarget, this.getDelegateOptions());
				$(e.currentTarget).data('bs.' + this.type, self);
			}
		}

		if (e) {
			self.inState.click = !self.inState.click;
			if (self.isInStateTrue()) {
			self.enter(self);
		} else {
			self.leave(self);
		}
		} else {
			self.tip().hasClass('in') ? self.leave(self) : self.enter(self);
		}
	};

	Tooltip.prototype.destroy = function () {
		var that = this;
		clearTimeout(this.timeout);

		this.hide(function () {
			that.$element.off('.' + that.type).removeData('bs.' + that.type);
			if (that.$tip) {
				that.$tip.detach();
			}
			that.$tip = null;
			that.$arrow = null;
			that.$viewport = null;
		});
	};


	// TOOLTIP PLUGIN DEFINITION
	// =========================

	function Plugin(option) {
		return this.each(function () {
			var $this   = $(this);
			var data    = $this.data('bs.tooltip');
			var options = typeof option == 'object' && option;

			if (!data && /destroy|hide/.test(option)) return;
			if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)));
			if (typeof option == 'string') data[option]();
		});
	};

	var old = $.fn.tooltip;

	$.fn.tooltip             = Plugin;
	$.fn.tooltip.Constructor = Tooltip;


	// TOOLTIP NO CONFLICT
	// ===================

	$.fn.tooltip.noConflict = function () {
		$.fn.tooltip = old;
		return this;
	};

}(jQuery);

/* ========================================================================
 * Bootstrap: popover.js v3.3.5
 * http://getbootstrap.com/javascript/#popovers
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
	'use strict';

	// POPOVER PUBLIC CLASS DEFINITION
	// ===============================

	var Popover = function (element, options) {
		this.init('popover', element, options);
	};

	if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js');

	Popover.VERSION  = '3.3.5';

	Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
		placement: 'right',
		trigger: 'click',
		content: '',
		template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
	});


	// NOTE: POPOVER EXTENDS tooltip.js
	// ================================

	Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype);

	Popover.prototype.constructor = Popover;

	Popover.prototype.getDefaults = function () {
		return Popover.DEFAULTS;
	};

	Popover.prototype.setContent = function () {
		var $tip    = this.tip();
		var title   = this.getTitle();
		var content = this.getContent();

		$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title);
		$tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
			this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
		](content);

		$tip.removeClass('fade top bottom left right in');

		// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
		// this manually by checking the contents.
		if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide();
	};

	Popover.prototype.hasContent = function () {
		return this.getTitle() || this.getContent();
	};

	Popover.prototype.getContent = function () {
		var $e = this.$element;
		var o  = this.options;

		return $e.attr('data-content')
			|| (typeof o.content == 'function' ?
						o.content.call($e[0]) :
						o.content);
	};

	Popover.prototype.arrow = function () {
		return (this.$arrow = this.$arrow || this.tip().find('.arrow'));
	};


	// POPOVER PLUGIN DEFINITION
	// =========================

	function Plugin(option) {
		return this.each(function () {
			var $this   = $(this);
			var data    = $this.data('bs.popover');
			var options = typeof option == 'object' && option;

			if (!data && /destroy|hide/.test(option)) return;
			if (!data) $this.data('bs.popover', (data = new Popover(this, options)));
			if (typeof option == 'string') data[option]();
		});
	};

	var old = $.fn.popover;

	$.fn.popover             = Plugin;
	$.fn.popover.Constructor = Popover;


	// POPOVER NO CONFLICT
	// ===================

	$.fn.popover.noConflict = function () {
		$.fn.popover = old;
		return this;
	};

}(jQuery);
;/**
 * CssUserAgent (cssua.js) v2.1.28
 * http://cssuseragent.org
 * 
 * Copyright (c)2006-2014 Stephen M. McKamey.
 * Licensed under The MIT License.
 */
/*jshint smarttabs:true, regexp:false, browser:true */

/**
 * @type {Object}
 */
var cssua = (

/**
 * @param html {Object} root DOM element
 * @param userAgent {string} browser userAgent string
 * @return {Object}
 */
function(html, userAgent, sa) {
	'use strict';

	/**
	 * @const
	 * @type {string}
	 */
	var PREFIX = ' ua-';

	/**
	 * @const
	 * @type {RegExp}
	 */
	var R_Platform = /\s*([\-\w ]+)[\s\/\:]([\d_]+\b(?:[\-\._\/]\w+)*)/;

	/**
	 * @const
	 * @type {RegExp}
	 */
	var R_Version = /([\w\-\.]+[\s\/][v]?[\d_]+\b(?:[\-\._\/]\w+)*)/g;

	/**
	 * @const
	 * @type {RegExp}
	 */
	var R_BlackBerry = /\b(?:(blackberry\w*|bb10)|(rim tablet os))(?:\/(\d+\.\d+(?:\.\w+)*))?/;

	/**
	 * @const
	 * @type {RegExp}
	 */
	var R_Silk = /\bsilk-accelerated=true\b/;

	/**
	 * @const
	 * @type {RegExp}
	 */
	var R_FluidApp = /\bfluidapp\b/;

	/**
	 * @const
	 * @type {RegExp}
	 */
	var R_desktop = /(\bwindows\b|\bmacintosh\b|\blinux\b|\bunix\b)/;

	/**
	 * @const
	 * @type {RegExp}
	 */
	var R_mobile = /(\bandroid\b|\bipad\b|\bipod\b|\bwindows phone\b|\bwpdesktop\b|\bxblwp7\b|\bzunewp7\b|\bwindows ce\b|\bblackberry\w*|\bbb10\b|\brim tablet os\b|\bmeego|\bwebos\b|\bpalm|\bsymbian|\bj2me\b|\bdocomo\b|\bpda\b|\bchtml\b|\bmidp\b|\bcldc\b|\w*?mobile\w*?|\w*?phone\w*?)/;

	/**
	 * @const
	 * @type {RegExp}
	 */
	var R_game = /(\bxbox\b|\bplaystation\b|\bnintendo\s+\w+)/;

	/**
	 * The root CssUserAgent
	 * @type {Object}
	 */
	var cssua = {

		parse:
			/**
			 * @param uaStr {string}
			 * @return {Object}
			 */
			function(uaStr, sa) {

				/**
				 * @type {Object}
				 */
				var ua = {};
				if (sa) {
					ua.standalone = sa;
				}

				uaStr = (''+uaStr).toLowerCase();
				if (!uaStr) {
					return ua;
				}

				var i, count, raw = uaStr.split(/[()]/);
				for (var j=0, rawCount=raw.length; j<rawCount; j++) {
					if (j%2) {
						// inside parens covers platform identifiers
						var platforms = raw[j].split(';');
						for (i=0, count=platforms.length; i<count; i++) {
							if (R_Platform.exec(platforms[i])) {
								var key = RegExp.$1.split(' ').join('_'),
									val = RegExp.$2;

								// if duplicate entries favor highest version
								if ((!ua[key] || parseFloat(ua[key]) < parseFloat(val))) {
									ua[key] = val;
								}
							}
						}

					} else {
						// outside parens covers most version identifiers
						var uas = raw[j].match(R_Version);
						if (uas) {
							for (i=0, count=uas.length; i<count; i++) {
								var parts = uas[i].split(/[\/\s]+/);
								if (parts.length && parts[0] !== 'mozilla') {
									ua[parts[0].split(' ').join('_')] = parts.slice(1).join('-');
								}
							}
						}
					}
				}

				if (R_mobile.exec(uaStr)) {
					// mobile device indicators
					ua.mobile = RegExp.$1;
					if (R_BlackBerry.exec(uaStr)) {
						delete ua[ua.mobile];
						ua.blackberry = ua.version || RegExp.$3 || RegExp.$2 || RegExp.$1;
						if (RegExp.$1) {
							// standardize non-tablet blackberry
							ua.mobile = 'blackberry';
						} else if (ua.version === '0.0.1') {
							// fix playbook 1.0 quirk
							ua.blackberry = '7.1.0.0';
						}
					}

				} else if (R_desktop.exec(uaStr)) {
					// desktop OS indicators
					ua.desktop = RegExp.$1;

				} else if (R_game.exec(uaStr)) {
					// game console indicators
					ua.game = RegExp.$1;
					var game = ua.game.split(' ').join('_');

					if (ua.version && !ua[game]) {
						ua[game] = ua.version;
					}
				}

				// platform naming standardizations
				if (ua.intel_mac_os_x) {
					ua.mac_os_x = ua.intel_mac_os_x.split('_').join('.');
					delete ua.intel_mac_os_x;

				} else if (ua.cpu_iphone_os) {
					ua.ios = ua.cpu_iphone_os.split('_').join('.');
					delete ua.cpu_iphone_os;

				} else if (ua.cpu_os) {
					ua.ios = ua.cpu_os.split('_').join('.');
					delete ua.cpu_os;

				} else if (ua.mobile === 'iphone' && !ua.ios) {
					ua.ios = '1';
				}

				// UA naming standardizations
				if (ua.opera && ua.version) {
					ua.opera = ua.version;
					// version/XXX refers to opera
					delete ua.blackberry;

				} else if (R_Silk.exec(uaStr)) {
					ua.silk_accelerated = true;

				} else if (R_FluidApp.exec(uaStr)) {
					ua.fluidapp = ua.version;
				}

				if (ua.applewebkit) {
					ua.webkit = ua.applewebkit;
					delete ua.applewebkit;

					if (ua.opr) {
						ua.opera = ua.opr;
						delete ua.opr;
						delete ua.chrome;
					}

					if (ua.safari) {
						if (ua.chrome || ua.crios || ua.opera || ua.silk || ua.fluidapp || ua.phantomjs || (ua.mobile && !ua.ios)) {
							delete ua.safari;

						} else if (ua.version && !ua.rim_tablet_os) {
							ua.safari = ua.version;

						} else {
							ua.safari = ({
								'419': '2.0.4',
								'417': '2.0.3',
								'416': '2.0.2',
								'412': '2.0',
								'312': '1.3',
								'125': '1.2',
								'85': '1.0'
							})[parseInt(ua.safari, 10)] || ua.safari;
						}
					}

				} else if (ua.msie || ua.trident) {
					if (!ua.opera) {
						// standardize Internet Explorer
						ua.ie = ua.msie || ua.rv;
					}
					delete ua.msie;

					if (ua.windows_phone_os) {
						// standardize window phone
						ua.windows_phone = ua.windows_phone_os;
						delete ua.windows_phone_os;

					} else if (ua.mobile === 'wpdesktop' || ua.mobile === 'xblwp7' || ua.mobile === 'zunewp7') {
						ua.mobile = 'windows desktop';
						ua.windows_phone = (+ua.ie < 9) ? '7.0' : (+ua.ie < 10) ? '7.5' : '8.0';
						delete ua.windows_nt;
					}

				} else if (ua.gecko || ua.firefox) {
					ua.gecko = ua.rv;
				}

				if (ua.rv) {
					delete ua.rv;
				}
				if (ua.version) {
					delete ua.version;
				}

				return ua;
			},

		format:
			/**
			 * @param ua {Object}
			 * @return {string}
			 */
			function (ua) {
				/**
				 * @param b {string} browser key
				 * @param v {string} browser value
				 * @return {string} formatted CSS classes
				 */
				function format(b, v) {
					b = b.split('.').join('-');

					/**
					 * @type {string}
					 */
					var css = PREFIX+b;
					if (typeof v === 'string') {
						v = v.split(' ').join('_').split('.').join('-');
						var i = v.indexOf('-');
						while (i > 0) {
							// loop through chopping last '-' to end off
							// concat result onto return string
							css += PREFIX+b+'-'+v.substring(0, i);
							i = v.indexOf('-', i+1);
						}
						css += PREFIX+b+'-'+v;
					}
					return css;
				}
	
				/**
				 * @type {string}
				 */
				var	uaCss = '';
				for (var b in ua) {
					if (b && ua.hasOwnProperty(b)) {
						uaCss += format(b, ua[b]);
					}
				}
	
				// user-agent classNames
				return uaCss;
			},

		encode:
			/**
			 * Encodes parsed userAgent object as a compact URI-Encoded key-value collection
			 * @param ua {Object}
			 * @return {string}
			 */
			function(ua) {
				var query = '';
				for (var b in ua) {
					if (b && ua.hasOwnProperty(b)) {
						if (query) {
							query += '&';
						}
						query += encodeURIComponent(b)+'='+encodeURIComponent(ua[b]);
					}
				}
				return query;
			}
	};

	/**
	 * @const
	 * @type {Object}
	 */
	cssua.userAgent = cssua.ua = cssua.parse(userAgent, sa);

	/**
	 * @const
	 * @type {string}
	 */
	var ua = cssua.format(cssua.ua)+' js';

	// append CSS classes to HTML node
	if (html.className) {
		html.className = html.className.replace(/\bno-js\b/g, '') + ua;
		
	} else {
		html.className = ua.substr(1);
	}

	return cssua;

})(document.documentElement, navigator.userAgent, navigator.standalone);;// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


// Known Issues:
//
// * Patterns are not implemented.
// * Radial gradient are not implemented. The VML version of these look very
//   different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
//   width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
//   Quirks mode will draw the canvas using border-box. Either change your
//   doctype to HTML5
//   (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
//   or use Box Sizing Behavior from WebFX
//   (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Non uniform scaling does not correctly scale strokes.
// * Optimize. There is always room for speed improvements.

// Only add this code if we do not already have a canvas implementation
if (!document.createElement('canvas').getContext) {

(function() {

  // alias some functions to make (compiled) code shorter
  var m = Math;
  var mr = m.round;
  var ms = m.sin;
  var mc = m.cos;
  var abs = m.abs;
  var sqrt = m.sqrt;

  // this is used for sub pixel precision
  var Z = 10;
  var Z2 = Z / 2;

  /**
   * This funtion is assigned to the <canvas> elements as element.getContext().
   * @this {HTMLElement}
   * @return {CanvasRenderingContext2D_}
   */
  function getContext() {
    return this.context_ ||
        (this.context_ = new CanvasRenderingContext2D_(this));
  }

  var slice = Array.prototype.slice;

  /**
   * Binds a function to an object. The returned function will always use the
   * passed in {@code obj} as {@code this}.
   *
   * Example:
   *
   *   g = bind(f, obj, a, b)
   *   g(c, d) // will do f.call(obj, a, b, c, d)
   *
   * @param {Function} f The function to bind the object to
   * @param {Object} obj The object that should act as this when the function
   *     is called
   * @param {*} var_args Rest arguments that will be used as the initial
   *     arguments when the function is called
   * @return {Function} A new function that has bound this
   */
  function bind(f, obj, var_args) {
    var a = slice.call(arguments, 2);
    return function() {
      return f.apply(obj, a.concat(slice.call(arguments)));
    };
  }

  var G_vmlCanvasManager_ = {
    init: function(opt_doc) {
      if (/MSIE/.test(navigator.userAgent) && !window.opera) {
        var doc = opt_doc || document;
        // Create a dummy element so that IE will allow canvas elements to be
        // recognized.
        doc.createElement('canvas');
        doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
      }
    },

    init_: function(doc) {
      // create xmlns
      if (!doc.namespaces['g_vml_']) {
        doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',
                           '#default#VML');

      }
      if (!doc.namespaces['g_o_']) {
        doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',
                           '#default#VML');
      }

      // Setup default CSS.  Only add one style sheet per document
      if (!doc.styleSheets['ex_canvas_']) {
        var ss = null;
        var cssText = 'canvas{display:inline-block;overflow:hidden;' +
            // default size is 300x150 in Gecko and Opera
            'text-align:left;width:300px;height:150px}' +
            'g_vml_\\:*{behavior:url(#default#VML)}' +
            'g_o_\\:*{behavior:url(#default#VML)}';

      }

      try {
        ss = doc.createStyleSheet();
        ss.owningElement.id = 'ex_canvas_';
        ss.cssText = cssText;
	  } catch( e ) {
		    ss = document.styleSheets[document.styleSheets.length - 1];
  			ss.cssText += "\r\n" + cssText;

	  }
      // find all canvas elements
      var els = doc.getElementsByTagName('canvas');
      for (var i = 0; i < els.length; i++) {
        this.initElement(els[i]);
      }
    },

    /**
     * Public initializes a canvas element so that it can be used as canvas
     * element from now on. This is called automatically before the page is
     * loaded but if you are creating elements using createElement you need to
     * make sure this is called on the element.
     * @param {HTMLElement} el The canvas element to initialize.
     * @return {HTMLElement} the element that was created.
     */
    initElement: function(el) {
      if (!el.getContext) {

        el.getContext = getContext;

        // Remove fallback content. There is no way to hide text nodes so we
        // just remove all childNodes. We could hide all elements and remove
        // text nodes but who really cares about the fallback content.
        el.innerHTML = '';

        // do not use inline function because that will leak memory
        el.attachEvent('onpropertychange', onPropertyChange);
        el.attachEvent('onresize', onResize);

        var attrs = el.attributes;
        if (attrs.width && attrs.width.specified) {
          // TODO: use runtimeStyle and coordsize
          // el.getContext().setWidth_(attrs.width.nodeValue);
          el.style.width = attrs.width.nodeValue + 'px';
        } else {
          el.width = el.clientWidth;
        }
        if (attrs.height && attrs.height.specified) {
          // TODO: use runtimeStyle and coordsize
          // el.getContext().setHeight_(attrs.height.nodeValue);
          el.style.height = attrs.height.nodeValue + 'px';
        } else {
          el.height = el.clientHeight;
        }
        //el.getContext().setCoordsize_()
      }
      return el;
    }
  };

  function onPropertyChange(e) {
    var el = e.srcElement;

    switch (e.propertyName) {
      case 'width':
        el.style.width = el.attributes.width.nodeValue + 'px';
        el.getContext().clearRect();
        break;
      case 'height':
        el.style.height = el.attributes.height.nodeValue + 'px';
        el.getContext().clearRect();
        break;
    }
  }

  function onResize(e) {
    var el = e.srcElement;
    if (el.firstChild) {
      el.firstChild.style.width =  el.clientWidth + 'px';
      el.firstChild.style.height = el.clientHeight + 'px';
    }
  }

  G_vmlCanvasManager_.init();

  // precompute "00" to "FF"
  var dec2hex = [];
  for (var i = 0; i < 16; i++) {
    for (var j = 0; j < 16; j++) {
      dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
    }
  }

  function createMatrixIdentity() {
    return [
      [1, 0, 0],
      [0, 1, 0],
      [0, 0, 1]
    ];
  }

  function matrixMultiply(m1, m2) {
    var result = createMatrixIdentity();

    for (var x = 0; x < 3; x++) {
      for (var y = 0; y < 3; y++) {
        var sum = 0;

        for (var z = 0; z < 3; z++) {
          sum += m1[x][z] * m2[z][y];
        }

        result[x][y] = sum;
      }
    }
    return result;
  }

  function copyState(o1, o2) {
    o2.fillStyle     = o1.fillStyle;
    o2.lineCap       = o1.lineCap;
    o2.lineJoin      = o1.lineJoin;
    o2.lineWidth     = o1.lineWidth;
    o2.miterLimit    = o1.miterLimit;
    o2.shadowBlur    = o1.shadowBlur;
    o2.shadowColor   = o1.shadowColor;
    o2.shadowOffsetX = o1.shadowOffsetX;
    o2.shadowOffsetY = o1.shadowOffsetY;
    o2.strokeStyle   = o1.strokeStyle;
    o2.globalAlpha   = o1.globalAlpha;
    o2.arcScaleX_    = o1.arcScaleX_;
    o2.arcScaleY_    = o1.arcScaleY_;
    o2.lineScale_    = o1.lineScale_;
  }

  function processStyle(styleString) {
    var str, alpha = 1;

    styleString = String(styleString);
    if (styleString.substring(0, 3) == 'rgb') {
      var start = styleString.indexOf('(', 3);
      var end = styleString.indexOf(')', start + 1);
      var guts = styleString.substring(start + 1, end).split(',');

      str = '#';
      for (var i = 0; i < 3; i++) {
        str += dec2hex[Number(guts[i])];
      }

      if (guts.length == 4 && styleString.substr(3, 1) == 'a') {
        alpha = guts[3];
      }
    } else {
      str = styleString;
    }

    return {color: str, alpha: alpha};
  }

  function processLineCap(lineCap) {
    switch (lineCap) {
      case 'butt':
        return 'flat';
      case 'round':
        return 'round';
      case 'square':
      default:
        return 'square';
    }
  }

  /**
   * This class implements CanvasRenderingContext2D interface as described by
   * the WHATWG.
   * @param {HTMLElement} surfaceElement The element that the 2D context should
   * be associated with
   */
  function CanvasRenderingContext2D_(surfaceElement) {
    this.m_ = createMatrixIdentity();

    this.mStack_ = [];
    this.aStack_ = [];
    this.currentPath_ = [];

    // Canvas context properties
    this.strokeStyle = '#000';
    this.fillStyle = '#000';

    this.lineWidth = 1;
    this.lineJoin = 'miter';
    this.lineCap = 'butt';
    this.miterLimit = Z * 1;
    this.globalAlpha = 1;
    this.canvas = surfaceElement;

    var el = surfaceElement.ownerDocument.createElement('div');
    el.style.width =  surfaceElement.clientWidth + 'px';
    el.style.height = surfaceElement.clientHeight + 'px';
    el.style.overflow = 'hidden';
    el.style.position = 'absolute';
    surfaceElement.appendChild(el);

    this.element_ = el;
    this.arcScaleX_ = 1;
    this.arcScaleY_ = 1;
    this.lineScale_ = 1;
  }

  var contextPrototype = CanvasRenderingContext2D_.prototype;
  contextPrototype.clearRect = function() {
    this.element_.innerHTML = '';
  };

  contextPrototype.beginPath = function() {
    // TODO: Branch current matrix so that save/restore has no effect
    //       as per safari docs.
    this.currentPath_ = [];
  };

  contextPrototype.moveTo = function(aX, aY) {
    var p = this.getCoords_(aX, aY);
    this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
    this.currentX_ = p.x;
    this.currentY_ = p.y;
  };

  contextPrototype.lineTo = function(aX, aY) {
    var p = this.getCoords_(aX, aY);
    this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});

    this.currentX_ = p.x;
    this.currentY_ = p.y;
  };

  contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
                                            aCP2x, aCP2y,
                                            aX, aY) {
    var p = this.getCoords_(aX, aY);
    var cp1 = this.getCoords_(aCP1x, aCP1y);
    var cp2 = this.getCoords_(aCP2x, aCP2y);
    bezierCurveTo(this, cp1, cp2, p);
  };

  // Helper function that takes the already fixed cordinates.
  function bezierCurveTo(self, cp1, cp2, p) {
    self.currentPath_.push({
      type: 'bezierCurveTo',
      cp1x: cp1.x,
      cp1y: cp1.y,
      cp2x: cp2.x,
      cp2y: cp2.y,
      x: p.x,
      y: p.y
    });
    self.currentX_ = p.x;
    self.currentY_ = p.y;
  }

  contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
    // the following is lifted almost directly from
    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes

    var cp = this.getCoords_(aCPx, aCPy);
    var p = this.getCoords_(aX, aY);

    var cp1 = {
      x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
      y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
    };
    var cp2 = {
      x: cp1.x + (p.x - this.currentX_) / 3.0,
      y: cp1.y + (p.y - this.currentY_) / 3.0
    };

    bezierCurveTo(this, cp1, cp2, p);
  };

  contextPrototype.arc = function(aX, aY, aRadius,
                                  aStartAngle, aEndAngle, aClockwise) {
    aRadius *= Z;
    var arcType = aClockwise ? 'at' : 'wa';

    var xStart = aX + mc(aStartAngle) * aRadius - Z2;
    var yStart = aY + ms(aStartAngle) * aRadius - Z2;

    var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
    var yEnd = aY + ms(aEndAngle) * aRadius - Z2;

    // IE won't render arches drawn counter clockwise if xStart == xEnd.
    if (xStart == xEnd && !aClockwise) {
      xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
                       // that can be represented in binary
    }

    var p = this.getCoords_(aX, aY);
    var pStart = this.getCoords_(xStart, yStart);
    var pEnd = this.getCoords_(xEnd, yEnd);

    this.currentPath_.push({type: arcType,
                           x: p.x,
                           y: p.y,
                           radius: aRadius,
                           xStart: pStart.x,
                           yStart: pStart.y,
                           xEnd: pEnd.x,
                           yEnd: pEnd.y});

  };

  contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
  };

  contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
    var oldPath = this.currentPath_;
    this.beginPath();

    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
    this.stroke();

    this.currentPath_ = oldPath;
  };

  contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
    var oldPath = this.currentPath_;
    this.beginPath();

    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
    this.fill();

    this.currentPath_ = oldPath;
  };

  contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
    var gradient = new CanvasGradient_('gradient');
    gradient.x0_ = aX0;
    gradient.y0_ = aY0;
    gradient.x1_ = aX1;
    gradient.y1_ = aY1;
    return gradient;
  };

  contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
                                                   aX1, aY1, aR1) {
    var gradient = new CanvasGradient_('gradientradial');
    gradient.x0_ = aX0;
    gradient.y0_ = aY0;
    gradient.r0_ = aR0;
    gradient.x1_ = aX1;
    gradient.y1_ = aY1;
    gradient.r1_ = aR1;
    return gradient;
  };

  contextPrototype.drawImage = function(image, var_args) {
    var dx, dy, dw, dh, sx, sy, sw, sh;

    // to find the original width we overide the width and height
    var oldRuntimeWidth = image.runtimeStyle.width;
    var oldRuntimeHeight = image.runtimeStyle.height;
    image.runtimeStyle.width = 'auto';
    image.runtimeStyle.height = 'auto';

    // get the original size
    var w = image.width;
    var h = image.height;

    // and remove overides
    image.runtimeStyle.width = oldRuntimeWidth;
    image.runtimeStyle.height = oldRuntimeHeight;

    if (arguments.length == 3) {
      dx = arguments[1];
      dy = arguments[2];
      sx = sy = 0;
      sw = dw = w;
      sh = dh = h;
    } else if (arguments.length == 5) {
      dx = arguments[1];
      dy = arguments[2];
      dw = arguments[3];
      dh = arguments[4];
      sx = sy = 0;
      sw = w;
      sh = h;
    } else if (arguments.length == 9) {
      sx = arguments[1];
      sy = arguments[2];
      sw = arguments[3];
      sh = arguments[4];
      dx = arguments[5];
      dy = arguments[6];
      dw = arguments[7];
      dh = arguments[8];
    } else {
      throw Error('Invalid number of arguments');
    }

    var d = this.getCoords_(dx, dy);

    var w2 = sw / 2;
    var h2 = sh / 2;

    var vmlStr = [];

    var W = 10;
    var H = 10;

    // For some reason that I've now forgotten, using divs didn't work
    vmlStr.push(' <g_vml_:group',
                ' coordsize="', Z * W, ',', Z * H, '"',
                ' coordorigin="0,0"' ,
                ' style="width:', W, 'px;height:', H, 'px;position:absolute;');

    // If filters are necessary (rotation exists), create them
    // filters are bog-slow, so only create them if abbsolutely necessary
    // The following check doesn't account for skews (which don't exist
    // in the canvas spec (yet) anyway.

    if (this.m_[0][0] != 1 || this.m_[0][1]) {
      var filter = [];

      // Note the 12/21 reversal
      filter.push('M11=', this.m_[0][0], ',',
                  'M12=', this.m_[1][0], ',',
                  'M21=', this.m_[0][1], ',',
                  'M22=', this.m_[1][1], ',',
                  'Dx=', mr(d.x / Z), ',',
                  'Dy=', mr(d.y / Z), '');

      // Bounding box calculation (need to minimize displayed area so that
      // filters don't waste time on unused pixels.
      var max = d;
      var c2 = this.getCoords_(dx + dw, dy);
      var c3 = this.getCoords_(dx, dy + dh);
      var c4 = this.getCoords_(dx + dw, dy + dh);

      max.x = m.max(max.x, c2.x, c3.x, c4.x);
      max.y = m.max(max.y, c2.y, c3.y, c4.y);

      vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
                  'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
                  filter.join(''), ", sizingmethod='clip');")
    } else {
      vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
    }

    vmlStr.push(' ">' ,
                '<g_vml_:image src="', image.src, '"',
                ' style="width:', Z * dw, 'px;',
                ' height:', Z * dh, 'px;"',
                ' cropleft="', sx / w, '"',
                ' croptop="', sy / h, '"',
                ' cropright="', (w - sx - sw) / w, '"',
                ' cropbottom="', (h - sy - sh) / h, '"',
                ' />',
                '</g_vml_:group>');

    this.element_.insertAdjacentHTML('BeforeEnd',
                                    vmlStr.join(''));
  };

  contextPrototype.stroke = function(aFill) {
    var lineStr = [];
    var lineOpen = false;
    var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
    var color = a.color;
    var opacity = a.alpha * this.globalAlpha;

    var W = 10;
    var H = 10;

    lineStr.push('<g_vml_:shape',
                 ' filled="', !!aFill, '"',
                 ' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
                 ' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
                 ' stroked="', !aFill, '"',
                 ' path="');

    var newSeq = false;
    var min = {x: null, y: null};
    var max = {x: null, y: null};

    for (var i = 0; i < this.currentPath_.length; i++) {
      var p = this.currentPath_[i];
      var c;

      switch (p.type) {
        case 'moveTo':
          c = p;
          lineStr.push(' m ', mr(p.x), ',', mr(p.y));
          break;
        case 'lineTo':
          lineStr.push(' l ', mr(p.x), ',', mr(p.y));
          break;
        case 'close':
          lineStr.push(' x ');
          p = null;
          break;
        case 'bezierCurveTo':
          lineStr.push(' c ',
                       mr(p.cp1x), ',', mr(p.cp1y), ',',
                       mr(p.cp2x), ',', mr(p.cp2y), ',',
                       mr(p.x), ',', mr(p.y));
          break;
        case 'at':
        case 'wa':
          lineStr.push(' ', p.type, ' ',
                       mr(p.x - this.arcScaleX_ * p.radius), ',',
                       mr(p.y - this.arcScaleY_ * p.radius), ' ',
                       mr(p.x + this.arcScaleX_ * p.radius), ',',
                       mr(p.y + this.arcScaleY_ * p.radius), ' ',
                       mr(p.xStart), ',', mr(p.yStart), ' ',
                       mr(p.xEnd), ',', mr(p.yEnd));
          break;
      }


      // TODO: Following is broken for curves due to
      //       move to proper paths.

      // Figure out dimensions so we can do gradient fills
      // properly
      if (p) {
        if (min.x == null || p.x < min.x) {
          min.x = p.x;
        }
        if (max.x == null || p.x > max.x) {
          max.x = p.x;
        }
        if (min.y == null || p.y < min.y) {
          min.y = p.y;
        }
        if (max.y == null || p.y > max.y) {
          max.y = p.y;
        }
      }
    }
    lineStr.push(' ">');

    if (!aFill) {
      var lineWidth = this.lineScale_ * this.lineWidth;

      // VML cannot correctly render a line if the width is less than 1px.
      // In that case, we dilute the color to make the line look thinner.
      if (lineWidth < 1) {
        opacity *= lineWidth;
      }

      lineStr.push(
        '<g_vml_:stroke',
        ' opacity="', opacity, '"',
        ' joinstyle="', this.lineJoin, '"',
        ' miterlimit="', this.miterLimit, '"',
        ' endcap="', processLineCap(this.lineCap), '"',
        ' weight="', lineWidth, 'px"',
        ' color="', color, '" />'
      );
    } else if (typeof this.fillStyle == 'object') {
      var fillStyle = this.fillStyle;
      var angle = 0;
      var focus = {x: 0, y: 0};

      // additional offset
      var shift = 0;
      // scale factor for offset
      var expansion = 1;

      if (fillStyle.type_ == 'gradient') {
        var x0 = fillStyle.x0_ / this.arcScaleX_;
        var y0 = fillStyle.y0_ / this.arcScaleY_;
        var x1 = fillStyle.x1_ / this.arcScaleX_;
        var y1 = fillStyle.y1_ / this.arcScaleY_;
        var p0 = this.getCoords_(x0, y0);
        var p1 = this.getCoords_(x1, y1);
        var dx = p1.x - p0.x;
        var dy = p1.y - p0.y;
        angle = Math.atan2(dx, dy) * 180 / Math.PI;

        // The angle should be a non-negative number.
        if (angle < 0) {
          angle += 360;
        }

        // Very small angles produce an unexpected result because they are
        // converted to a scientific notation string.
        if (angle < 1e-6) {
          angle = 0;
        }
      } else {
        var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_);
        var width  = max.x - min.x;
        var height = max.y - min.y;
        focus = {
          x: (p0.x - min.x) / width,
          y: (p0.y - min.y) / height
        };

        width  /= this.arcScaleX_ * Z;
        height /= this.arcScaleY_ * Z;
        var dimension = m.max(width, height);
        shift = 2 * fillStyle.r0_ / dimension;
        expansion = 2 * fillStyle.r1_ / dimension - shift;
      }

      // We need to sort the color stops in ascending order by offset,
      // otherwise IE won't interpret it correctly.
      var stops = fillStyle.colors_;
      stops.sort(function(cs1, cs2) {
        return cs1.offset - cs2.offset;
      });

      var length = stops.length;
      var color1 = stops[0].color;
      var color2 = stops[length - 1].color;
      var opacity1 = stops[0].alpha * this.globalAlpha;
      var opacity2 = stops[length - 1].alpha * this.globalAlpha;

      var colors = [];
      for (var i = 0; i < length; i++) {
        var stop = stops[i];
        colors.push(stop.offset * expansion + shift + ' ' + stop.color);
      }

      // When colors attribute is used, the meanings of opacity and o:opacity2
      // are reversed.
      lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
                   ' method="none" focus="100%"',
                   ' color="', color1, '"',
                   ' color2="', color2, '"',
                   ' colors="', colors.join(','), '"',
                   ' opacity="', opacity2, '"',
                   ' g_o_:opacity2="', opacity1, '"',
                   ' angle="', angle, '"',
                   ' focusposition="', focus.x, ',', focus.y, '" />');
    } else {
      lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
                   '" />');
    }

    lineStr.push('</g_vml_:shape>');

    this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
  };

  contextPrototype.fill = function() {
    this.stroke(true);
  };

  contextPrototype.closePath = function() {
    this.currentPath_.push({type: 'close'});
  };

  /**
   * @private
   */
  contextPrototype.getCoords_ = function(aX, aY) {
    var m = this.m_;
    return {
      x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
      y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
    }
  };

  contextPrototype.save = function() {
    var o = {};
    copyState(this, o);
    this.aStack_.push(o);
    this.mStack_.push(this.m_);
    this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
  };

  contextPrototype.restore = function() {
    copyState(this.aStack_.pop(), this);
    this.m_ = this.mStack_.pop();
  };

  function matrixIsFinite(m) {
    for (var j = 0; j < 3; j++) {
      for (var k = 0; k < 2; k++) {
        if (!isFinite(m[j][k]) || isNaN(m[j][k])) {
          return false;
        }
      }
    }
    return true;
  }

  function setM(ctx, m, updateLineScale) {
    if (!matrixIsFinite(m)) {
      return;
    }
    ctx.m_ = m;

    if (updateLineScale) {
      // Get the line scale.
      // Determinant of this.m_ means how much the area is enlarged by the
      // transformation. So its square root can be used as a scale factor
      // for width.
      var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
      ctx.lineScale_ = sqrt(abs(det));
    }
  }

  contextPrototype.translate = function(aX, aY) {
    var m1 = [
      [1,  0,  0],
      [0,  1,  0],
      [aX, aY, 1]
    ];

    setM(this, matrixMultiply(m1, this.m_), false);
  };

  contextPrototype.rotate = function(aRot) {
    var c = mc(aRot);
    var s = ms(aRot);

    var m1 = [
      [c,  s, 0],
      [-s, c, 0],
      [0,  0, 1]
    ];

    setM(this, matrixMultiply(m1, this.m_), false);
  };

  contextPrototype.scale = function(aX, aY) {
    this.arcScaleX_ *= aX;
    this.arcScaleY_ *= aY;
    var m1 = [
      [aX, 0,  0],
      [0,  aY, 0],
      [0,  0,  1]
    ];

    setM(this, matrixMultiply(m1, this.m_), true);
  };

  contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
    var m1 = [
      [m11, m12, 0],
      [m21, m22, 0],
      [dx,  dy,  1]
    ];

    setM(this, matrixMultiply(m1, this.m_), true);
  };

  contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
    var m = [
      [m11, m12, 0],
      [m21, m22, 0],
      [dx,  dy,  1]
    ];

    setM(this, m, true);
  };

  /******** STUBS ********/
  contextPrototype.clip = function() {
    // TODO: Implement
  };

  contextPrototype.arcTo = function() {
    // TODO: Implement
  };

  contextPrototype.createPattern = function() {
    return new CanvasPattern_;
  };

  // Gradient / Pattern Stubs
  function CanvasGradient_(aType) {
    this.type_ = aType;
    this.x0_ = 0;
    this.y0_ = 0;
    this.r0_ = 0;
    this.x1_ = 0;
    this.y1_ = 0;
    this.r1_ = 0;
    this.colors_ = [];
  }

  CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
    aColor = processStyle(aColor);
    this.colors_.push({offset: aOffset,
                       color: aColor.color,
                       alpha: aColor.alpha});
  };

  function CanvasPattern_() {}

  // set up externs
  G_vmlCanvasManager = G_vmlCanvasManager_;
  CanvasRenderingContext2D = CanvasRenderingContext2D_;
  CanvasGradient = CanvasGradient_;
  CanvasPattern = CanvasPattern_;

})();

} // if
;// Init style shamelessly stolen from jQuery http://jquery.com
var Froogaloop = (function(){
	// Define a local copy of Froogaloop
	function Froogaloop(iframe) {
		// The Froogaloop object is actually just the init constructor
		return new Froogaloop.fn.init(iframe);
	}

	var eventCallbacks = {},
		hasWindowEvent = false,
		isReady = false,
		slice = Array.prototype.slice,
		playerDomain = '';

	Froogaloop.fn = Froogaloop.prototype = {
		element: null,

		init: function(iframe) {
			if (typeof iframe === "string") {
				iframe = document.getElementById(iframe);
			}

			this.element = iframe;

			// Register message event listeners
			playerDomain = getDomainFromUrl(this.element.getAttribute('src'));

			return this;
		},

		/*
		 * Calls a function to act upon the player.
		 *
		 * @param {string} method The name of the Javascript API method to call. Eg: 'play'.
		 * @param {Array|Function} valueOrCallback params Array of parameters to pass when calling an API method
		 *								or callback function when the method returns a value.
		 */
		api: function(method, valueOrCallback) {
			if (!this.element || !method) {
				return false;
			}

			var self = this,
				element = self.element,
				target_id = element.id !== '' ? element.id : null,
				params = !isFunction(valueOrCallback) ? valueOrCallback : null,
				callback = isFunction(valueOrCallback) ? valueOrCallback : null;

			// Store the callback for get functions
			if (callback) {
				storeCallback(method, callback, target_id);
			}

			postMessage(method, params, element);
			return self;
		},

		/*
		 * Registers an event listener and a callback function that gets called when the event fires.
		 *
		 * @param eventName (String): Name of the event to listen for.
		 * @param callback (Function): Function that should be called when the event fires.
		 */
		addEvent: function(eventName, callback) {
			if (!this.element) {
				return false;
			}

			var self = this,
				element = self.element,
				target_id = element.id !== '' ? element.id : null;


			storeCallback(eventName, callback, target_id);

			// The ready event is not registered via postMessage. It fires regardless.
			if (eventName != 'ready') {
				postMessage('addEventListener', eventName, element);
			}
			else if (eventName == 'ready' && isReady) {
				callback.call(null, target_id);
			}

			return self;
		},

		/*
		 * Unregisters an event listener that gets called when the event fires.
		 *
		 * @param eventName (String): Name of the event to stop listening for.
		 */
		removeEvent: function(eventName) {
			if (!this.element) {
				return false;
			}

			var self = this,
				element = self.element,
				target_id = element.id !== '' ? element.id : null,
				removed = removeCallback(eventName, target_id);

			// The ready event is not registered
			if (eventName != 'ready' && removed) {
				postMessage('removeEventListener', eventName, element);
			}
		}
	};

	/**
	 * Handles posting a message to the parent window.
	 *
	 * @param method (String): name of the method to call inside the player. For api calls
	 * this is the name of the api method (api_play or api_pause) while for events this method
	 * is api_addEventListener.
	 * @param params (Object or Array): List of parameters to submit to the method. Can be either
	 * a single param or an array list of parameters.
	 * @param target (HTMLElement): Target iframe to post the message to.
	 */
	function postMessage(method, params, target) {
		if (!target.contentWindow.postMessage) {
			return false;
		}

		var url = target.getAttribute('src').split('?')[0],
			data = JSON.stringify({
				method: method,
				value: params
			});

		if (url.substr(0, 2) === '//') {
			url = window.location.protocol + url;
		}

		target.contentWindow.postMessage(data, url);
	}

	/**
	 * Event that fires whenever the window receives a message from its parent
	 * via window.postMessage.
	 */
	function onMessageReceived(event) {
		var data, method;

		try {
			data = JSON.parse(event.data);
			method = data.event || data.method;
		}
		catch(e)  {
			//fail silently... like a ninja!
		}

		if (method == 'ready' && !isReady) {
			isReady = true;
		}

		// Handles messages from moogaloop only
		if (event.origin != playerDomain) {
			return false;
		}

		var value = data.value,
			eventData = data.data,
			target_id = target_id === '' ? null : data.player_id,

			callback = getCallback(method, target_id),
			params = [];

		if (!callback) {
			return false;
		}

		if (value !== undefined) {
			params.push(value);
		}

		if (eventData) {
			params.push(eventData);
		}

		if (target_id) {
			params.push(target_id);
		}

		return params.length > 0 ? callback.apply(null, params) : callback.call();
	}


	/**
	 * Stores submitted callbacks for each iframe being tracked and each
	 * event for that iframe.
	 *
	 * @param eventName (String): Name of the event. Eg. api_onPlay
	 * @param callback (Function): Function that should get executed when the
	 * event is fired.
	 * @param target_id (String) [Optional]: If handling more than one iframe then
	 * it stores the different callbacks for different iframes based on the iframe's
	 * id.
	 */
	function storeCallback(eventName, callback, target_id) {
		if (target_id) {
			if (!eventCallbacks[target_id]) {
				eventCallbacks[target_id] = {};
			}
			eventCallbacks[target_id][eventName] = callback;
		}
		else {
			eventCallbacks[eventName] = callback;
		}
	}

	/**
	 * Retrieves stored callbacks.
	 */
	function getCallback(eventName, target_id) {
		if (target_id) {
			return eventCallbacks[target_id][eventName];
		}
		else {
			return eventCallbacks[eventName];
		}
	}

	function removeCallback(eventName, target_id) {
		if (target_id && eventCallbacks[target_id]) {
			if (!eventCallbacks[target_id][eventName]) {
				return false;
			}
			eventCallbacks[target_id][eventName] = null;
		}
		else {
			if (!eventCallbacks[eventName]) {
				return false;
			}
			eventCallbacks[eventName] = null;
		}

		return true;
	}

	/**
	 * Returns a domain's root domain.
	 * Eg. returns http://vimeo.com when http://vimeo.com/channels is sbumitted
	 *
	 * @param url (String): Url to test against.
	 * @return url (String): Root domain of submitted url
	 */
	function getDomainFromUrl(url) {
		if (url.substr(0, 2) === '//') {
			url = window.location.protocol + url;
		}

		var url_pieces = url.split('/'),
			domain_str = '';

		for(var i = 0, length = url_pieces.length; i < length; i++) {
			if(i<3) {domain_str += url_pieces[i];}
			else {break;}
			if(i<2) {domain_str += '/';}
		}

		return domain_str;
	}

	function isFunction(obj) {
		return !!(obj && obj.constructor && obj.call && obj.apply);
	}

	function isArray(obj) {
		return toString.call(obj) === '[object Array]';
	}

	// Give the init function the Froogaloop prototype for later instantiation
	Froogaloop.fn.init.prototype = Froogaloop.fn;

	// Listens for the message event.
	// W3C
	if (window.addEventListener) {
		window.addEventListener('message', onMessageReceived, false);
	}
	// IE
	else {
		window.attachEvent('onmessage', onMessageReceived);
	}

	// Expose froogaloop to the global object
	return (window.Froogaloop = window.$f = Froogaloop);

})();;/*!
 * imagesLoaded PACKAGED v3.1.8
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */


/*!
 * EventEmitter v4.2.6 - git.io/ee
 * Oliver Caldwell
 * MIT license
 * @preserve
 */

(function () {
  

  /**
   * Class for managing events.
   * Can be extended to provide event functionality in other classes.
   *
   * @class EventEmitter Manages event registering and emitting.
   */
  function EventEmitter() {}

  // Shortcuts to improve speed and size
  var proto = EventEmitter.prototype;
  var exports = this;
  var originalGlobalValue = exports.EventEmitter;

  /**
   * Finds the index of the listener for the event in it's storage array.
   *
   * @param {Function[]} listeners Array of listeners to search through.
   * @param {Function} listener Method to look for.
   * @return {Number} Index of the specified listener, -1 if not found
   * @api private
   */
  function indexOfListener(listeners, listener) {
    var i = listeners.length;
    while (i--) {
      if (listeners[i].listener === listener) {
        return i;
      }
    }

    return -1;
  }

  /**
   * Alias a method while keeping the context correct, to allow for overwriting of target method.
   *
   * @param {String} name The name of the target method.
   * @return {Function} The aliased method
   * @api private
   */
  function alias(name) {
    return function aliasClosure() {
      return this[name].apply(this, arguments);
    };
  }

  /**
   * Returns the listener array for the specified event.
   * Will initialise the event object and listener arrays if required.
   * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
   * Each property in the object response is an array of listener functions.
   *
   * @param {String|RegExp} evt Name of the event to return the listeners from.
   * @return {Function[]|Object} All listener functions for the event.
   */
  proto.getListeners = function getListeners(evt) {
    var events = this._getEvents();
    var response;
    var key;

    // Return a concatenated array of all matching events if
    // the selector is a regular expression.
    if (typeof evt === 'object') {
      response = {};
      for (key in events) {
        if (events.hasOwnProperty(key) && evt.test(key)) {
          response[key] = events[key];
        }
      }
    }
    else {
      response = events[evt] || (events[evt] = []);
    }

    return response;
  };

  /**
   * Takes a list of listener objects and flattens it into a list of listener functions.
   *
   * @param {Object[]} listeners Raw listener objects.
   * @return {Function[]} Just the listener functions.
   */
  proto.flattenListeners = function flattenListeners(listeners) {
    var flatListeners = [];
    var i;

    for (i = 0; i < listeners.length; i += 1) {
      flatListeners.push(listeners[i].listener);
    }

    return flatListeners;
  };

  /**
   * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
   *
   * @param {String|RegExp} evt Name of the event to return the listeners from.
   * @return {Object} All listener functions for an event in an object.
   */
  proto.getListenersAsObject = function getListenersAsObject(evt) {
    var listeners = this.getListeners(evt);
    var response;

    if (listeners instanceof Array) {
      response = {};
      response[evt] = listeners;
    }

    return response || listeners;
  };

  /**
   * Adds a listener function to the specified event.
   * The listener will not be added if it is a duplicate.
   * If the listener returns true then it will be removed after it is called.
   * If you pass a regular expression as the event name then the listener will be added to all events that match it.
   *
   * @param {String|RegExp} evt Name of the event to attach the listener to.
   * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.addListener = function addListener(evt, listener) {
    var listeners = this.getListenersAsObject(evt);
    var listenerIsWrapped = typeof listener === 'object';
    var key;

    for (key in listeners) {
      if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
        listeners[key].push(listenerIsWrapped ? listener : {
          listener: listener,
          once: false
        });
      }
    }

    return this;
  };

  /**
   * Alias of addListener
   */
  proto.on = alias('addListener');

  /**
   * Semi-alias of addListener. It will add a listener that will be
   * automatically removed after it's first execution.
   *
   * @param {String|RegExp} evt Name of the event to attach the listener to.
   * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.addOnceListener = function addOnceListener(evt, listener) {
    return this.addListener(evt, {
      listener: listener,
      once: true
    });
  };

  /**
   * Alias of addOnceListener.
   */
  proto.once = alias('addOnceListener');

  /**
   * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
   * You need to tell it what event names should be matched by a regex.
   *
   * @param {String} evt Name of the event to create.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.defineEvent = function defineEvent(evt) {
    this.getListeners(evt);
    return this;
  };

  /**
   * Uses defineEvent to define multiple events.
   *
   * @param {String[]} evts An array of event names to define.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.defineEvents = function defineEvents(evts) {
    for (var i = 0; i < evts.length; i += 1) {
      this.defineEvent(evts[i]);
    }
    return this;
  };

  /**
   * Removes a listener function from the specified event.
   * When passed a regular expression as the event name, it will remove the listener from all events that match it.
   *
   * @param {String|RegExp} evt Name of the event to remove the listener from.
   * @param {Function} listener Method to remove from the event.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.removeListener = function removeListener(evt, listener) {
    var listeners = this.getListenersAsObject(evt);
    var index;
    var key;

    for (key in listeners) {
      if (listeners.hasOwnProperty(key)) {
        index = indexOfListener(listeners[key], listener);

        if (index !== -1) {
          listeners[key].splice(index, 1);
        }
      }
    }

    return this;
  };

  /**
   * Alias of removeListener
   */
  proto.off = alias('removeListener');

  /**
   * Adds listeners in bulk using the manipulateListeners method.
   * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
   * You can also pass it a regular expression to add the array of listeners to all events that match it.
   * Yeah, this function does quite a bit. That's probably a bad thing.
   *
   * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
   * @param {Function[]} [listeners] An optional array of listener functions to add.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.addListeners = function addListeners(evt, listeners) {
    // Pass through to manipulateListeners
    return this.manipulateListeners(false, evt, listeners);
  };

  /**
   * Removes listeners in bulk using the manipulateListeners method.
   * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
   * You can also pass it an event name and an array of listeners to be removed.
   * You can also pass it a regular expression to remove the listeners from all events that match it.
   *
   * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
   * @param {Function[]} [listeners] An optional array of listener functions to remove.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.removeListeners = function removeListeners(evt, listeners) {
    // Pass through to manipulateListeners
    return this.manipulateListeners(true, evt, listeners);
  };

  /**
   * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
   * The first argument will determine if the listeners are removed (true) or added (false).
   * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
   * You can also pass it an event name and an array of listeners to be added/removed.
   * You can also pass it a regular expression to manipulate the listeners of all events that match it.
   *
   * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
   * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
   * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
    var i;
    var value;
    var single = remove ? this.removeListener : this.addListener;
    var multiple = remove ? this.removeListeners : this.addListeners;

    // If evt is an object then pass each of it's properties to this method
    if (typeof evt === 'object' && !(evt instanceof RegExp)) {
      for (i in evt) {
        if (evt.hasOwnProperty(i) && (value = evt[i])) {
          // Pass the single listener straight through to the singular method
          if (typeof value === 'function') {
            single.call(this, i, value);
          }
          else {
            // Otherwise pass back to the multiple function
            multiple.call(this, i, value);
          }
        }
      }
    }
    else {
      // So evt must be a string
      // And listeners must be an array of listeners
      // Loop over it and pass each one to the multiple method
      i = listeners.length;
      while (i--) {
        single.call(this, evt, listeners[i]);
      }
    }

    return this;
  };

  /**
   * Removes all listeners from a specified event.
   * If you do not specify an event then all listeners will be removed.
   * That means every event will be emptied.
   * You can also pass a regex to remove all events that match it.
   *
   * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.removeEvent = function removeEvent(evt) {
    var type = typeof evt;
    var events = this._getEvents();
    var key;

    // Remove different things depending on the state of evt
    if (type === 'string') {
      // Remove all listeners for the specified event
      delete events[evt];
    }
    else if (type === 'object') {
      // Remove all events matching the regex.
      for (key in events) {
        if (events.hasOwnProperty(key) && evt.test(key)) {
          delete events[key];
        }
      }
    }
    else {
      // Remove all listeners in all events
      delete this._events;
    }

    return this;
  };

  /**
   * Alias of removeEvent.
   *
   * Added to mirror the node API.
   */
  proto.removeAllListeners = alias('removeEvent');

  /**
   * Emits an event of your choice.
   * When emitted, every listener attached to that event will be executed.
   * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
   * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
   * So they will not arrive within the array on the other side, they will be separate.
   * You can also pass a regular expression to emit to all events that match it.
   *
   * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
   * @param {Array} [args] Optional array of arguments to be passed to each listener.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.emitEvent = function emitEvent(evt, args) {
    var listeners = this.getListenersAsObject(evt);
    var listener;
    var i;
    var key;
    var response;

    for (key in listeners) {
      if (listeners.hasOwnProperty(key)) {
        i = listeners[key].length;

        while (i--) {
          // If the listener returns true then it shall be removed from the event
          // The function is executed either with a basic call or an apply if there is an args array
          listener = listeners[key][i];

          if (listener.once === true) {
            this.removeListener(evt, listener.listener);
          }

          response = listener.listener.apply(this, args || []);

          if (response === this._getOnceReturnValue()) {
            this.removeListener(evt, listener.listener);
          }
        }
      }
    }

    return this;
  };

  /**
   * Alias of emitEvent
   */
  proto.trigger = alias('emitEvent');

  /**
   * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
   * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
   *
   * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
   * @param {...*} Optional additional arguments to be passed to each listener.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.emit = function emit(evt) {
    var args = Array.prototype.slice.call(arguments, 1);
    return this.emitEvent(evt, args);
  };

  /**
   * Sets the current value to check against when executing listeners. If a
   * listeners return value matches the one set here then it will be removed
   * after execution. This value defaults to true.
   *
   * @param {*} value The new value to check for when executing listeners.
   * @return {Object} Current instance of EventEmitter for chaining.
   */
  proto.setOnceReturnValue = function setOnceReturnValue(value) {
    this._onceReturnValue = value;
    return this;
  };

  /**
   * Fetches the current value to check against when executing listeners. If
   * the listeners return value matches this one then it should be removed
   * automatically. It will return true by default.
   *
   * @return {*|Boolean} The current value to check for or the default, true.
   * @api private
   */
  proto._getOnceReturnValue = function _getOnceReturnValue() {
    if (this.hasOwnProperty('_onceReturnValue')) {
      return this._onceReturnValue;
    }
    else {
      return true;
    }
  };

  /**
   * Fetches the events object and creates one if required.
   *
   * @return {Object} The events storage object.
   * @api private
   */
  proto._getEvents = function _getEvents() {
    return this._events || (this._events = {});
  };

  /**
   * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
   *
   * @return {Function} Non conflicting EventEmitter class.
   */
  EventEmitter.noConflict = function noConflict() {
    exports.EventEmitter = originalGlobalValue;
    return EventEmitter;
  };

  // Expose the class either via AMD, CommonJS or the global object
  if (typeof define === 'function' && define.amd) {
    define('eventEmitter/EventEmitter',[],function () {
      return EventEmitter;
    });
  }
  else if (typeof module === 'object' && module.exports){
    module.exports = EventEmitter;
  }
  else {
    this.EventEmitter = EventEmitter;
  }
}.call(this));

/*!
 * eventie v1.0.4
 * event binding helper
 *   eventie.bind( elem, 'click', myFn )
 *   eventie.unbind( elem, 'click', myFn )
 */

/*jshint browser: true, undef: true, unused: true */
/*global define: false */

( function( window ) {



var docElem = document.documentElement;

var bind = function() {};

function getIEEvent( obj ) {
  var event = window.event;
  // add event.target
  event.target = event.target || event.srcElement || obj;
  return event;
}

if ( docElem.addEventListener ) {
  bind = function( obj, type, fn ) {
    obj.addEventListener( type, fn, false );
  };
} else if ( docElem.attachEvent ) {
  bind = function( obj, type, fn ) {
    obj[ type + fn ] = fn.handleEvent ?
      function() {
        var event = getIEEvent( obj );
        fn.handleEvent.call( fn, event );
      } :
      function() {
        var event = getIEEvent( obj );
        fn.call( obj, event );
      };
    obj.attachEvent( "on" + type, obj[ type + fn ] );
  };
}

var unbind = function() {};

if ( docElem.removeEventListener ) {
  unbind = function( obj, type, fn ) {
    obj.removeEventListener( type, fn, false );
  };
} else if ( docElem.detachEvent ) {
  unbind = function( obj, type, fn ) {
    obj.detachEvent( "on" + type, obj[ type + fn ] );
    try {
      delete obj[ type + fn ];
    } catch ( err ) {
      // can't delete window object properties
      obj[ type + fn ] = undefined;
    }
  };
}

var eventie = {
  bind: bind,
  unbind: unbind
};

// transport
if ( typeof define === 'function' && define.amd ) {
  // AMD
  define( 'eventie/eventie',eventie );
} else {
  // browser global
  window.eventie = eventie;
}

})( this );

/*!
 * imagesLoaded v3.1.8
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

( function( window, factory ) { 
  // universal module definition

  /*global define: false, module: false, require: false */

  if ( typeof define === 'function' && define.amd ) {
    // AMD
    define( [
      'eventEmitter/EventEmitter',
      'eventie/eventie'
    ], function( EventEmitter, eventie ) {
      return factory( window, EventEmitter, eventie );
    });
  } else if ( typeof exports === 'object' ) {
    // CommonJS
    module.exports = factory(
      window,
      require('wolfy87-eventemitter'),
      require('eventie')
    );
  } else {
    // browser global
    window.imagesLoaded = factory(
      window,
      window.EventEmitter,
      window.eventie
    );
  }

})( window,

// --------------------------  factory -------------------------- //

function factory( window, EventEmitter, eventie ) {



var $ = window.jQuery;
var console = window.console;
var hasConsole = typeof console !== 'undefined';

// -------------------------- helpers -------------------------- //

// extend objects
function extend( a, b ) {
  for ( var prop in b ) {
    a[ prop ] = b[ prop ];
  }
  return a;
}

var objToString = Object.prototype.toString;
function isArray( obj ) {
  return objToString.call( obj ) === '[object Array]';
}

// turn element or nodeList into an array
function makeArray( obj ) {
  var ary = [];
  if ( isArray( obj ) ) {
    // use object if already an array
    ary = obj;
  } else if ( typeof obj.length === 'number' ) {
    // convert nodeList to array
    for ( var i=0, len = obj.length; i < len; i++ ) {
      ary.push( obj[i] );
    }
  } else {
    // array of single index
    ary.push( obj );
  }
  return ary;
}

  // -------------------------- imagesLoaded -------------------------- //

  /**
   * @param {Array, Element, NodeList, String} elem
   * @param {Object or Function} options - if function, use as callback
   * @param {Function} onAlways - callback function
   */
  function ImagesLoaded( elem, options, onAlways ) {
    // coerce ImagesLoaded() without new, to be new ImagesLoaded()
    if ( !( this instanceof ImagesLoaded ) ) {
      return new ImagesLoaded( elem, options );
    }
    // use elem as selector string
    if ( typeof elem === 'string' ) {
      elem = document.querySelectorAll( elem );
    }

    this.elements = makeArray( elem );
    this.options = extend( {}, this.options );

    if ( typeof options === 'function' ) {
      onAlways = options;
    } else {
      extend( this.options, options );
    }

    if ( onAlways ) {
      this.on( 'always', onAlways );
    }

    this.getImages();

    if ( $ ) {
      // add jQuery Deferred object
      this.jqDeferred = new $.Deferred();
    }

    // HACK check async to allow time to bind listeners
    var _this = this;
    setTimeout( function() {
      _this.check();
    });
  }

  ImagesLoaded.prototype = new EventEmitter();

  ImagesLoaded.prototype.options = {};

  ImagesLoaded.prototype.getImages = function() {
    this.images = [];

    // filter & find items if we have an item selector
    for ( var i=0, len = this.elements.length; i < len; i++ ) {
      var elem = this.elements[i];
      // filter siblings
      if ( elem.nodeName === 'IMG' ) {
        this.addImage( elem );
      }
      // find children
      // no non-element nodes, #143
      var nodeType = elem.nodeType;
      if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) {
        continue;
      }
      var childElems = elem.querySelectorAll('img');
      // concat childElems to filterFound array
      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
        var img = childElems[j];
        this.addImage( img );
      }
    }
  };

  /**
   * @param {Image} img
   */
  ImagesLoaded.prototype.addImage = function( img ) {
    var loadingImage = new LoadingImage( img );
    this.images.push( loadingImage );
  };

  ImagesLoaded.prototype.check = function() {
    var _this = this;
    var checkedCount = 0;
    var length = this.images.length;
    this.hasAnyBroken = false;
    // complete if no images
    if ( !length ) {
      this.complete();
      return;
    }

    function onConfirm( image, message ) {
      if ( _this.options.debug && hasConsole ) {
        console.log( 'confirm', image, message );
      }

      _this.progress( image );
      checkedCount++;
      if ( checkedCount === length ) {
        _this.complete();
      }
      return true; // bind once
    }

    for ( var i=0; i < length; i++ ) {
      var loadingImage = this.images[i];
      loadingImage.on( 'confirm', onConfirm );
      loadingImage.check();
    }
  };

  ImagesLoaded.prototype.progress = function( image ) {
    this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
    // HACK - Chrome triggers event before object properties have changed. #83
    var _this = this;
    setTimeout( function() {
      _this.emit( 'progress', _this, image );
      if ( _this.jqDeferred && _this.jqDeferred.notify ) {
        _this.jqDeferred.notify( _this, image );
      }
    });
  };

  ImagesLoaded.prototype.complete = function() {
    var eventName = this.hasAnyBroken ? 'fail' : 'done';
    this.isComplete = true;
    var _this = this;
    // HACK - another setTimeout so that confirm happens after progress
    setTimeout( function() {
      _this.emit( eventName, _this );
      _this.emit( 'always', _this );
      if ( _this.jqDeferred ) {
        var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve';
        _this.jqDeferred[ jqMethod ]( _this );
      }
    });
  };

  // -------------------------- jquery -------------------------- //

  if ( $ ) {
    $.fn.imagesLoaded = function( options, callback ) {
      var instance = new ImagesLoaded( this, options, callback );
      return instance.jqDeferred.promise( $(this) );
    };
  }


  // --------------------------  -------------------------- //

  function LoadingImage( img ) {
    this.img = img;
  }

  LoadingImage.prototype = new EventEmitter();

  LoadingImage.prototype.check = function() {
    // first check cached any previous images that have same src
    var resource = cache[ this.img.src ] || new Resource( this.img.src );
    if ( resource.isConfirmed ) {
      this.confirm( resource.isLoaded, 'cached was confirmed' );
      return;
    }

    // If complete is true and browser supports natural sizes,
    // try to check for image status manually.
    if ( this.img.complete && this.img.naturalWidth !== undefined ) {
      // report based on naturalWidth
      this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
      return;
    }

    // If none of the checks above matched, simulate loading on detached element.
    var _this = this;
    resource.on( 'confirm', function( resrc, message ) {
      _this.confirm( resrc.isLoaded, message );
      return true;
    });

    resource.check();
  };

  LoadingImage.prototype.confirm = function( isLoaded, message ) {
    this.isLoaded = isLoaded;
    this.emit( 'confirm', this, message );
  };

  // -------------------------- Resource -------------------------- //

  // Resource checks each src, only once
  // separate class from LoadingImage to prevent memory leaks. See #115

  var cache = {};

  function Resource( src ) {
    this.src = src;
    // add to cache
    cache[ src ] = this;
  }

  Resource.prototype = new EventEmitter();

  Resource.prototype.check = function() {
    // only trigger checking once
    if ( this.isChecked ) {
      return;
    }
    // simulate loading on detached element
    var proxyImage = new Image();
    eventie.bind( proxyImage, 'load', this );
    eventie.bind( proxyImage, 'error', this );
    proxyImage.src = this.src;
    // set flag
    this.isChecked = true;
  };

  // ----- events ----- //

  // trigger specified handler for event type
  Resource.prototype.handleEvent = function( event ) {
    var method = 'on' + event.type;
    if ( this[ method ] ) {
      this[ method ]( event );
    }
  };

  Resource.prototype.onload = function( event ) {
    this.confirm( true, 'onload' );
    this.unbindProxyEvents( event );
  };

  Resource.prototype.onerror = function( event ) {
    this.confirm( false, 'onerror' );
    this.unbindProxyEvents( event );
  };

  // ----- confirm ----- //

  Resource.prototype.confirm = function( isLoaded, message ) {
    this.isConfirmed = true;
    this.isLoaded = isLoaded;
    this.emit( 'confirm', this, message );
  };

  Resource.prototype.unbindProxyEvents = function( event ) {
    eventie.unbind( event.target, 'load', this );
    eventie.unbind( event.target, 'error', this );
  };

  // -----  ----- //

  return ImagesLoaded;

});;/*!
 * Isotope PACKAGED v3.0.0
 *
 * Licensed GPLv3 for open source use
 * or Isotope Commercial License for commercial use
 *
 * http://isotope.metafizzy.co
 * Copyright 2016 Metafizzy
 */

/**
 * Bridget makes jQuery widgets
 * v2.0.0
 * MIT license
 */

/* jshint browser: true, strict: true, undef: true, unused: true */

( function( window, factory ) {
  'use strict';
  /* globals define: false, module: false, require: false */

  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
      factory( window, jQuery );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('jquery')
    );
  } else {
    // browser global
    window.jQueryBridget = factory(
      window,
      window.jQuery
    );
  }

}( window, function factory( window, jQuery ) {
'use strict';

// ----- utils ----- //

var arraySlice = Array.prototype.slice;

// helper function for logging errors
// $.error breaks jQuery chaining
var console = window.console;
var logError = typeof console == 'undefined' ? function() {} :
  function( message ) {
    console.error( message );
  };

// ----- jQueryBridget ----- //

function jQueryBridget( namespace, PluginClass, $ ) {
  $ = $ || jQuery || window.jQuery;
  if ( !$ ) {
    return;
  }

  // add option method -> $().plugin('option', {...})
  if ( !PluginClass.prototype.option ) {
    // option setter
    PluginClass.prototype.option = function( opts ) {
      // bail out if not an object
      if ( !$.isPlainObject( opts ) ){
        return;
      }
      this.options = $.extend( true, this.options, opts );
    };
  }

  // make jQuery plugin
  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
    if ( typeof arg0 == 'string' ) {
      // method call $().plugin( 'methodName', { options } )
      // shift arguments by 1
      var args = arraySlice.call( arguments, 1 );
      return methodCall( this, arg0, args );
    }
    // just $().plugin({ options })
    plainCall( this, arg0 );
    return this;
  };

  // $().plugin('methodName')
  function methodCall( $elems, methodName, args ) {
    var returnValue;
    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';

    $elems.each( function( i, elem ) {
      // get instance
      var instance = $.data( elem, namespace );
      if ( !instance ) {
        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
          pluginMethodStr );
        return;
      }

      var method = instance[ methodName ];
      if ( !method || methodName.charAt(0) == '_' ) {
        logError( pluginMethodStr + ' is not a valid method' );
        return;
      }

      // apply method, get return value
      var value = method.apply( instance, args );
      // set return value if value is returned, use only first value
      returnValue = returnValue === undefined ? value : returnValue;
    });

    return returnValue !== undefined ? returnValue : $elems;
  }

  function plainCall( $elems, options ) {
    $elems.each( function( i, elem ) {
      var instance = $.data( elem, namespace );
      if ( instance ) {
        // set options & init
        instance.option( options );
        instance._init();
      } else {
        // initialize new instance
        instance = new PluginClass( elem, options );
        $.data( elem, namespace, instance );
      }
    });
  }

  updateJQuery( $ );

}

// ----- updateJQuery ----- //

// set $.bridget for v1 backwards compatibility
function updateJQuery( $ ) {
  if ( !$ || ( $ && $.bridget ) ) {
    return;
  }
  $.bridget = jQueryBridget;
}

updateJQuery( jQuery || window.jQuery );

// -----  ----- //

return jQueryBridget;

}));

/**
 * EvEmitter v1.0.2
 * Lil' event emitter
 * MIT License
 */

/* jshint unused: true, undef: true, strict: true */

( function( global, factory ) {
  // universal module definition
  /* jshint strict: false */ /* globals define, module */
  if ( typeof define == 'function' && define.amd ) {
    // AMD - RequireJS
    define( 'ev-emitter/ev-emitter',factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS - Browserify, Webpack
    module.exports = factory();
  } else {
    // Browser globals
    global.EvEmitter = factory();
  }

}( this, function() {



function EvEmitter() {}

var proto = EvEmitter.prototype;

proto.on = function( eventName, listener ) {
  if ( !eventName || !listener ) {
    return;
  }
  // set events hash
  var events = this._events = this._events || {};
  // set listeners array
  var listeners = events[ eventName ] = events[ eventName ] || [];
  // only add once
  if ( listeners.indexOf( listener ) == -1 ) {
    listeners.push( listener );
  }

  return this;
};

proto.once = function( eventName, listener ) {
  if ( !eventName || !listener ) {
    return;
  }
  // add event
  this.on( eventName, listener );
  // set once flag
  // set onceEvents hash
  var onceEvents = this._onceEvents = this._onceEvents || {};
  // set onceListeners object
  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
  // set flag
  onceListeners[ listener ] = true;

  return this;
};

proto.off = function( eventName, listener ) {
  var listeners = this._events && this._events[ eventName ];
  if ( !listeners || !listeners.length ) {
    return;
  }
  var index = listeners.indexOf( listener );
  if ( index != -1 ) {
    listeners.splice( index, 1 );
  }

  return this;
};

proto.emitEvent = function( eventName, args ) {
  var listeners = this._events && this._events[ eventName ];
  if ( !listeners || !listeners.length ) {
    return;
  }
  var i = 0;
  var listener = listeners[i];
  args = args || [];
  // once stuff
  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];

  while ( listener ) {
    var isOnce = onceListeners && onceListeners[ listener ];
    if ( isOnce ) {
      // remove listener
      // remove before trigger to prevent recursion
      this.off( eventName, listener );
      // unset once flag
      delete onceListeners[ listener ];
    }
    // trigger listener
    listener.apply( this, args );
    // get next listener
    i += isOnce ? 0 : 1;
    listener = listeners[i];
  }

  return this;
};

return EvEmitter;

}));

/*!
 * getSize v2.0.2
 * measure size of elements
 * MIT license
 */

/*jshint browser: true, strict: true, undef: true, unused: true */
/*global define: false, module: false, console: false */

( function( window, factory ) {
  'use strict';

  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'get-size/get-size',[],function() {
      return factory();
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory();
  } else {
    // browser global
    window.getSize = factory();
  }

})( window, function factory() {
'use strict';

// -------------------------- helpers -------------------------- //

// get a number from a string, not a percentage
function getStyleSize( value ) {
  var num = parseFloat( value );
  // not a percent like '100%', and a number
  var isValid = value.indexOf('%') == -1 && !isNaN( num );
  return isValid && num;
}

function noop() {}

var logError = typeof console == 'undefined' ? noop :
  function( message ) {
    console.error( message );
  };

// -------------------------- measurements -------------------------- //

var measurements = [
  'paddingLeft',
  'paddingRight',
  'paddingTop',
  'paddingBottom',
  'marginLeft',
  'marginRight',
  'marginTop',
  'marginBottom',
  'borderLeftWidth',
  'borderRightWidth',
  'borderTopWidth',
  'borderBottomWidth'
];

var measurementsLength = measurements.length;

function getZeroSize() {
  var size = {
    width: 0,
    height: 0,
    innerWidth: 0,
    innerHeight: 0,
    outerWidth: 0,
    outerHeight: 0
  };
  for ( var i=0; i < measurementsLength; i++ ) {
    var measurement = measurements[i];
    size[ measurement ] = 0;
  }
  return size;
}

// -------------------------- getStyle -------------------------- //

/**
 * getStyle, get style of element, check for Firefox bug
 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
 */
function getStyle( elem ) {
  var style = getComputedStyle( elem );
  if ( !style ) {
    logError( 'Style returned ' + style +
      '. Are you running this code in a hidden iframe on Firefox? ' +
      'See http://bit.ly/getsizebug1' );
  }
  return style;
}

// -------------------------- setup -------------------------- //

var isSetup = false;

var isBoxSizeOuter;

/**
 * setup
 * check isBoxSizerOuter
 * do on first getSize() rather than on page load for Firefox bug
 */
function setup() {
  // setup once
  if ( isSetup ) {
    return;
  }
  isSetup = true;

  // -------------------------- box sizing -------------------------- //

  /**
   * WebKit measures the outer-width on style.width on border-box elems
   * IE & Firefox<29 measures the inner-width
   */
  var div = document.createElement('div');
  div.style.width = '200px';
  div.style.padding = '1px 2px 3px 4px';
  div.style.borderStyle = 'solid';
  div.style.borderWidth = '1px 2px 3px 4px';
  div.style.boxSizing = 'border-box';

  var body = document.body || document.documentElement;
  body.appendChild( div );
  var style = getStyle( div );

  getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;
  body.removeChild( div );

}

// -------------------------- getSize -------------------------- //

function getSize( elem ) {
  setup();

  // use querySeletor if elem is string
  if ( typeof elem == 'string' ) {
    elem = document.querySelector( elem );
  }

  // do not proceed on non-objects
  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
    return;
  }

  var style = getStyle( elem );

  // if hidden, everything is 0
  if ( style.display == 'none' ) {
    return getZeroSize();
  }

  var size = {};
  size.width = elem.offsetWidth;
  size.height = elem.offsetHeight;

  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';

  // get all measurements
  for ( var i=0; i < measurementsLength; i++ ) {
    var measurement = measurements[i];
    var value = style[ measurement ];
    var num = parseFloat( value );
    // any 'auto', 'medium' value will be 0
    size[ measurement ] = !isNaN( num ) ? num : 0;
  }

  var paddingWidth = size.paddingLeft + size.paddingRight;
  var paddingHeight = size.paddingTop + size.paddingBottom;
  var marginWidth = size.marginLeft + size.marginRight;
  var marginHeight = size.marginTop + size.marginBottom;
  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
  var borderHeight = size.borderTopWidth + size.borderBottomWidth;

  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;

  // overwrite width and height if we can get it from style
  var styleWidth = getStyleSize( style.width );
  if ( styleWidth !== false ) {
    size.width = styleWidth +
      // add padding and border unless it's already including it
      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
  }

  var styleHeight = getStyleSize( style.height );
  if ( styleHeight !== false ) {
    size.height = styleHeight +
      // add padding and border unless it's already including it
      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
  }

  size.innerWidth = size.width - ( paddingWidth + borderWidth );
  size.innerHeight = size.height - ( paddingHeight + borderHeight );

  size.outerWidth = size.width + marginWidth;
  size.outerHeight = size.height + marginHeight;

  return size;
}

return getSize;

});

/**
 * matchesSelector v2.0.1
 * matchesSelector( element, '.selector' )
 * MIT license
 */

/*jshint browser: true, strict: true, undef: true, unused: true */

( function( window, factory ) {
  /*global define: false, module: false */
  'use strict';
  // universal module definition
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'desandro-matches-selector/matches-selector',factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory();
  } else {
    // browser global
    window.matchesSelector = factory();
  }

}( window, function factory() {
  'use strict';

  var matchesMethod = ( function() {
    var ElemProto = Element.prototype;
    // check for the standard method name first
    if ( ElemProto.matches ) {
      return 'matches';
    }
    // check un-prefixed
    if ( ElemProto.matchesSelector ) {
      return 'matchesSelector';
    }
    // check vendor prefixes
    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];

    for ( var i=0; i < prefixes.length; i++ ) {
      var prefix = prefixes[i];
      var method = prefix + 'MatchesSelector';
      if ( ElemProto[ method ] ) {
        return method;
      }
    }
  })();

  return function matchesSelector( elem, selector ) {
    return elem[ matchesMethod ]( selector );
  };

}));

/**
 * Fizzy UI utils v2.0.1
 * MIT license
 */

/*jshint browser: true, undef: true, unused: true, strict: true */

( function( window, factory ) {
  // universal module definition
  /*jshint strict: false */ /*globals define, module, require */

  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'fizzy-ui-utils/utils',[
      'desandro-matches-selector/matches-selector'
    ], function( matchesSelector ) {
      return factory( window, matchesSelector );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('desandro-matches-selector')
    );
  } else {
    // browser global
    window.fizzyUIUtils = factory(
      window,
      window.matchesSelector
    );
  }

}( window, function factory( window, matchesSelector ) {



var utils = {};

// ----- extend ----- //

// extends objects
utils.extend = function( a, b ) {
  for ( var prop in b ) {
    a[ prop ] = b[ prop ];
  }
  return a;
};

// ----- modulo ----- //

utils.modulo = function( num, div ) {
  return ( ( num % div ) + div ) % div;
};

// ----- makeArray ----- //

// turn element or nodeList into an array
utils.makeArray = function( obj ) {
  var ary = [];
  if ( Array.isArray( obj ) ) {
    // use object if already an array
    ary = obj;
  } else if ( obj && typeof obj.length == 'number' ) {
    // convert nodeList to array
    for ( var i=0; i < obj.length; i++ ) {
      ary.push( obj[i] );
    }
  } else {
    // array of single index
    ary.push( obj );
  }
  return ary;
};

// ----- removeFrom ----- //

utils.removeFrom = function( ary, obj ) {
  var index = ary.indexOf( obj );
  if ( index != -1 ) {
    ary.splice( index, 1 );
  }
};

// ----- getParent ----- //

utils.getParent = function( elem, selector ) {
  while ( elem != document.body ) {
    elem = elem.parentNode;
    if ( matchesSelector( elem, selector ) ) {
      return elem;
    }
  }
};

// ----- getQueryElement ----- //

// use element as selector string
utils.getQueryElement = function( elem ) {
  if ( typeof elem == 'string' ) {
    return document.querySelector( elem );
  }
  return elem;
};

// ----- handleEvent ----- //

// enable .ontype to trigger from .addEventListener( elem, 'type' )
utils.handleEvent = function( event ) {
  var method = 'on' + event.type;
  if ( this[ method ] ) {
    this[ method ]( event );
  }
};

// ----- filterFindElements ----- //

utils.filterFindElements = function( elems, selector ) {
  // make array of elems
  elems = utils.makeArray( elems );
  var ffElems = [];

  elems.forEach( function( elem ) {
    // check that elem is an actual element
    if ( !( elem instanceof HTMLElement ) ) {
      return;
    }
    // add elem if no selector
    if ( !selector ) {
      ffElems.push( elem );
      return;
    }
    // filter & find items if we have a selector
    // filter
    if ( matchesSelector( elem, selector ) ) {
      ffElems.push( elem );
    }
    // find children
    var childElems = elem.querySelectorAll( selector );
    // concat childElems to filterFound array
    for ( var i=0; i < childElems.length; i++ ) {
      ffElems.push( childElems[i] );
    }
  });

  return ffElems;
};

// ----- debounceMethod ----- //

utils.debounceMethod = function( _class, methodName, threshold ) {
  // original method
  var method = _class.prototype[ methodName ];
  var timeoutName = methodName + 'Timeout';

  _class.prototype[ methodName ] = function() {
    var timeout = this[ timeoutName ];
    if ( timeout ) {
      clearTimeout( timeout );
    }
    var args = arguments;

    var _this = this;
    this[ timeoutName ] = setTimeout( function() {
      method.apply( _this, args );
      delete _this[ timeoutName ];
    }, threshold || 100 );
  };
};

// ----- docReady ----- //

utils.docReady = function( callback ) {
  if ( document.readyState == 'complete' ) {
    callback();
  } else {
    document.addEventListener( 'DOMContentLoaded', callback );
  }
};

// ----- htmlInit ----- //

// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
utils.toDashed = function( str ) {
  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
    return $1 + '-' + $2;
  }).toLowerCase();
};

var console = window.console;
/**
 * allow user to initialize classes via [data-namespace] or .js-namespace class
 * htmlInit( Widget, 'widgetName' )
 * options are parsed from data-namespace-options
 */
utils.htmlInit = function( WidgetClass, namespace ) {
  utils.docReady( function() {
    var dashedNamespace = utils.toDashed( namespace );
    var dataAttr = 'data-' + dashedNamespace;
    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
    var elems = utils.makeArray( dataAttrElems )
      .concat( utils.makeArray( jsDashElems ) );
    var dataOptionsAttr = dataAttr + '-options';
    var jQuery = window.jQuery;

    elems.forEach( function( elem ) {
      var attr = elem.getAttribute( dataAttr ) ||
        elem.getAttribute( dataOptionsAttr );
      var options;
      try {
        options = attr && JSON.parse( attr );
      } catch ( error ) {
        // log error, do not initialize
        if ( console ) {
          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
          ': ' + error );
        }
        return;
      }
      // initialize
      var instance = new WidgetClass( elem, options );
      // make available via $().data('layoutname')
      if ( jQuery ) {
        jQuery.data( elem, namespace, instance );
      }
    });

  });
};

// -----  ----- //

return utils;

}));

/**
 * Outlayer Item
 */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /* globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD - RequireJS
    define( 'outlayer/item',[
        'ev-emitter/ev-emitter',
        'get-size/get-size'
      ],
      factory
    );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS - Browserify, Webpack
    module.exports = factory(
      require('ev-emitter'),
      require('get-size')
    );
  } else {
    // browser global
    window.Outlayer = {};
    window.Outlayer.Item = factory(
      window.EvEmitter,
      window.getSize
    );
  }

}( window, function factory( EvEmitter, getSize ) {
'use strict';

// ----- helpers ----- //

function isEmptyObj( obj ) {
  for ( var prop in obj ) {
    return false;
  }
  prop = null;
  return true;
}

// -------------------------- CSS3 support -------------------------- //


var docElemStyle = document.documentElement.style;

var transitionProperty = typeof docElemStyle.transition == 'string' ?
  'transition' : 'WebkitTransition';
var transformProperty = typeof docElemStyle.transform == 'string' ?
  'transform' : 'WebkitTransform';

var transitionEndEvent = {
  WebkitTransition: 'webkitTransitionEnd',
  transition: 'transitionend'
}[ transitionProperty ];

// cache all vendor properties that could have vendor prefix
var vendorProperties = {
  transform: transformProperty,
  transition: transitionProperty,
  transitionDuration: transitionProperty + 'Duration',
  transitionProperty: transitionProperty + 'Property',
  transitionDelay: transitionProperty + 'Delay'
};

// -------------------------- Item -------------------------- //

function Item( element, layout ) {
  if ( !element ) {
    return;
  }

  this.element = element;
  // parent layout class, i.e. Masonry, Isotope, or Packery
  this.layout = layout;
  this.position = {
    x: 0,
    y: 0
  };

  this._create();
}

// inherit EvEmitter
var proto = Item.prototype = Object.create( EvEmitter.prototype );
proto.constructor = Item;

proto._create = function() {
  // transition objects
  this._transn = {
    ingProperties: {},
    clean: {},
    onEnd: {}
  };

  this.css({
    position: 'absolute'
  });
};

// trigger specified handler for event type
proto.handleEvent = function( event ) {
  var method = 'on' + event.type;
  if ( this[ method ] ) {
    this[ method ]( event );
  }
};

proto.getSize = function() {
  this.size = getSize( this.element );
};

/**
 * apply CSS styles to element
 * @param {Object} style
 */
proto.css = function( style ) {
  var elemStyle = this.element.style;

  for ( var prop in style ) {
    // use vendor property if available
    var supportedProp = vendorProperties[ prop ] || prop;
    elemStyle[ supportedProp ] = style[ prop ];
  }
};

 // measure position, and sets it
proto.getPosition = function() {
  var style = getComputedStyle( this.element );
  var isOriginLeft = this.layout._getOption('originLeft');
  var isOriginTop = this.layout._getOption('originTop');
  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
  // convert percent to pixels
  var layoutSize = this.layout.size;
  var x = xValue.indexOf('%') != -1 ?
    ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );
  var y = yValue.indexOf('%') != -1 ?
    ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );

  // clean up 'auto' or other non-integer values
  x = isNaN( x ) ? 0 : x;
  y = isNaN( y ) ? 0 : y;
  // remove padding from measurement
  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;

  this.position.x = x;
  this.position.y = y;
};

// set settled position, apply padding
proto.layoutPosition = function() {
  var layoutSize = this.layout.size;
  var style = {};
  var isOriginLeft = this.layout._getOption('originLeft');
  var isOriginTop = this.layout._getOption('originTop');

  // x
  var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
  var xProperty = isOriginLeft ? 'left' : 'right';
  var xResetProperty = isOriginLeft ? 'right' : 'left';

  var x = this.position.x + layoutSize[ xPadding ];
  // set in percentage or pixels
  style[ xProperty ] = this.getXValue( x );
  // reset other property
  style[ xResetProperty ] = '';

  // y
  var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
  var yProperty = isOriginTop ? 'top' : 'bottom';
  var yResetProperty = isOriginTop ? 'bottom' : 'top';

  var y = this.position.y + layoutSize[ yPadding ];
  // set in percentage or pixels
  style[ yProperty ] = this.getYValue( y );
  // reset other property
  style[ yResetProperty ] = '';

  this.css( style );
  this.emitEvent( 'layout', [ this ] );
};

proto.getXValue = function( x ) {
  var isHorizontal = this.layout._getOption('horizontal');
  return this.layout.options.percentPosition && !isHorizontal ?
    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
};

proto.getYValue = function( y ) {
  var isHorizontal = this.layout._getOption('horizontal');
  return this.layout.options.percentPosition && isHorizontal ?
    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
};

proto._transitionTo = function( x, y ) {
  this.getPosition();
  // get current x & y from top/left
  var curX = this.position.x;
  var curY = this.position.y;

  var compareX = parseInt( x, 10 );
  var compareY = parseInt( y, 10 );
  var didNotMove = compareX === this.position.x && compareY === this.position.y;

  // save end position
  this.setPosition( x, y );

  // if did not move and not transitioning, just go to layout
  if ( didNotMove && !this.isTransitioning ) {
    this.layoutPosition();
    return;
  }

  var transX = x - curX;
  var transY = y - curY;
  var transitionStyle = {};
  transitionStyle.transform = this.getTranslate( transX, transY );

  this.transition({
    to: transitionStyle,
    onTransitionEnd: {
      transform: this.layoutPosition
    },
    isCleaning: true
  });
};

proto.getTranslate = function( x, y ) {
  // flip cooridinates if origin on right or bottom
  var isOriginLeft = this.layout._getOption('originLeft');
  var isOriginTop = this.layout._getOption('originTop');
  x = isOriginLeft ? x : -x;
  y = isOriginTop ? y : -y;
  return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
};

// non transition + transform support
proto.goTo = function( x, y ) {
  this.setPosition( x, y );
  this.layoutPosition();
};

proto.moveTo = proto._transitionTo;

proto.setPosition = function( x, y ) {
  this.position.x = parseInt( x, 10 );
  this.position.y = parseInt( y, 10 );
};

// ----- transition ----- //

/**
 * @param {Object} style - CSS
 * @param {Function} onTransitionEnd
 */

// non transition, just trigger callback
proto._nonTransition = function( args ) {
  this.css( args.to );
  if ( args.isCleaning ) {
    this._removeStyles( args.to );
  }
  for ( var prop in args.onTransitionEnd ) {
    args.onTransitionEnd[ prop ].call( this );
  }
};

/**
 * proper transition
 * @param {Object} args - arguments
 *   @param {Object} to - style to transition to
 *   @param {Object} from - style to start transition from
 *   @param {Boolean} isCleaning - removes transition styles after transition
 *   @param {Function} onTransitionEnd - callback
 */
proto.transition = function( args ) {
  // redirect to nonTransition if no transition duration
  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
    this._nonTransition( args );
    return;
  }

  var _transition = this._transn;
  // keep track of onTransitionEnd callback by css property
  for ( var prop in args.onTransitionEnd ) {
    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
  }
  // keep track of properties that are transitioning
  for ( prop in args.to ) {
    _transition.ingProperties[ prop ] = true;
    // keep track of properties to clean up when transition is done
    if ( args.isCleaning ) {
      _transition.clean[ prop ] = true;
    }
  }

  // set from styles
  if ( args.from ) {
    this.css( args.from );
    // force redraw. http://blog.alexmaccaw.com/css-transitions
    var h = this.element.offsetHeight;
    // hack for JSHint to hush about unused var
    h = null;
  }
  // enable transition
  this.enableTransition( args.to );
  // set styles that are transitioning
  this.css( args.to );

  this.isTransitioning = true;

};

// dash before all cap letters, including first for
// WebkitTransform => -webkit-transform
function toDashedAll( str ) {
  return str.replace( /([A-Z])/g, function( $1 ) {
    return '-' + $1.toLowerCase();
  });
}

var transitionProps = 'opacity,' + toDashedAll( transformProperty );

proto.enableTransition = function(/* style */) {
  // HACK changing transitionProperty during a transition
  // will cause transition to jump
  if ( this.isTransitioning ) {
    return;
  }

  // make `transition: foo, bar, baz` from style object
  // HACK un-comment this when enableTransition can work
  // while a transition is happening
  // var transitionValues = [];
  // for ( var prop in style ) {
  //   // dash-ify camelCased properties like WebkitTransition
  //   prop = vendorProperties[ prop ] || prop;
  //   transitionValues.push( toDashedAll( prop ) );
  // }
  // munge number to millisecond, to match stagger
  var duration = this.layout.options.transitionDuration;
  duration = typeof duration == 'number' ? duration + 'ms' : duration;
  // enable transition styles
  this.css({
    transitionProperty: transitionProps,
    transitionDuration: duration,
    transitionDelay: this.staggerDelay || 0
  });
  // listen for transition end event
  this.element.addEventListener( transitionEndEvent, this, false );
};

// ----- events ----- //

proto.onwebkitTransitionEnd = function( event ) {
  this.ontransitionend( event );
};

proto.onotransitionend = function( event ) {
  this.ontransitionend( event );
};

// properties that I munge to make my life easier
var dashedVendorProperties = {
  '-webkit-transform': 'transform'
};

proto.ontransitionend = function( event ) {
  // disregard bubbled events from children
  if ( event.target !== this.element ) {
    return;
  }
  var _transition = this._transn;
  // get property name of transitioned property, convert to prefix-free
  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;

  // remove property that has completed transitioning
  delete _transition.ingProperties[ propertyName ];
  // check if any properties are still transitioning
  if ( isEmptyObj( _transition.ingProperties ) ) {
    // all properties have completed transitioning
    this.disableTransition();
  }
  // clean style
  if ( propertyName in _transition.clean ) {
    // clean up style
    this.element.style[ event.propertyName ] = '';
    delete _transition.clean[ propertyName ];
  }
  // trigger onTransitionEnd callback
  if ( propertyName in _transition.onEnd ) {
    var onTransitionEnd = _transition.onEnd[ propertyName ];
    onTransitionEnd.call( this );
    delete _transition.onEnd[ propertyName ];
  }

  this.emitEvent( 'transitionEnd', [ this ] );
};

proto.disableTransition = function() {
  this.removeTransitionStyles();
  this.element.removeEventListener( transitionEndEvent, this, false );
  this.isTransitioning = false;
};

/**
 * removes style property from element
 * @param {Object} style
**/
proto._removeStyles = function( style ) {
  // clean up transition styles
  var cleanStyle = {};
  for ( var prop in style ) {
    cleanStyle[ prop ] = '';
  }
  this.css( cleanStyle );
};

var cleanTransitionStyle = {
  transitionProperty: '',
  transitionDuration: '',
  transitionDelay: ''
};

proto.removeTransitionStyles = function() {
  // remove transition
  this.css( cleanTransitionStyle );
};

// ----- stagger ----- //

proto.stagger = function( delay ) {
  delay = isNaN( delay ) ? 0 : delay;
  this.staggerDelay = delay + 'ms';
};

// ----- show/hide/remove ----- //

// remove element from DOM
proto.removeElem = function() {
  this.element.parentNode.removeChild( this.element );
  // remove display: none
  this.css({ display: '' });
  this.emitEvent( 'remove', [ this ] );
};

proto.remove = function() {
  // just remove element if no transition support or no transition
  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
    this.removeElem();
    return;
  }

  // start transition
  this.once( 'transitionEnd', function() {
    this.removeElem();
  });
  this.hide();
};

proto.reveal = function() {
  delete this.isHidden;
  // remove display: none
  this.css({ display: '' });

  var options = this.layout.options;

  var onTransitionEnd = {};
  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;

  this.transition({
    from: options.hiddenStyle,
    to: options.visibleStyle,
    isCleaning: true,
    onTransitionEnd: onTransitionEnd
  });
};

proto.onRevealTransitionEnd = function() {
  // check if still visible
  // during transition, item may have been hidden
  if ( !this.isHidden ) {
    this.emitEvent('reveal');
  }
};

/**
 * get style property use for hide/reveal transition end
 * @param {String} styleProperty - hiddenStyle/visibleStyle
 * @returns {String}
 */
proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
  var optionStyle = this.layout.options[ styleProperty ];
  // use opacity
  if ( optionStyle.opacity ) {
    return 'opacity';
  }
  // get first property
  for ( var prop in optionStyle ) {
    return prop;
  }
};

proto.hide = function() {
  // set flag
  this.isHidden = true;
  // remove display: none
  this.css({ display: '' });

  var options = this.layout.options;

  var onTransitionEnd = {};
  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;

  this.transition({
    from: options.visibleStyle,
    to: options.hiddenStyle,
    // keep hidden stuff hidden
    isCleaning: true,
    onTransitionEnd: onTransitionEnd
  });
};

proto.onHideTransitionEnd = function() {
  // check if still hidden
  // during transition, item may have been un-hidden
  if ( this.isHidden ) {
    this.css({ display: 'none' });
    this.emitEvent('hide');
  }
};

proto.destroy = function() {
  this.css({
    position: '',
    left: '',
    right: '',
    top: '',
    bottom: '',
    transition: '',
    transform: ''
  });
};

return Item;

}));

/*!
 * Outlayer v2.1.0
 * the brains and guts of a layout library
 * MIT license
 */

( function( window, factory ) {
  'use strict';
  // universal module definition
  /* jshint strict: false */ /* globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD - RequireJS
    define( 'outlayer/outlayer',[
        'ev-emitter/ev-emitter',
        'get-size/get-size',
        'fizzy-ui-utils/utils',
        './item'
      ],
      function( EvEmitter, getSize, utils, Item ) {
        return factory( window, EvEmitter, getSize, utils, Item);
      }
    );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS - Browserify, Webpack
    module.exports = factory(
      window,
      require('ev-emitter'),
      require('get-size'),
      require('fizzy-ui-utils'),
      require('./item')
    );
  } else {
    // browser global
    window.Outlayer = factory(
      window,
      window.EvEmitter,
      window.getSize,
      window.fizzyUIUtils,
      window.Outlayer.Item
    );
  }

}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
'use strict';

// ----- vars ----- //

var console = window.console;
var jQuery = window.jQuery;
var noop = function() {};

// -------------------------- Outlayer -------------------------- //

// globally unique identifiers
var GUID = 0;
// internal store of all Outlayer intances
var instances = {};


/**
 * @param {Element, String} element
 * @param {Object} options
 * @constructor
 */
function Outlayer( element, options ) {
  var queryElement = utils.getQueryElement( element );
  if ( !queryElement ) {
    if ( console ) {
      console.error( 'Bad element for ' + this.constructor.namespace +
        ': ' + ( queryElement || element ) );
    }
    return;
  }
  this.element = queryElement;
  // add jQuery
  if ( jQuery ) {
    this.$element = jQuery( this.element );
  }

  // options
  this.options = utils.extend( {}, this.constructor.defaults );
  this.option( options );

  // add id for Outlayer.getFromElement
  var id = ++GUID;
  this.element.outlayerGUID = id; // expando
  instances[ id ] = this; // associate via id

  // kick it off
  this._create();

  var isInitLayout = this._getOption('initLayout');
  if ( isInitLayout ) {
    this.layout();
  }
}

// settings are for internal use only
Outlayer.namespace = 'outlayer';
Outlayer.Item = Item;

// default options
Outlayer.defaults = {
  containerStyle: {
    position: 'relative'
  },
  initLayout: true,
  originLeft: true,
  originTop: true,
  resize: true,
  resizeContainer: true,
  // item options
  transitionDuration: '0.4s',
  hiddenStyle: {
    opacity: 0,
    transform: 'scale(0.001)'
  },
  visibleStyle: {
    opacity: 1,
    transform: 'scale(1)'
  }
};

var proto = Outlayer.prototype;
// inherit EvEmitter
utils.extend( proto, EvEmitter.prototype );

/**
 * set options
 * @param {Object} opts
 */
proto.option = function( opts ) {
  utils.extend( this.options, opts );
};

/**
 * get backwards compatible option value, check old name
 */
proto._getOption = function( option ) {
  var oldOption = this.constructor.compatOptions[ option ];
  return oldOption && this.options[ oldOption ] !== undefined ?
    this.options[ oldOption ] : this.options[ option ];
};

Outlayer.compatOptions = {
  // currentName: oldName
  initLayout: 'isInitLayout',
  horizontal: 'isHorizontal',
  layoutInstant: 'isLayoutInstant',
  originLeft: 'isOriginLeft',
  originTop: 'isOriginTop',
  resize: 'isResizeBound',
  resizeContainer: 'isResizingContainer'
};

proto._create = function() {
  // get items from children
  this.reloadItems();
  // elements that affect layout, but are not laid out
  this.stamps = [];
  this.stamp( this.options.stamp );
  // set container style
  utils.extend( this.element.style, this.options.containerStyle );

  // bind resize method
  var canBindResize = this._getOption('resize');
  if ( canBindResize ) {
    this.bindResize();
  }
};

// goes through all children again and gets bricks in proper order
proto.reloadItems = function() {
  // collection of item elements
  this.items = this._itemize( this.element.children );
};


/**
 * turn elements into Outlayer.Items to be used in layout
 * @param {Array or NodeList or HTMLElement} elems
 * @returns {Array} items - collection of new Outlayer Items
 */
proto._itemize = function( elems ) {

  var itemElems = this._filterFindItemElements( elems );
  var Item = this.constructor.Item;

  // create new Outlayer Items for collection
  var items = [];
  for ( var i=0; i < itemElems.length; i++ ) {
    var elem = itemElems[i];
    var item = new Item( elem, this );
    items.push( item );
  }

  return items;
};

/**
 * get item elements to be used in layout
 * @param {Array or NodeList or HTMLElement} elems
 * @returns {Array} items - item elements
 */
proto._filterFindItemElements = function( elems ) {
  return utils.filterFindElements( elems, this.options.itemSelector );
};

/**
 * getter method for getting item elements
 * @returns {Array} elems - collection of item elements
 */
proto.getItemElements = function() {
  return this.items.map( function( item ) {
    return item.element;
  });
};

// ----- init & layout ----- //

/**
 * lays out all items
 */
proto.layout = function() {
  this._resetLayout();
  this._manageStamps();

  // don't animate first layout
  var layoutInstant = this._getOption('layoutInstant');
  var isInstant = layoutInstant !== undefined ?
    layoutInstant : !this._isLayoutInited;
  this.layoutItems( this.items, isInstant );

  // flag for initalized
  this._isLayoutInited = true;
};

// _init is alias for layout
proto._init = proto.layout;

/**
 * logic before any new layout
 */
proto._resetLayout = function() {
  this.getSize();
};


proto.getSize = function() {
  this.size = getSize( this.element );
};

/**
 * get measurement from option, for columnWidth, rowHeight, gutter
 * if option is String -> get element from selector string, & get size of element
 * if option is Element -> get size of element
 * else use option as a number
 *
 * @param {String} measurement
 * @param {String} size - width or height
 * @private
 */
proto._getMeasurement = function( measurement, size ) {
  var option = this.options[ measurement ];
  var elem;
  if ( !option ) {
    // default to 0
    this[ measurement ] = 0;
  } else {
    // use option as an element
    if ( typeof option == 'string' ) {
      elem = this.element.querySelector( option );
    } else if ( option instanceof HTMLElement ) {
      elem = option;
    }
    // use size of element, if element
    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
  }
};

/**
 * layout a collection of item elements
 * @api public
 */
proto.layoutItems = function( items, isInstant ) {
  items = this._getItemsForLayout( items );

  this._layoutItems( items, isInstant );

  this._postLayout();
};

/**
 * get the items to be laid out
 * you may want to skip over some items
 * @param {Array} items
 * @returns {Array} items
 */
proto._getItemsForLayout = function( items ) {
  return items.filter( function( item ) {
    return !item.isIgnored;
  });
};

/**
 * layout items
 * @param {Array} items
 * @param {Boolean} isInstant
 */
proto._layoutItems = function( items, isInstant ) {
  this._emitCompleteOnItems( 'layout', items );

  if ( !items || !items.length ) {
    // no items, emit event with empty array
    return;
  }

  var queue = [];

  items.forEach( function( item ) {
    // get x/y object from method
    var position = this._getItemLayoutPosition( item );
    // enqueue
    position.item = item;
    position.isInstant = isInstant || item.isLayoutInstant;
    queue.push( position );
  }, this );

  this._processLayoutQueue( queue );
};

/**
 * get item layout position
 * @param {Outlayer.Item} item
 * @returns {Object} x and y position
 */
proto._getItemLayoutPosition = function( /* item */ ) {
  return {
    x: 0,
    y: 0
  };
};

/**
 * iterate over array and position each item
 * Reason being - separating this logic prevents 'layout invalidation'
 * thx @paul_irish
 * @param {Array} queue
 */
proto._processLayoutQueue = function( queue ) {
  this.updateStagger();
  queue.forEach( function( obj, i ) {
    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
  }, this );
};

// set stagger from option in milliseconds number
proto.updateStagger = function() {
  var stagger = this.options.stagger;
  if ( stagger === null || stagger === undefined ) {
    this.stagger = 0;
    return;
  }
  this.stagger = getMilliseconds( stagger );
  return this.stagger;
};

/**
 * Sets position of item in DOM
 * @param {Outlayer.Item} item
 * @param {Number} x - horizontal position
 * @param {Number} y - vertical position
 * @param {Boolean} isInstant - disables transitions
 */
proto._positionItem = function( item, x, y, isInstant, i ) {
  if ( isInstant ) {
    // if not transition, just set CSS
    item.goTo( x, y );
  } else {
    item.stagger( i * this.stagger );
    item.moveTo( x, y );
  }
};

/**
 * Any logic you want to do after each layout,
 * i.e. size the container
 */
proto._postLayout = function() {
  this.resizeContainer();
};

proto.resizeContainer = function() {
  var isResizingContainer = this._getOption('resizeContainer');
  if ( !isResizingContainer ) {
    return;
  }
  var size = this._getContainerSize();
  if ( size ) {
    this._setContainerMeasure( size.width, true );
    this._setContainerMeasure( size.height, false );
  }
};

/**
 * Sets width or height of container if returned
 * @returns {Object} size
 *   @param {Number} width
 *   @param {Number} height
 */
proto._getContainerSize = noop;

/**
 * @param {Number} measure - size of width or height
 * @param {Boolean} isWidth
 */
proto._setContainerMeasure = function( measure, isWidth ) {
  if ( measure === undefined ) {
    return;
  }

  var elemSize = this.size;
  // add padding and border width if border box
  if ( elemSize.isBorderBox ) {
    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
      elemSize.borderLeftWidth + elemSize.borderRightWidth :
      elemSize.paddingBottom + elemSize.paddingTop +
      elemSize.borderTopWidth + elemSize.borderBottomWidth;
  }

  measure = Math.max( measure, 0 );
  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
};

/**
 * emit eventComplete on a collection of items events
 * @param {String} eventName
 * @param {Array} items - Outlayer.Items
 */
proto._emitCompleteOnItems = function( eventName, items ) {
  var _this = this;
  function onComplete() {
    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
  }

  var count = items.length;
  if ( !items || !count ) {
    onComplete();
    return;
  }

  var doneCount = 0;
  function tick() {
    doneCount++;
    if ( doneCount == count ) {
      onComplete();
    }
  }

  // bind callback
  items.forEach( function( item ) {
    item.once( eventName, tick );
  });
};

/**
 * emits events via EvEmitter and jQuery events
 * @param {String} type - name of event
 * @param {Event} event - original event
 * @param {Array} args - extra arguments
 */
proto.dispatchEvent = function( type, event, args ) {
  // add original event to arguments
  var emitArgs = event ? [ event ].concat( args ) : args;
  this.emitEvent( type, emitArgs );

  if ( jQuery ) {
    // set this.$element
    this.$element = this.$element || jQuery( this.element );
    if ( event ) {
      // create jQuery event
      var $event = jQuery.Event( event );
      $event.type = type;
      this.$element.trigger( $event, args );
    } else {
      // just trigger with type if no event available
      this.$element.trigger( type, args );
    }
  }
};

// -------------------------- ignore & stamps -------------------------- //


/**
 * keep item in collection, but do not lay it out
 * ignored items do not get skipped in layout
 * @param {Element} elem
 */
proto.ignore = function( elem ) {
  var item = this.getItem( elem );
  if ( item ) {
    item.isIgnored = true;
  }
};

/**
 * return item to layout collection
 * @param {Element} elem
 */
proto.unignore = function( elem ) {
  var item = this.getItem( elem );
  if ( item ) {
    delete item.isIgnored;
  }
};

/**
 * adds elements to stamps
 * @param {NodeList, Array, Element, or String} elems
 */
proto.stamp = function( elems ) {
  elems = this._find( elems );
  if ( !elems ) {
    return;
  }

  this.stamps = this.stamps.concat( elems );
  // ignore
  elems.forEach( this.ignore, this );
};

/**
 * removes elements to stamps
 * @param {NodeList, Array, or Element} elems
 */
proto.unstamp = function( elems ) {
  elems = this._find( elems );
  if ( !elems ){
    return;
  }

  elems.forEach( function( elem ) {
    // filter out removed stamp elements
    utils.removeFrom( this.stamps, elem );
    this.unignore( elem );
  }, this );
};

/**
 * finds child elements
 * @param {NodeList, Array, Element, or String} elems
 * @returns {Array} elems
 */
proto._find = function( elems ) {
  if ( !elems ) {
    return;
  }
  // if string, use argument as selector string
  if ( typeof elems == 'string' ) {
    elems = this.element.querySelectorAll( elems );
  }
  elems = utils.makeArray( elems );
  return elems;
};

proto._manageStamps = function() {
  if ( !this.stamps || !this.stamps.length ) {
    return;
  }

  this._getBoundingRect();

  this.stamps.forEach( this._manageStamp, this );
};

// update boundingLeft / Top
proto._getBoundingRect = function() {
  // get bounding rect for container element
  var boundingRect = this.element.getBoundingClientRect();
  var size = this.size;
  this._boundingRect = {
    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
  };
};

/**
 * @param {Element} stamp
**/
proto._manageStamp = noop;

/**
 * get x/y position of element relative to container element
 * @param {Element} elem
 * @returns {Object} offset - has left, top, right, bottom
 */
proto._getElementOffset = function( elem ) {
  var boundingRect = elem.getBoundingClientRect();
  var thisRect = this._boundingRect;
  var size = getSize( elem );
  var offset = {
    left: boundingRect.left - thisRect.left - size.marginLeft,
    top: boundingRect.top - thisRect.top - size.marginTop,
    right: thisRect.right - boundingRect.right - size.marginRight,
    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
  };
  return offset;
};

// -------------------------- resize -------------------------- //

// enable event handlers for listeners
// i.e. resize -> onresize
proto.handleEvent = utils.handleEvent;

/**
 * Bind layout to window resizing
 */
proto.bindResize = function() {
  window.addEventListener( 'resize', this );
  this.isResizeBound = true;
};

/**
 * Unbind layout to window resizing
 */
proto.unbindResize = function() {
  window.removeEventListener( 'resize', this );
  this.isResizeBound = false;
};

proto.onresize = function() {
  this.resize();
};

utils.debounceMethod( Outlayer, 'onresize', 100 );

proto.resize = function() {
  // don't trigger if size did not change
  // or if resize was unbound. See #9
  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
    return;
  }

  this.layout();
};

/**
 * check if layout is needed post layout
 * @returns Boolean
 */
proto.needsResizeLayout = function() {
  var size = getSize( this.element );
  // check that this.size and size are there
  // IE8 triggers resize on body size change, so they might not be
  var hasSizes = this.size && size;
  return hasSizes && size.innerWidth !== this.size.innerWidth;
};

// -------------------------- methods -------------------------- //

/**
 * add items to Outlayer instance
 * @param {Array or NodeList or Element} elems
 * @returns {Array} items - Outlayer.Items
**/
proto.addItems = function( elems ) {
  var items = this._itemize( elems );
  // add items to collection
  if ( items.length ) {
    this.items = this.items.concat( items );
  }
  return items;
};

/**
 * Layout newly-appended item elements
 * @param {Array or NodeList or Element} elems
 */
proto.appended = function( elems ) {
  var items = this.addItems( elems );
  if ( !items.length ) {
    return;
  }
  // layout and reveal just the new items
  this.layoutItems( items, true );
  this.reveal( items );
};

/**
 * Layout prepended elements
 * @param {Array or NodeList or Element} elems
 */
proto.prepended = function( elems ) {
  var items = this._itemize( elems );
  if ( !items.length ) {
    return;
  }
  // add items to beginning of collection
  var previousItems = this.items.slice(0);
  this.items = items.concat( previousItems );
  // start new layout
  this._resetLayout();
  this._manageStamps();
  // layout new stuff without transition
  this.layoutItems( items, true );
  this.reveal( items );
  // layout previous items
  this.layoutItems( previousItems );
};

/**
 * reveal a collection of items
 * @param {Array of Outlayer.Items} items
 */
proto.reveal = function( items ) {
  this._emitCompleteOnItems( 'reveal', items );
  if ( !items || !items.length ) {
    return;
  }
  var stagger = this.updateStagger();
  items.forEach( function( item, i ) {
    item.stagger( i * stagger );
    item.reveal();
  });
};

/**
 * hide a collection of items
 * @param {Array of Outlayer.Items} items
 */
proto.hide = function( items ) {
  this._emitCompleteOnItems( 'hide', items );
  if ( !items || !items.length ) {
    return;
  }
  var stagger = this.updateStagger();
  items.forEach( function( item, i ) {
    item.stagger( i * stagger );
    item.hide();
  });
};

/**
 * reveal item elements
 * @param {Array}, {Element}, {NodeList} items
 */
proto.revealItemElements = function( elems ) {
  var items = this.getItems( elems );
  this.reveal( items );
};

/**
 * hide item elements
 * @param {Array}, {Element}, {NodeList} items
 */
proto.hideItemElements = function( elems ) {
  var items = this.getItems( elems );
  this.hide( items );
};

/**
 * get Outlayer.Item, given an Element
 * @param {Element} elem
 * @param {Function} callback
 * @returns {Outlayer.Item} item
 */
proto.getItem = function( elem ) {
  // loop through items to get the one that matches
  for ( var i=0; i < this.items.length; i++ ) {
    var item = this.items[i];
    if ( item.element == elem ) {
      // return item
      return item;
    }
  }
};

/**
 * get collection of Outlayer.Items, given Elements
 * @param {Array} elems
 * @returns {Array} items - Outlayer.Items
 */
proto.getItems = function( elems ) {
  elems = utils.makeArray( elems );
  var items = [];
  elems.forEach( function( elem ) {
    var item = this.getItem( elem );
    if ( item ) {
      items.push( item );
    }
  }, this );

  return items;
};

/**
 * remove element(s) from instance and DOM
 * @param {Array or NodeList or Element} elems
 */
proto.remove = function( elems ) {
  var removeItems = this.getItems( elems );

  this._emitCompleteOnItems( 'remove', removeItems );

  // bail if no items to remove
  if ( !removeItems || !removeItems.length ) {
    return;
  }

  removeItems.forEach( function( item ) {
    item.remove();
    // remove item from collection
    utils.removeFrom( this.items, item );
  }, this );
};

// ----- destroy ----- //

// remove and disable Outlayer instance
proto.destroy = function() {
  // clean up dynamic styles
  var style = this.element.style;
  style.height = '';
  style.position = '';
  style.width = '';
  // destroy items
  this.items.forEach( function( item ) {
    item.destroy();
  });

  this.unbindResize();

  var id = this.element.outlayerGUID;
  delete instances[ id ]; // remove reference to instance by id
  delete this.element.outlayerGUID;
  // remove data for jQuery
  if ( jQuery ) {
    jQuery.removeData( this.element, this.constructor.namespace );
  }

};

// -------------------------- data -------------------------- //

/**
 * get Outlayer instance from element
 * @param {Element} elem
 * @returns {Outlayer}
 */
Outlayer.data = function( elem ) {
  elem = utils.getQueryElement( elem );
  var id = elem && elem.outlayerGUID;
  return id && instances[ id ];
};


// -------------------------- create Outlayer class -------------------------- //

/**
 * create a layout class
 * @param {String} namespace
 */
Outlayer.create = function( namespace, options ) {
  // sub-class Outlayer
  var Layout = subclass( Outlayer );
  // apply new options and compatOptions
  Layout.defaults = utils.extend( {}, Outlayer.defaults );
  utils.extend( Layout.defaults, options );
  Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );

  Layout.namespace = namespace;

  Layout.data = Outlayer.data;

  // sub-class Item
  Layout.Item = subclass( Item );

  // -------------------------- declarative -------------------------- //

  utils.htmlInit( Layout, namespace );

  // -------------------------- jQuery bridge -------------------------- //

  // make into jQuery plugin
  if ( jQuery && jQuery.bridget ) {
    jQuery.bridget( namespace, Layout );
  }

  return Layout;
};

function subclass( Parent ) {
  function SubClass() {
    Parent.apply( this, arguments );
  }

  SubClass.prototype = Object.create( Parent.prototype );
  SubClass.prototype.constructor = SubClass;

  return SubClass;
}

// ----- helpers ----- //

// how many milliseconds are in each unit
var msUnits = {
  ms: 1,
  s: 1000
};

// munge time-like parameter into millisecond number
// '0.4s' -> 40
function getMilliseconds( time ) {
  if ( typeof time == 'number' ) {
    return time;
  }
  var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
  var num = matches && matches[1];
  var unit = matches && matches[2];
  if ( !num.length ) {
    return 0;
  }
  num = parseFloat( num );
  var mult = msUnits[ unit ] || 1;
  return num * mult;
}

// ----- fin ----- //

// back in global
Outlayer.Item = Item;

return Outlayer;

}));

/**
 * Isotope Item
**/

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'isotope/item',[
        'outlayer/outlayer'
      ],
      factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('outlayer')
    );
  } else {
    // browser global
    window.Isotope = window.Isotope || {};
    window.Isotope.Item = factory(
      window.Outlayer
    );
  }

}( window, function factory( Outlayer ) {
'use strict';

// -------------------------- Item -------------------------- //

// sub-class Outlayer Item
function Item() {
  Outlayer.Item.apply( this, arguments );
}

var proto = Item.prototype = Object.create( Outlayer.Item.prototype );

var _create = proto._create;
proto._create = function() {
  // assign id, used for original-order sorting
  this.id = this.layout.itemGUID++;
  _create.call( this );
  this.sortData = {};
};

proto.updateSortData = function() {
  if ( this.isIgnored ) {
    return;
  }
  // default sorters
  this.sortData.id = this.id;
  // for backward compatibility
  this.sortData['original-order'] = this.id;
  this.sortData.random = Math.random();
  // go thru getSortData obj and apply the sorters
  var getSortData = this.layout.options.getSortData;
  var sorters = this.layout._sorters;
  for ( var key in getSortData ) {
    var sorter = sorters[ key ];
    this.sortData[ key ] = sorter( this.element, this );
  }
};

var _destroy = proto.destroy;
proto.destroy = function() {
  // call super
  _destroy.apply( this, arguments );
  // reset display, #741
  this.css({
    display: ''
  });
};

return Item;

}));

/**
 * Isotope LayoutMode
 */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'isotope/layout-mode',[
        'get-size/get-size',
        'outlayer/outlayer'
      ],
      factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('get-size'),
      require('outlayer')
    );
  } else {
    // browser global
    window.Isotope = window.Isotope || {};
    window.Isotope.LayoutMode = factory(
      window.getSize,
      window.Outlayer
    );
  }

}( window, function factory( getSize, Outlayer ) {
  'use strict';

  // layout mode class
  function LayoutMode( isotope ) {
    this.isotope = isotope;
    // link properties
    if ( isotope ) {
      this.options = isotope.options[ this.namespace ];
      this.element = isotope.element;
      this.items = isotope.filteredItems;
      this.size = isotope.size;
    }
  }

  var proto = LayoutMode.prototype;

  /**
   * some methods should just defer to default Outlayer method
   * and reference the Isotope instance as `this`
  **/
  var facadeMethods = [
    '_resetLayout',
    '_getItemLayoutPosition',
    '_manageStamp',
    '_getContainerSize',
    '_getElementOffset',
    'needsResizeLayout',
    '_getOption'
  ];

  facadeMethods.forEach( function( methodName ) {
    proto[ methodName ] = function() {
      return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
    };
  });

  // -----  ----- //

  // for horizontal layout modes, check vertical size
  proto.needsVerticalResizeLayout = function() {
    // don't trigger if size did not change
    var size = getSize( this.isotope.element );
    // check that this.size and size are there
    // IE8 triggers resize on body size change, so they might not be
    var hasSizes = this.isotope.size && size;
    return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
  };

  // ----- measurements ----- //

  proto._getMeasurement = function() {
    this.isotope._getMeasurement.apply( this, arguments );
  };

  proto.getColumnWidth = function() {
    this.getSegmentSize( 'column', 'Width' );
  };

  proto.getRowHeight = function() {
    this.getSegmentSize( 'row', 'Height' );
  };

  /**
   * get columnWidth or rowHeight
   * segment: 'column' or 'row'
   * size 'Width' or 'Height'
  **/
  proto.getSegmentSize = function( segment, size ) {
    var segmentName = segment + size;
    var outerSize = 'outer' + size;
    // columnWidth / outerWidth // rowHeight / outerHeight
    this._getMeasurement( segmentName, outerSize );
    // got rowHeight or columnWidth, we can chill
    if ( this[ segmentName ] ) {
      return;
    }
    // fall back to item of first element
    var firstItemSize = this.getFirstItemSize();
    this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
      // or size of container
      this.isotope.size[ 'inner' + size ];
  };

  proto.getFirstItemSize = function() {
    var firstItem = this.isotope.filteredItems[0];
    return firstItem && firstItem.element && getSize( firstItem.element );
  };

  // ----- methods that should reference isotope ----- //

  proto.layout = function() {
    this.isotope.layout.apply( this.isotope, arguments );
  };

  proto.getSize = function() {
    this.isotope.getSize();
    this.size = this.isotope.size;
  };

  // -------------------------- create -------------------------- //

  LayoutMode.modes = {};

  LayoutMode.create = function( namespace, options ) {

    function Mode() {
      LayoutMode.apply( this, arguments );
    }

    Mode.prototype = Object.create( proto );
    Mode.prototype.constructor = Mode;

    // default options
    if ( options ) {
      Mode.options = options;
    }

    Mode.prototype.namespace = namespace;
    // register in Isotope
    LayoutMode.modes[ namespace ] = Mode;

    return Mode;
  };

  return LayoutMode;

}));

/*!
 * Masonry v4.1.0
 * Cascading grid layout library
 * http://masonry.desandro.com
 * MIT License
 * by David DeSandro
 */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'masonry/masonry',[
        'outlayer/outlayer',
        'get-size/get-size'
      ],
      factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('outlayer'),
      require('get-size')
    );
  } else {
    // browser global
    window.Masonry = factory(
      window.Outlayer,
      window.getSize
    );
  }

}( window, function factory( Outlayer, getSize ) {



// -------------------------- masonryDefinition -------------------------- //

  // create an Outlayer layout class
  var Masonry = Outlayer.create('masonry');
  // isFitWidth -> fitWidth
  Masonry.compatOptions.fitWidth = 'isFitWidth';

  Masonry.prototype._resetLayout = function() {
    this.getSize();
    this._getMeasurement( 'columnWidth', 'outerWidth' );
    this._getMeasurement( 'gutter', 'outerWidth' );
    this.measureColumns();

    // reset column Y
    this.colYs = [];
    for ( var i=0; i < this.cols; i++ ) {
      this.colYs.push( 0 );
    }

    this.maxY = 0;
  };

  Masonry.prototype.measureColumns = function() {
    this.getContainerWidth();
    // if columnWidth is 0, default to outerWidth of first item
    if ( !this.columnWidth ) {
      var firstItem = this.items[0];
      var firstItemElem = firstItem && firstItem.element;
      // columnWidth fall back to item of first element
      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
        // if first elem has no width, default to size of container
        this.containerWidth;
    }

    var columnWidth = this.columnWidth += this.gutter;

    // calculate columns
    var containerWidth = this.containerWidth + this.gutter;
    var cols = containerWidth / columnWidth;
    // fix rounding errors, typically with gutters
    var excess = columnWidth - containerWidth % columnWidth;
    // if overshoot is less than a pixel, round up, otherwise floor it
    var mathMethod = excess && excess < 1 ? 'round' : 'floor';
    cols = Math[ mathMethod ]( cols );
    this.cols = Math.max( cols, 1 );
  };

  Masonry.prototype.getContainerWidth = function() {
    // container is parent if fit width
    var isFitWidth = this._getOption('fitWidth');
    var container = isFitWidth ? this.element.parentNode : this.element;
    // check that this.size and size are there
    // IE8 triggers resize on body size change, so they might not be
    var size = getSize( container );
    this.containerWidth = size && size.innerWidth;
  };

  Masonry.prototype._getItemLayoutPosition = function( item ) {
    item.getSize();
    // how many columns does this brick span
    var remainder = item.size.outerWidth % this.columnWidth;
    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
    // round if off by 1 pixel, otherwise use ceil
    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
    colSpan = Math.min( colSpan, this.cols );

    var colGroup = this._getColGroup( colSpan );
    // get the minimum Y value from the columns
    var minimumY = Math.min.apply( Math, colGroup );
    var shortColIndex = colGroup.indexOf( minimumY );

    // position the brick
    var position = {
      x: this.columnWidth * shortColIndex,
      y: minimumY
    };

    // apply setHeight to necessary columns
    var setHeight = minimumY + item.size.outerHeight;
    var setSpan = this.cols + 1 - colGroup.length;
    for ( var i = 0; i < setSpan; i++ ) {
      this.colYs[ shortColIndex + i ] = setHeight;
    }

    return position;
  };

  /**
   * @param {Number} colSpan - number of columns the element spans
   * @returns {Array} colGroup
   */
  Masonry.prototype._getColGroup = function( colSpan ) {
    if ( colSpan < 2 ) {
      // if brick spans only one column, use all the column Ys
      return this.colYs;
    }

    var colGroup = [];
    // how many different places could this brick fit horizontally
    var groupCount = this.cols + 1 - colSpan;
    // for each group potential horizontal position
    for ( var i = 0; i < groupCount; i++ ) {
      // make an array of colY values for that one group
      var groupColYs = this.colYs.slice( i, i + colSpan );
      // and get the max value of the array
      colGroup[i] = Math.max.apply( Math, groupColYs );
    }
    return colGroup;
  };

  Masonry.prototype._manageStamp = function( stamp ) {
    var stampSize = getSize( stamp );
    var offset = this._getElementOffset( stamp );
    // get the columns that this stamp affects
    var isOriginLeft = this._getOption('originLeft');
    var firstX = isOriginLeft ? offset.left : offset.right;
    var lastX = firstX + stampSize.outerWidth;
    var firstCol = Math.floor( firstX / this.columnWidth );
    firstCol = Math.max( 0, firstCol );
    var lastCol = Math.floor( lastX / this.columnWidth );
    // lastCol should not go over if multiple of columnWidth #425
    lastCol -= lastX % this.columnWidth ? 0 : 1;
    lastCol = Math.min( this.cols - 1, lastCol );
    // set colYs to bottom of the stamp

    var isOriginTop = this._getOption('originTop');
    var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
      stampSize.outerHeight;
    for ( var i = firstCol; i <= lastCol; i++ ) {
      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
    }
  };

  Masonry.prototype._getContainerSize = function() {
    this.maxY = Math.max.apply( Math, this.colYs );
    var size = {
      height: this.maxY
    };

    if ( this._getOption('fitWidth') ) {
      size.width = this._getContainerFitWidth();
    }

    return size;
  };

  Masonry.prototype._getContainerFitWidth = function() {
    var unusedCols = 0;
    // count unused columns
    var i = this.cols;
    while ( --i ) {
      if ( this.colYs[i] !== 0 ) {
        break;
      }
      unusedCols++;
    }
    // fit container to columns that have been used
    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
  };

  Masonry.prototype.needsResizeLayout = function() {
    var previousWidth = this.containerWidth;
    this.getContainerWidth();
    return previousWidth != this.containerWidth;
  };

  return Masonry;

}));

/*!
 * Masonry layout mode
 * sub-classes Masonry
 * http://masonry.desandro.com
 */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'isotope/layout-modes/masonry',[
        '../layout-mode',
        'masonry/masonry'
      ],
      factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('../layout-mode'),
      require('masonry-layout')
    );
  } else {
    // browser global
    factory(
      window.Isotope.LayoutMode,
      window.Masonry
    );
  }

}( window, function factory( LayoutMode, Masonry ) {
'use strict';

// -------------------------- masonryDefinition -------------------------- //

  // create an Outlayer layout class
  var MasonryMode = LayoutMode.create('masonry');

  var proto = MasonryMode.prototype;

  var keepModeMethods = {
    _getElementOffset: true,
    layout: true,
    _getMeasurement: true
  };

  // inherit Masonry prototype
  for ( var method in Masonry.prototype ) {
    // do not inherit mode methods
    if ( !keepModeMethods[ method ] ) {
      proto[ method ] = Masonry.prototype[ method ];
    }
  }

  var measureColumns = proto.measureColumns;
  proto.measureColumns = function() {
    // set items, used if measuring first item
    this.items = this.isotope.filteredItems;
    measureColumns.call( this );
  };

  // point to mode options for fitWidth
  var _getOption = proto._getOption;
  proto._getOption = function( option ) {
    if ( option == 'fitWidth' ) {
      return this.options.isFitWidth !== undefined ?
        this.options.isFitWidth : this.options.fitWidth;
    }
    return _getOption.apply( this.isotope, arguments );
  };

  return MasonryMode;

}));

/**
 * fitRows layout mode
 */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'isotope/layout-modes/fit-rows',[
        '../layout-mode'
      ],
      factory );
  } else if ( typeof exports == 'object' ) {
    // CommonJS
    module.exports = factory(
      require('../layout-mode')
    );
  } else {
    // browser global
    factory(
      window.Isotope.LayoutMode
    );
  }

}( window, function factory( LayoutMode ) {
'use strict';

var FitRows = LayoutMode.create('fitRows');

var proto = FitRows.prototype;

proto._resetLayout = function() {
  this.x = 0;
  this.y = 0;
  this.maxY = 0;
  this._getMeasurement( 'gutter', 'outerWidth' );
};

proto._getItemLayoutPosition = function( item ) {
  item.getSize();

  var itemWidth = item.size.outerWidth + this.gutter;
  // if this element cannot fit in the current row
  var containerWidth = this.isotope.size.innerWidth + this.gutter;
  if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
    this.x = 0;
    this.y = this.maxY;
  }

  var position = {
    x: this.x,
    y: this.y
  };

  this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
  this.x += itemWidth;

  return position;
};

proto._getContainerSize = function() {
  return { height: this.maxY };
};

return FitRows;

}));

/**
 * vertical layout mode
 */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( 'isotope/layout-modes/vertical',[
        '../layout-mode'
      ],
      factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('../layout-mode')
    );
  } else {
    // browser global
    factory(
      window.Isotope.LayoutMode
    );
  }

}( window, function factory( LayoutMode ) {
'use strict';

var Vertical = LayoutMode.create( 'vertical', {
  horizontalAlignment: 0
});

var proto = Vertical.prototype;

proto._resetLayout = function() {
  this.y = 0;
};

proto._getItemLayoutPosition = function( item ) {
  item.getSize();
  var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
    this.options.horizontalAlignment;
  var y = this.y;
  this.y += item.size.outerHeight;
  return { x: x, y: y };
};

proto._getContainerSize = function() {
  return { height: this.y };
};

return Vertical;

}));

/*!
 * Isotope v3.0.0
 *
 * Licensed GPLv3 for open source use
 * or Isotope Commercial License for commercial use
 *
 * http://isotope.metafizzy.co
 * Copyright 2016 Metafizzy
 */

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( [
        'outlayer/outlayer',
        'get-size/get-size',
        'desandro-matches-selector/matches-selector',
        'fizzy-ui-utils/utils',
        './item',
        './layout-mode',
        // include default layout modes
        './layout-modes/masonry',
        './layout-modes/fit-rows',
        './layout-modes/vertical'
      ],
      function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
        return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
      });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('outlayer'),
      require('get-size'),
      require('desandro-matches-selector'),
      require('fizzy-ui-utils'),
      require('./item'),
      require('./layout-mode'),
      // include default layout modes
      require('./layout-modes/masonry'),
      require('./layout-modes/fit-rows'),
      require('./layout-modes/vertical')
    );
  } else {
    // browser global
    window.Isotope = factory(
      window,
      window.Outlayer,
      window.getSize,
      window.matchesSelector,
      window.fizzyUIUtils,
      window.Isotope.Item,
      window.Isotope.LayoutMode
    );
  }

}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
  Item, LayoutMode ) {



// -------------------------- vars -------------------------- //

var jQuery = window.jQuery;

// -------------------------- helpers -------------------------- //

var trim = String.prototype.trim ?
  function( str ) {
    return str.trim();
  } :
  function( str ) {
    return str.replace( /^\s+|\s+$/g, '' );
  };

// -------------------------- isotopeDefinition -------------------------- //

  // create an Outlayer layout class
  var Isotope = Outlayer.create( 'isotope', {
    layoutMode: 'masonry',
    isJQueryFiltering: true,
    sortAscending: true
  });

  Isotope.Item = Item;
  Isotope.LayoutMode = LayoutMode;

  var proto = Isotope.prototype;

  proto._create = function() {
    this.itemGUID = 0;
    // functions that sort items
    this._sorters = {};
    this._getSorters();
    // call super
    Outlayer.prototype._create.call( this );

    // create layout modes
    this.modes = {};
    // start filteredItems with all items
    this.filteredItems = this.items;
    // keep of track of sortBys
    this.sortHistory = [ 'original-order' ];
    // create from registered layout modes
    for ( var name in LayoutMode.modes ) {
      this._initLayoutMode( name );
    }
  };

  proto.reloadItems = function() {
    // reset item ID counter
    this.itemGUID = 0;
    // call super
    Outlayer.prototype.reloadItems.call( this );
  };

  proto._itemize = function() {
    var items = Outlayer.prototype._itemize.apply( this, arguments );
    // assign ID for original-order
    for ( var i=0; i < items.length; i++ ) {
      var item = items[i];
      item.id = this.itemGUID++;
    }
    this._updateItemsSortData( items );
    return items;
  };


  // -------------------------- layout -------------------------- //

  proto._initLayoutMode = function( name ) {
    var Mode = LayoutMode.modes[ name ];
    // set mode options
    // HACK extend initial options, back-fill in default options
    var initialOpts = this.options[ name ] || {};
    this.options[ name ] = Mode.options ?
      utils.extend( Mode.options, initialOpts ) : initialOpts;
    // init layout mode instance
    this.modes[ name ] = new Mode( this );
  };


  proto.layout = function() {
    // if first time doing layout, do all magic
    if ( !this._isLayoutInited && this._getOption('initLayout') ) {
      this.arrange();
      return;
    }
    this._layout();
  };

  // private method to be used in layout() & magic()
  proto._layout = function() {
    // don't animate first layout
    var isInstant = this._getIsInstant();
    // layout flow
    this._resetLayout();
    this._manageStamps();
    this.layoutItems( this.filteredItems, isInstant );

    // flag for initalized
    this._isLayoutInited = true;
  };

  // filter + sort + layout
  proto.arrange = function( opts ) {
    // set any options pass
    this.option( opts );
    this._getIsInstant();
    // filter, sort, and layout

    // filter
    var filtered = this._filter( this.items );
    this.filteredItems = filtered.matches;

    this._bindArrangeComplete();

    if ( this._isInstant ) {
      this._noTransition( this._hideReveal, [ filtered ] );
    } else {
      this._hideReveal( filtered );
    }

    this._sort();
    this._layout();
  };
  // alias to _init for main plugin method
  proto._init = proto.arrange;

  proto._hideReveal = function( filtered ) {
    this.reveal( filtered.needReveal );
    this.hide( filtered.needHide );
  };

  // HACK
  // Don't animate/transition first layout
  // Or don't animate/transition other layouts
  proto._getIsInstant = function() {
    var isLayoutInstant = this._getOption('layoutInstant');
    var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
      !this._isLayoutInited;
    this._isInstant = isInstant;
    return isInstant;
  };

  // listen for layoutComplete, hideComplete and revealComplete
  // to trigger arrangeComplete
  proto._bindArrangeComplete = function() {
    // listen for 3 events to trigger arrangeComplete
    var isLayoutComplete, isHideComplete, isRevealComplete;
    var _this = this;
    function arrangeParallelCallback() {
      if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
        _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
      }
    }
    this.once( 'layoutComplete', function() {
      isLayoutComplete = true;
      arrangeParallelCallback();
    });
    this.once( 'hideComplete', function() {
      isHideComplete = true;
      arrangeParallelCallback();
    });
    this.once( 'revealComplete', function() {
      isRevealComplete = true;
      arrangeParallelCallback();
    });
  };

  // -------------------------- filter -------------------------- //

  proto._filter = function( items ) {
    var filter = this.options.filter;
    filter = filter || '*';
    var matches = [];
    var hiddenMatched = [];
    var visibleUnmatched = [];

    var test = this._getFilterTest( filter );

    // test each item
    for ( var i=0; i < items.length; i++ ) {
      var item = items[i];
      if ( item.isIgnored ) {
        continue;
      }
      // add item to either matched or unmatched group
      var isMatched = test( item );
      // item.isFilterMatched = isMatched;
      // add to matches if its a match
      if ( isMatched ) {
        matches.push( item );
      }
      // add to additional group if item needs to be hidden or revealed
      if ( isMatched && item.isHidden ) {
        hiddenMatched.push( item );
      } else if ( !isMatched && !item.isHidden ) {
        visibleUnmatched.push( item );
      }
    }

    // return collections of items to be manipulated
    return {
      matches: matches,
      needReveal: hiddenMatched,
      needHide: visibleUnmatched
    };
  };

  // get a jQuery, function, or a matchesSelector test given the filter
  proto._getFilterTest = function( filter ) {
    if ( jQuery && this.options.isJQueryFiltering ) {
      // use jQuery
      return function( item ) {
        return jQuery( item.element ).is( filter );
      };
    }
    if ( typeof filter == 'function' ) {
      // use filter as function
      return function( item ) {
        return filter( item.element );
      };
    }
    // default, use filter as selector string
    return function( item ) {
      return matchesSelector( item.element, filter );
    };
  };

  // -------------------------- sorting -------------------------- //

  /**
   * @params {Array} elems
   * @public
   */
  proto.updateSortData = function( elems ) {
    // get items
    var items;
    if ( elems ) {
      elems = utils.makeArray( elems );
      items = this.getItems( elems );
    } else {
      // update all items if no elems provided
      items = this.items;
    }

    this._getSorters();
    this._updateItemsSortData( items );
  };

  proto._getSorters = function() {
    var getSortData = this.options.getSortData;
    for ( var key in getSortData ) {
      var sorter = getSortData[ key ];
      this._sorters[ key ] = mungeSorter( sorter );
    }
  };

  /**
   * @params {Array} items - of Isotope.Items
   * @private
   */
  proto._updateItemsSortData = function( items ) {
    // do not update if no items
    var len = items && items.length;

    for ( var i=0; len && i < len; i++ ) {
      var item = items[i];
      item.updateSortData();
    }
  };

  // ----- munge sorter ----- //

  // encapsulate this, as we just need mungeSorter
  // other functions in here are just for munging
  var mungeSorter = ( function() {
    // add a magic layer to sorters for convienent shorthands
    // `.foo-bar` will use the text of .foo-bar querySelector
    // `[foo-bar]` will use attribute
    // you can also add parser
    // `.foo-bar parseInt` will parse that as a number
    function mungeSorter( sorter ) {
      // if not a string, return function or whatever it is
      if ( typeof sorter != 'string' ) {
        return sorter;
      }
      // parse the sorter string
      var args = trim( sorter ).split(' ');
      var query = args[0];
      // check if query looks like [an-attribute]
      var attrMatch = query.match( /^\[(.+)\]$/ );
      var attr = attrMatch && attrMatch[1];
      var getValue = getValueGetter( attr, query );
      // use second argument as a parser
      var parser = Isotope.sortDataParsers[ args[1] ];
      // parse the value, if there was a parser
      sorter = parser ? function( elem ) {
        return elem && parser( getValue( elem ) );
      } :
      // otherwise just return value
      function( elem ) {
        return elem && getValue( elem );
      };

      return sorter;
    }

    // get an attribute getter, or get text of the querySelector
    function getValueGetter( attr, query ) {
      // if query looks like [foo-bar], get attribute
      if ( attr ) {
        return function getAttribute( elem ) {
          return elem.getAttribute( attr );
        };
      }

      // otherwise, assume its a querySelector, and get its text
      return function getChildText( elem ) {
        var child = elem.querySelector( query );
        return child && child.textContent;
      };
    }

    return mungeSorter;
  })();

  // parsers used in getSortData shortcut strings
  Isotope.sortDataParsers = {
    'parseInt': function( val ) {
      return parseInt( val, 10 );
    },
    'parseFloat': function( val ) {
      return parseFloat( val );
    }
  };

  // ----- sort method ----- //

  // sort filteredItem order
  proto._sort = function() {
    var sortByOpt = this.options.sortBy;
    if ( !sortByOpt ) {
      return;
    }
    // concat all sortBy and sortHistory
    var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
    // sort magic
    var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
    this.filteredItems.sort( itemSorter );
    // keep track of sortBy History
    if ( sortByOpt != this.sortHistory[0] ) {
      // add to front, oldest goes in last
      this.sortHistory.unshift( sortByOpt );
    }
  };

  // returns a function used for sorting
  function getItemSorter( sortBys, sortAsc ) {
    return function sorter( itemA, itemB ) {
      // cycle through all sortKeys
      for ( var i = 0; i < sortBys.length; i++ ) {
        var sortBy = sortBys[i];
        var a = itemA.sortData[ sortBy ];
        var b = itemB.sortData[ sortBy ];
        if ( a > b || a < b ) {
          // if sortAsc is an object, use the value given the sortBy key
          var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
          var direction = isAscending ? 1 : -1;
          return ( a > b ? 1 : -1 ) * direction;
        }
      }
      return 0;
    };
  }

  // -------------------------- methods -------------------------- //

  // get layout mode
  proto._mode = function() {
    var layoutMode = this.options.layoutMode;
    var mode = this.modes[ layoutMode ];
    if ( !mode ) {
      // TODO console.error
      throw new Error( 'No layout mode: ' + layoutMode );
    }
    // HACK sync mode's options
    // any options set after init for layout mode need to be synced
    mode.options = this.options[ layoutMode ];
    return mode;
  };

  proto._resetLayout = function() {
    // trigger original reset layout
    Outlayer.prototype._resetLayout.call( this );
    this._mode()._resetLayout();
  };

  proto._getItemLayoutPosition = function( item  ) {
    return this._mode()._getItemLayoutPosition( item );
  };

  proto._manageStamp = function( stamp ) {
    this._mode()._manageStamp( stamp );
  };

  proto._getContainerSize = function() {
    return this._mode()._getContainerSize();
  };

  proto.needsResizeLayout = function() {
    return this._mode().needsResizeLayout();
  };

  // -------------------------- adding & removing -------------------------- //

  // HEADS UP overwrites default Outlayer appended
  proto.appended = function( elems ) {
    var items = this.addItems( elems );
    if ( !items.length ) {
      return;
    }
    // filter, layout, reveal new items
    var filteredItems = this._filterRevealAdded( items );
    // add to filteredItems
    this.filteredItems = this.filteredItems.concat( filteredItems );
  };

  // HEADS UP overwrites default Outlayer prepended
  proto.prepended = function( elems ) {
    var items = this._itemize( elems );
    if ( !items.length ) {
      return;
    }
    // start new layout
    this._resetLayout();
    this._manageStamps();
    // filter, layout, reveal new items
    var filteredItems = this._filterRevealAdded( items );
    // layout previous items
    this.layoutItems( this.filteredItems );
    // add to items and filteredItems
    this.filteredItems = filteredItems.concat( this.filteredItems );
    this.items = items.concat( this.items );
  };

  proto._filterRevealAdded = function( items ) {
    var filtered = this._filter( items );
    this.hide( filtered.needHide );
    // reveal all new items
    this.reveal( filtered.matches );
    // layout new items, no transition
    this.layoutItems( filtered.matches, true );
    return filtered.matches;
  };

  /**
   * Filter, sort, and layout newly-appended item elements
   * @param {Array or NodeList or Element} elems
   */
  proto.insert = function( elems ) {
    var items = this.addItems( elems );
    if ( !items.length ) {
      return;
    }
    // append item elements
    var i, item;
    var len = items.length;
    for ( i=0; i < len; i++ ) {
      item = items[i];
      this.element.appendChild( item.element );
    }
    // filter new stuff
    var filteredInsertItems = this._filter( items ).matches;
    // set flag
    for ( i=0; i < len; i++ ) {
      items[i].isLayoutInstant = true;
    }
    this.arrange();
    // reset flag
    for ( i=0; i < len; i++ ) {
      delete items[i].isLayoutInstant;
    }
    this.reveal( filteredInsertItems );
  };

  var _remove = proto.remove;
  proto.remove = function( elems ) {
    elems = utils.makeArray( elems );
    var removeItems = this.getItems( elems );
    // do regular thing
    _remove.call( this, elems );
    // bail if no items to remove
    var len = removeItems && removeItems.length;
    // remove elems from filteredItems
    for ( var i=0; len && i < len; i++ ) {
      var item = removeItems[i];
      // remove item from collection
      utils.removeFrom( this.filteredItems, item );
    }
  };

  proto.shuffle = function() {
    // update random sortData
    for ( var i=0; i < this.items.length; i++ ) {
      var item = this.items[i];
      item.sortData.random = Math.random();
    }
    this.options.sortBy = 'random';
    this._sort();
    this._layout();
  };

  /**
   * trigger fn without transition
   * kind of hacky to have this in the first place
   * @param {Function} fn
   * @param {Array} args
   * @returns ret
   * @private
   */
  proto._noTransition = function( fn, args ) {
    // save transitionDuration before disabling
    var transitionDuration = this.options.transitionDuration;
    // disable transition
    this.options.transitionDuration = 0;
    // do it
    var returnValue = fn.apply( this, args );
    // re-enable transition for reveal
    this.options.transitionDuration = transitionDuration;
    return returnValue;
  };

  // ----- helper methods ----- //

  /**
   * getter method for getting filtered item elements
   * @returns {Array} elems - collection of item elements
   */
  proto.getFilteredItemElements = function() {
    return this.filteredItems.map( function( item ) {
      return item.element;
    });
  };

  // -----  ----- //

  return Isotope;

}));;/*
 * jQuery.appear
 * https://github.com/bas2k/jquery.appear/
 * http://code.google.com/p/jquery-appear/
 *
 * Copyright (c) 2009 Michael Hixson
 * Copyright (c) 2012 Alexander Brovikov
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
 */
(function($) {
	$.fn.appear = function(fn, options) {

		var settings = $.extend({

			//arbitrary data to pass to fn
			data: undefined,

			//call fn only on the first appear?
			one: true,

			// X & Y accuracy
			accX: 0,
			accY: 0

		}, options);

		return this.each(function() {

			var t = $(this);

			//whether the element is currently visible
			t.appeared = false;

			if (!fn) {

				//trigger the custom event
				t.trigger('appear', settings.data);
				return;
			}

			var w = $(window);

			//fires the appear event when appropriate
			var check = function() {

				//is the element hidden?
				if (!t.is(':visible')) {

					//it became hidden
					t.appeared = false;
					return;
				}

				//is the element inside the visible window?
				var a = w.scrollLeft();
				var b = w.scrollTop();
				var o = t.offset();
				var x = o.left;
				var y = o.top;

				var ax = settings.accX;
				var ay = settings.accY;
				var th = t.height();
				var wh = w.height();
				var tw = t.width();
				var ww = w.width();

				if (y + th + ay >= b &&
					y <= b + wh + ay &&
					x + tw + ax >= a &&
					x <= a + ww + ax) {

					//trigger the custom event
					if (!t.appeared) t.trigger('appear', settings.data);

				} else {

					//it scrolled out of view
					t.appeared = false;
				}
			};

			//create a modified fn with some additional logic
			var modifiedFn = function() {

				//mark the element as visible
				t.appeared = true;

				//is this supposed to happen only once?
				if (settings.one) {

					//remove the check
					w.unbind('scroll', check);
					var i = $.inArray(check, $.fn.appear.checks);
					if (i >= 0) $.fn.appear.checks.splice(i, 1);
				}

				//trigger the original fn
				fn.apply(this, arguments);
			};

			//bind the modified fn to the element
			if (settings.one) t.one('appear', settings.data, modifiedFn);
			else t.bind('appear', settings.data, modifiedFn);

			//check whenever the window scrolls
			w.scroll(check);

			//check whenever the dom changes
			$.fn.appear.checks.push(check);

			//check now
			(check)();
		});
	};

	//keep a queue of appearance checks
	$.extend($.fn.appear, {

		checks: [],
		timeout: null,

		//process the queue
		checkAll: function() {
			var length = $.fn.appear.checks.length;
			if (length > 0) while (length--) ($.fn.appear.checks[length])();
		},

		//check the queue asynchronously
		run: function() {
			if ($.fn.appear.timeout) clearTimeout($.fn.appear.timeout);
			$.fn.appear.timeout = setTimeout($.fn.appear.checkAll, 20);
		}
	});

	//run checks when these methods are called
	$.each(['append', 'prepend', 'after', 'before', 'attr',
		'removeAttr', 'addClass', 'removeClass', 'toggleClass',
		'remove', 'css', 'show', 'hide'], function(i, n) {
		var old = $.fn[n];
		if (old) {
			$.fn[n] = function() {
				var r = old.apply(this, arguments);
				$.fn.appear.run();
				return r;
			}
		}
	});

})(jQuery);;/*
* @fileOverview TouchSwipe - jQuery Plugin
* @version 1.6.6
*
* @author Matt Bryson http://www.github.com/mattbryson
* @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
* @see http://labs.skinkers.com/touchSwipe/
* @see http://plugins.jquery.com/project/touchSwipe
*
* Copyright (c) 2010 Matt Bryson
* Dual licensed under the MIT or GPL Version 2 licenses.
*
*/

/*
*
* Changelog
* $Date: 2014-06-04 (Wed, 04 June 2014) $
* $version 1.6.6 	- Merge of pull requests.
*    				- IE10 touch support
*    				- Only prevent default event handling on valid swipe
*    				- Separate license/changelog comment
*    				- Detect if the swipe is valid at the end of the touch event.
*    				- Pass fingerdata to event handlers.
*    				- Add 'hold' gesture
*    				- Be more tolerant about the tap distance
*    				- Typos and minor fixes
*/

/**
 * See (http://jquery.com/).
 * @name $
 * @class
 * See the jQuery Library  (http://jquery.com/) for full details.  This just
 * documents the function and classes that are added to jQuery by this plug-in.
 */

/**
 * See (http://jquery.com/)
 * @name fn
 * @class
 * See the jQuery Library  (http://jquery.com/) for full details.  This just
 * documents the function and classes that are added to jQuery by this plug-in.
 * @memberOf $
 */



(function (factory) {
    if (typeof define === 'function' && define.amd && define.amd.jQuery) {
        // AMD. Register as anonymous module.
        define(['jquery'], factory);
    } else {
        // Browser globals.
        factory(jQuery);
    }
}(function ($) {
	"use strict";

	//Constants
	var LEFT = "left",
		RIGHT = "right",
		UP = "up",
		DOWN = "down",
		IN = "in",
		OUT = "out",

		NONE = "none",
		AUTO = "auto",

		SWIPE = "swipe",
		PINCH = "pinch",
		TAP = "tap",
		DOUBLE_TAP = "doubletap",
		LONG_TAP = "longtap",
		HOLD = "hold",

		HORIZONTAL = "horizontal",
		VERTICAL = "vertical",

		ALL_FINGERS = "all",

		DOUBLE_TAP_THRESHOLD = 10,

		PHASE_START = "start",
		PHASE_MOVE = "move",
		PHASE_END = "end",
		PHASE_CANCEL = "cancel",

		SUPPORTS_TOUCH = 'ontouchstart' in window,

		SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.navigator.pointerEnabled,

		SUPPORTS_POINTER = window.navigator.pointerEnabled || window.navigator.msPointerEnabled,

		PLUGIN_NS = 'TouchSwipe';



	/**
	* The default configuration, and available options to configure touch swipe with.
	* You can set the default values by updating any of the properties prior to instantiation.
	* @name $.fn.swipe.defaults
	* @namespace
	* @property {int} [fingers=1] The number of fingers to detect in a swipe. Any swipes that do not meet this requirement will NOT trigger swipe handlers.
	* @property {int} [threshold=75] The number of pixels that the user must move their finger by before it is considered a swipe.
	* @property {int} [cancelThreshold=null] The number of pixels that the user must move their finger back from the original swipe direction to cancel the gesture.
	* @property {int} [pinchThreshold=20] The number of pixels that the user must pinch their finger by before it is considered a pinch.
	* @property {int} [maxTimeThreshold=null] Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe.
	* @property {int} [fingerReleaseThreshold=250] Time in milliseconds between releasing multiple fingers.  If 2 fingers are down, and are released one after the other, if they are within this threshold, it counts as a simultaneous release.
	* @property {int} [longTapThreshold=500] Time in milliseconds between tap and release for a long tap
	* @property {int} [doubleTapThreshold=200] Time in milliseconds between 2 taps to count as a double tap
	* @property {function} [swipe=null] A handler to catch all swipes. See {@link $.fn.swipe#event:swipe}
	* @property {function} [swipeLeft=null] A handler that is triggered for "left" swipes. See {@link $.fn.swipe#event:swipeLeft}
	* @property {function} [swipeRight=null] A handler that is triggered for "right" swipes. See {@link $.fn.swipe#event:swipeRight}
	* @property {function} [swipeUp=null] A handler that is triggered for "up" swipes. See {@link $.fn.swipe#event:swipeUp}
	* @property {function} [swipeDown=null] A handler that is triggered for "down" swipes. See {@link $.fn.swipe#event:swipeDown}
	* @property {function} [swipeStatus=null] A handler triggered for every phase of the swipe. See {@link $.fn.swipe#event:swipeStatus}
	* @property {function} [pinchIn=null] A handler triggered for pinch in events. See {@link $.fn.swipe#event:pinchIn}
	* @property {function} [pinchOut=null] A handler triggered for pinch out events. See {@link $.fn.swipe#event:pinchOut}
	* @property {function} [pinchStatus=null] A handler triggered for every phase of a pinch. See {@link $.fn.swipe#event:pinchStatus}
	* @property {function} [tap=null] A handler triggered when a user just taps on the item, rather than swipes it. If they do not move, tap is triggered, if they do move, it is not.
	* @property {function} [doubleTap=null] A handler triggered when a user double taps on the item. The delay between taps can be set with the doubleTapThreshold property. See {@link $.fn.swipe.defaults#doubleTapThreshold}
	* @property {function} [longTap=null] A handler triggered when a user long taps on the item. The delay between start and end can be set with the longTapThreshold property. See {@link $.fn.swipe.defaults#longTapThreshold}
	* @property (function) [hold=null] A handler triggered when a user reaches longTapThreshold on the item. See {@link $.fn.swipe.defaults#longTapThreshold}
	* @property {boolean} [triggerOnTouchEnd=true] If true, the swipe events are triggered when the touch end event is received (user releases finger).  If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically.
	* @property {boolean} [triggerOnTouchLeave=false] If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers.
	* @property {string|undefined} [allowPageScroll='auto'] How the browser handles page scrolls when the user is swiping on a touchSwipe object. See {@link $.fn.swipe.pageScroll}.  <br/><br/>
										<code>"auto"</code> : all undefined swipes will cause the page to scroll in that direction. <br/>
										<code>"none"</code> : the page will not scroll when user swipes. <br/>
										<code>"horizontal"</code> : will force page to scroll on horizontal swipes. <br/>
										<code>"vertical"</code> : will force page to scroll on vertical swipes. <br/>
	* @property {boolean} [fallbackToMouseEvents=true] If true mouse events are used when run on a non touch device, false will stop swipes being triggered by mouse events on non tocuh devices.
	* @property {string} [excludedElements="button, input, select, textarea, a, .noSwipe"] A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes all form, input, select, button, anchor and .noSwipe elements.

	*/
	var defaults = {
		fingers: 1,
		threshold: 75,
		cancelThreshold:null,
		pinchThreshold:20,
		maxTimeThreshold: null,
		fingerReleaseThreshold:250,
		longTapThreshold:500,
		doubleTapThreshold:200,
		swipe: null,
		swipeLeft: null,
		swipeRight: null,
		swipeUp: null,
		swipeDown: null,
		swipeStatus: null,
		pinchIn:null,
		pinchOut:null,
		pinchStatus:null,
		click:null, //Deprecated since 1.6.2
		tap:null,
		doubleTap:null,
		longTap:null,
		hold:null,
		triggerOnTouchEnd: true,
		triggerOnTouchLeave:false,
		allowPageScroll: "auto",
		fallbackToMouseEvents: true,
		excludedElements:"label, button, input, select, textarea, a, .noSwipe"
	};



	/**
	* Applies TouchSwipe behaviour to one or more jQuery objects.
	* The TouchSwipe plugin can be instantiated via this method, or methods within
	* TouchSwipe can be executed via this method as per jQuery plugin architecture.
	* @see TouchSwipe
	* @class
	* @param {Mixed} method If the current DOMNode is a TouchSwipe object, and <code>method</code> is a TouchSwipe method, then
	* the <code>method</code> is executed, and any following arguments are passed to the TouchSwipe method.
	* If <code>method</code> is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the
	* configuration properties defined in the object. See TouchSwipe
	*
	*/
	$.fn.swipe = function (method) {
		var $this = $(this),
			plugin = $this.data(PLUGIN_NS);

		//Check if we are already instantiated and trying to execute a method
		if (plugin && typeof method === 'string') {
			if (plugin[method]) {
				return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1));
			} else {
				$.error('Method ' + method + ' does not exist on jQuery.swipe');
			}
		}
		//Else not instantiated and trying to pass init object (or nothing)
		else if (!plugin && (typeof method === 'object' || !method)) {
			return init.apply(this, arguments);
		}

		return $this;
	};

	//Expose our defaults so a user could override the plugin defaults
	$.fn.swipe.defaults = defaults;

	/**
	* The phases that a touch event goes through.  The <code>phase</code> is passed to the event handlers.
	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
	* @namespace
	* @readonly
	* @property {string} PHASE_START Constant indicating the start phase of the touch event. Value is <code>"start"</code>.
	* @property {string} PHASE_MOVE Constant indicating the move phase of the touch event. Value is <code>"move"</code>.
	* @property {string} PHASE_END Constant indicating the end phase of the touch event. Value is <code>"end"</code>.
	* @property {string} PHASE_CANCEL Constant indicating the cancel phase of the touch event. Value is <code>"cancel"</code>.
	*/
	$.fn.swipe.phases = {
		PHASE_START: PHASE_START,
		PHASE_MOVE: PHASE_MOVE,
		PHASE_END: PHASE_END,
		PHASE_CANCEL: PHASE_CANCEL
	};

	/**
	* The direction constants that are passed to the event handlers.
	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
	* @namespace
	* @readonly
	* @property {string} LEFT Constant indicating the left direction. Value is <code>"left"</code>.
	* @property {string} RIGHT Constant indicating the right direction. Value is <code>"right"</code>.
	* @property {string} UP Constant indicating the up direction. Value is <code>"up"</code>.
	* @property {string} DOWN Constant indicating the down direction. Value is <code>"cancel"</code>.
	* @property {string} IN Constant indicating the in direction. Value is <code>"in"</code>.
	* @property {string} OUT Constant indicating the out direction. Value is <code>"out"</code>.
	*/
	$.fn.swipe.directions = {
		LEFT: LEFT,
		RIGHT: RIGHT,
		UP: UP,
		DOWN: DOWN,
		IN : IN,
		OUT: OUT
	};

	/**
	* The page scroll constants that can be used to set the value of <code>allowPageScroll</code> option
	* These properties are read only
	* @namespace
	* @readonly
	* @see $.fn.swipe.defaults#allowPageScroll
	* @property {string} NONE Constant indicating no page scrolling is allowed. Value is <code>"none"</code>.
	* @property {string} HORIZONTAL Constant indicating horizontal page scrolling is allowed. Value is <code>"horizontal"</code>.
	* @property {string} VERTICAL Constant indicating vertical page scrolling is allowed. Value is <code>"vertical"</code>.
	* @property {string} AUTO Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is <code>"auto"</code>.
	*/
	$.fn.swipe.pageScroll = {
		NONE: NONE,
		HORIZONTAL: HORIZONTAL,
		VERTICAL: VERTICAL,
		AUTO: AUTO
	};

	/**
	* Constants representing the number of fingers used in a swipe.  These are used to set both the value of <code>fingers</code> in the
	* options object, as well as the value of the <code>fingers</code> event property.
	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
	* @namespace
	* @readonly
	* @see $.fn.swipe.defaults#fingers
	* @property {string} ONE Constant indicating 1 finger is to be detected / was detected. Value is <code>1</code>.
	* @property {string} TWO Constant indicating 2 fingers are to be detected / were detected. Value is <code>1</code>.
	* @property {string} THREE Constant indicating 3 finger are to be detected / were detected. Value is <code>1</code>.
	* @property {string} ALL Constant indicating any combination of finger are to be detected.  Value is <code>"all"</code>.
	*/
	$.fn.swipe.fingers = {
		ONE: 1,
		TWO: 2,
		THREE: 3,
		ALL: ALL_FINGERS
	};

	/**
	* Initialise the plugin for each DOM element matched
	* This creates a new instance of the main TouchSwipe class for each DOM element, and then
	* saves a reference to that instance in the elements data property.
	* @internal
	*/
	function init(options) {
		//Prep and extend the options
		if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) {
			options.allowPageScroll = NONE;
		}

        //Check for deprecated options
		//Ensure that any old click handlers are assigned to the new tap, unless we have a tap
		if(options.click!==undefined && options.tap===undefined) {
		    options.tap = options.click;
		}

		if (!options) {
			options = {};
		}

        //pass empty object so we dont modify the defaults
		options = $.extend({}, $.fn.swipe.defaults, options);

		//For each element instantiate the plugin
		return this.each(function () {
			var $this = $(this);

			//Check we havent already initialised the plugin
			var plugin = $this.data(PLUGIN_NS);

			if (!plugin) {
				plugin = new TouchSwipe(this, options);
				$this.data(PLUGIN_NS, plugin);
			}
		});
	}

	/**
	* Main TouchSwipe Plugin Class.
	* Do not use this to construct your TouchSwipe object, use the jQuery plugin method $.fn.swipe(); {@link $.fn.swipe}
	* @private
	* @name TouchSwipe
	* @param {DOMNode} element The HTML DOM object to apply to plugin to
	* @param {Object} options The options to configure the plugin with.  @link {$.fn.swipe.defaults}
	* @see $.fh.swipe.defaults
	* @see $.fh.swipe
    * @class
	*/
	function TouchSwipe(element, options) {
        var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents),
            START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown',
            MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove',
            END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup',
            LEAVE_EV = useTouchEvents ? null : 'mouseleave', //we manually detect leave on touch devices, so null event here
            CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel');



		//touch properties
		var distance = 0,
			direction = null,
			duration = 0,
			startTouchesDistance = 0,
			endTouchesDistance = 0,
			pinchZoom = 1,
			pinchDistance = 0,
			pinchDirection = 0,
			maximumsMap=null;



		//jQuery wrapped element for this instance
		var $element = $(element);

		//Current phase of th touch cycle
		var phase = "start";

		// the current number of fingers being used.
		var fingerCount = 0;

		//track mouse points / delta
		var fingerData=null;

		//track times
		var startTime = 0,
			endTime = 0,
			previousTouchEndTime=0,
			previousTouchFingerCount=0,
			doubleTapStartTime=0;

		//Timeouts
		var singleTapTimeout=null,
			holdTimeout=null;

		// Add gestures to all swipable areas if supported
		try {
			$element.bind(START_EV, touchStart);
			$element.bind(CANCEL_EV, touchCancel);
		}
		catch (e) {
			$.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe');
		}

		//
		//Public methods
		//

		/**
		* re-enables the swipe plugin with the previous configuration
		* @function
		* @name $.fn.swipe#enable
		* @return {DOMNode} The Dom element that was registered with TouchSwipe
		* @example $("#element").swipe("enable");
		*/
		this.enable = function () {
			$element.bind(START_EV, touchStart);
			$element.bind(CANCEL_EV, touchCancel);
			return $element;
		};

		/**
		* disables the swipe plugin
		* @function
		* @name $.fn.swipe#disable
		* @return {DOMNode} The Dom element that is now registered with TouchSwipe
	    * @example $("#element").swipe("disable");
		*/
		this.disable = function () {
			removeListeners();
			return $element;
		};

		/**
		* Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin.
		* @function
		* @name $.fn.swipe#destroy
		* @return {DOMNode} The Dom element that was registered with TouchSwipe
		* @example $("#element").swipe("destroy");
		*/
		this.destroy = function () {
			removeListeners();
			$element.data(PLUGIN_NS, null);
			return $element;
		};


        /**
         * Allows run time updating of the swipe configuration options.
         * @function
    	 * @name $.fn.swipe#option
    	 * @param {String} property The option property to get or set
         * @param {Object} [value] The value to set the property to
		 * @return {Object} If only a property name is passed, then that property value is returned.
		 * @example $("#element").swipe("option", "threshold"); // return the threshold
         * @example $("#element").swipe("option", "threshold", 100); // set the threshold after init
         * @see $.fn.swipe.defaults
         *
         */
        this.option = function (property, value) {
            if(options[property]!==undefined) {
                if(value===undefined) {
                    return options[property];
                } else {
                    options[property] = value;
                }
            } else {
                $.error('Option ' + property + ' does not exist on jQuery.swipe.options');
            }

            return null;
        };

		//
		// Private methods
		//

		//
		// EVENTS
		//
		/**
		* Event handler for a touch start event.
		* Stops the default click event from triggering and stores where we touched
		* @inner
		* @param {object} jqEvent The normalised jQuery event object.
		*/
		function touchStart(jqEvent) {
			//If we already in a touch event (a finger already in use) then ignore subsequent ones..
			if( getTouchInProgress() )
				return;

			//Check if this element matches any in the excluded elements selectors,  or its parent is excluded, if so, DON'T swipe
			if( $(jqEvent.target).closest( options.excludedElements, $element ).length>0 )
				return;

			//As we use Jquery bind for events, we need to target the original event object
			//If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;

			var ret,
				evt = SUPPORTS_TOUCH ? event.touches[0] : event;

			phase = PHASE_START;

			//If we support touches, get the finger count
			if (SUPPORTS_TOUCH) {
				// get the total number of fingers touching the screen
				fingerCount = event.touches.length;
			}
			//Else this is the desktop, so stop the browser from dragging the image
			else {
				jqEvent.preventDefault(); //call this on jq event so we are cross browser
			}

			//clear vars..
			distance = 0;
			direction = null;
			pinchDirection=null;
			duration = 0;
			startTouchesDistance=0;
			endTouchesDistance=0;
			pinchZoom = 1;
			pinchDistance = 0;
			fingerData=createAllFingerData();
			maximumsMap=createMaximumsData();
			cancelMultiFingerRelease();


			// check the number of fingers is what we are looking for, or we are capturing pinches
			if (!SUPPORTS_TOUCH || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) {
				// get the coordinates of the touch
				createFingerData( 0, evt );
				startTime = getTimeStamp();

				if(fingerCount==2) {
					//Keep track of the initial pinch distance, so we can calculate the diff later
					//Store second finger data as start
					createFingerData( 1, event.touches[1] );
					startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
				}

				if (options.swipeStatus || options.pinchStatus) {
					ret = triggerHandler(event, phase);
				}
			}
			else {
				//A touch with more or less than the fingers we are looking for, so cancel
				ret = false;
			}

			//If we have a return value from the users handler, then return and cancel
			if (ret === false) {
				phase = PHASE_CANCEL;
				triggerHandler(event, phase);
				return ret;
			}
			else {
				if (options.hold) {
					holdTimeout = setTimeout($.proxy(function() {
						//Trigger the event
						$element.trigger('hold', [event.target]);
						//Fire the callback
						if(options.hold) {
							ret = options.hold.call($element, event, event.target);
						}
					}, this), options.longTapThreshold );
				}

				setTouchInProgress(true);
			}

            return null;
		};



		/**
		* Event handler for a touch move event.
		* If we change fingers during move, then cancel the event
		* @inner
		* @param {object} jqEvent The normalised jQuery event object.
		*/
		function touchMove(jqEvent) {

			//As we use Jquery bind for events, we need to target the original event object
			//If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;

			//If we are ending, cancelling, or within the threshold of 2 fingers being released, don't track anything..
			if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease())
				return;

			var ret,
				evt = SUPPORTS_TOUCH ? event.touches[0] : event;


			//Update the  finger data
			var currentFinger = updateFingerData(evt);
			endTime = getTimeStamp();

			if (SUPPORTS_TOUCH) {
				fingerCount = event.touches.length;
			}

			if (options.hold)
				clearTimeout(holdTimeout);

			phase = PHASE_MOVE;

			//If we have 2 fingers get Touches distance as well
			if(fingerCount==2) {

				//Keep track of the initial pinch distance, so we can calculate the diff later
				//We do this here as well as the start event, in case they start with 1 finger, and the press 2 fingers
				if(startTouchesDistance==0) {
					//Create second finger if this is the first time...
					createFingerData( 1, event.touches[1] );

					startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
				} else {
					//Else just update the second finger
					updateFingerData(event.touches[1]);

					endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end);
					pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end);
				}


				pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance);
				pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance);
			}


			if ( (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH || hasPinches() ) {

				direction = calculateDirection(currentFinger.start, currentFinger.end);

				//Check if we need to prevent default event (page scroll / pinch zoom) or not
				validateDefaultEvent(jqEvent, direction);

				//Distance and duration are all off the main finger
				distance = calculateDistance(currentFinger.start, currentFinger.end);
				duration = calculateDuration();

                //Cache the maximum distance we made in this direction
                setMaxDistance(direction, distance);


				if (options.swipeStatus || options.pinchStatus) {
					ret = triggerHandler(event, phase);
				}


				//If we trigger end events when threshold are met, or trigger events when touch leaves element
				if(!options.triggerOnTouchEnd || options.triggerOnTouchLeave) {

					var inBounds = true;

					//If checking if we leave the element, run the bounds check (we can use touchleave as its not supported on webkit)
					if(options.triggerOnTouchLeave) {
						var bounds = getbounds( this );
						inBounds = isInBounds( currentFinger.end, bounds );
					}

					//Trigger end handles as we swipe if thresholds met or if we have left the element if the user has asked to check these..
					if(!options.triggerOnTouchEnd && inBounds) {
						phase = getNextPhase( PHASE_MOVE );
					}
					//We end if out of bounds here, so set current phase to END, and check if its modified
					else if(options.triggerOnTouchLeave && !inBounds ) {
						phase = getNextPhase( PHASE_END );
					}

					if(phase==PHASE_CANCEL || phase==PHASE_END)	{
						triggerHandler(event, phase);
					}
				}
			}
			else {
				phase = PHASE_CANCEL;
				triggerHandler(event, phase);
			}

			if (ret === false) {
				phase = PHASE_CANCEL;
				triggerHandler(event, phase);
			}
		}



		/**
		* Event handler for a touch end event.
		* Calculate the direction and trigger events
		* @inner
		* @param {object} jqEvent The normalised jQuery event object.
		*/
		function touchEnd(jqEvent) {
			//As we use Jquery bind for events, we need to target the original event object
			var event = jqEvent.originalEvent;


			//If we are still in a touch with another finger return
			//This allows us to wait a fraction and see if the other finger comes up, if it does within the threshold, then we treat it as a multi release, not a single release.
			if (SUPPORTS_TOUCH) {
				if(event.touches.length>0) {
					startMultiFingerRelease();
					return true;
				}
			}

			//If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release.
			//This is used to allow 2 fingers to release fractionally after each other, whilst maintainig the event as containg 2 fingers, not 1
			if(inMultiFingerRelease()) {
				fingerCount=previousTouchFingerCount;
			}

			//Set end of swipe
			endTime = getTimeStamp();

			//Get duration incase move was never fired
			duration = calculateDuration();

			//If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase
			if(didSwipeBackToCancel() || !validateSwipeDistance()) {
			    phase = PHASE_CANCEL;
                triggerHandler(event, phase);
			} else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) {
				//call this on jq event so we are cross browser
				jqEvent.preventDefault();
				phase = PHASE_END;
                triggerHandler(event, phase);
			}
			//Special cases - A tap should always fire on touch end regardless,
			//So here we manually trigger the tap end handler by itself
			//We dont run trigger handler as it will re-trigger events that may have fired already
			else if (!options.triggerOnTouchEnd && hasTap()) {
                //Trigger the pinch events...
			    phase = PHASE_END;
			    triggerHandlerForGesture(event, phase, TAP);
			}
			else if (phase === PHASE_MOVE) {
				phase = PHASE_CANCEL;
				triggerHandler(event, phase);
			}

			setTouchInProgress(false);

            return null;
		}



		/**
		* Event handler for a touch cancel event.
		* Clears current vars
		* @inner
		*/
		function touchCancel() {
			// reset the variables back to default values
			fingerCount = 0;
			endTime = 0;
			startTime = 0;
			startTouchesDistance=0;
			endTouchesDistance=0;
			pinchZoom=1;

			//If we were in progress of tracking a possible multi touch end, then re set it.
			cancelMultiFingerRelease();

			setTouchInProgress(false);
		}


		/**
		* Event handler for a touch leave event.
		* This is only triggered on desktops, in touch we work this out manually
		* as the touchleave event is not supported in webkit
		* @inner
		*/
		function touchLeave(jqEvent) {
			var event = jqEvent.originalEvent;

			//If we have the trigger on leave property set....
			if(options.triggerOnTouchLeave) {
				phase = getNextPhase( PHASE_END );
				triggerHandler(event, phase);
			}
		}

		/**
		* Removes all listeners that were associated with the plugin
		* @inner
		*/
		function removeListeners() {
			$element.unbind(START_EV, touchStart);
			$element.unbind(CANCEL_EV, touchCancel);
			$element.unbind(MOVE_EV, touchMove);
			$element.unbind(END_EV, touchEnd);

			//we only have leave events on desktop, we manually calculate leave on touch as its not supported in webkit
			if(LEAVE_EV) {
				$element.unbind(LEAVE_EV, touchLeave);
			}

			setTouchInProgress(false);
		}


		/**
		 * Checks if the time and distance thresholds have been met, and if so then the appropriate handlers are fired.
		 */
		function getNextPhase(currentPhase) {

			var nextPhase = currentPhase;

			// Ensure we have valid swipe (under time and over distance  and check if we are out of bound...)
			var validTime = validateSwipeTime();
			var validDistance = validateSwipeDistance();
			var didCancel = didSwipeBackToCancel();

			//If we have exceeded our time, then cancel
			if(!validTime || didCancel) {
				nextPhase = PHASE_CANCEL;
			}
			//Else if we are moving, and have reached distance then end
			else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) ) {
				nextPhase = PHASE_END;
			}
			//Else if we have ended by leaving and didn't reach distance, then cancel
			else if (!validDistance && currentPhase==PHASE_END && options.triggerOnTouchLeave) {
				nextPhase = PHASE_CANCEL;
			}

			return nextPhase;
		}


		/**
		* Trigger the relevant event handler
		* The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
		* @param {object} event the original event object
		* @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
		* @inner
		*/
		function triggerHandler(event, phase) {

			var ret = undefined;

			// SWIPE GESTURES
			if(didSwipe() || hasSwipes()) { //hasSwipes as status needs to fire even if swipe is invalid
				//Trigger the swipe events...
				ret = triggerHandlerForGesture(event, phase, SWIPE);
			}

			// PINCH GESTURES (if the above didn't cancel)
			else if((didPinch() || hasPinches()) && ret!==false) {
				//Trigger the pinch events...
				ret = triggerHandlerForGesture(event, phase, PINCH);
			}

			// CLICK / TAP (if the above didn't cancel)
			if(didDoubleTap() && ret!==false) {
				//Trigger the tap events...
				ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP);
			}

			// CLICK / TAP (if the above didn't cancel)
			else if(didLongTap() && ret!==false) {
				//Trigger the tap events...
				ret = triggerHandlerForGesture(event, phase, LONG_TAP);
			}

			// CLICK / TAP (if the above didn't cancel)
			else if(didTap() && ret!==false) {
				//Trigger the tap event..
				ret = triggerHandlerForGesture(event, phase, TAP);
			}



			// If we are cancelling the gesture, then manually trigger the reset handler
			if (phase === PHASE_CANCEL) {
				touchCancel(event);
			}

			// If we are ending the gesture, then manually trigger the reset handler IF all fingers are off
			if(phase === PHASE_END) {
				//If we support touch, then check that all fingers are off before we cancel
				if (SUPPORTS_TOUCH) {
					if(event.touches.length==0) {
						touchCancel(event);
					}
				}
				else {
					touchCancel(event);
				}
			}

			return ret;
		}



		/**
		* Trigger the relevant event handler
		* The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
		* @param {object} event the original event object
		* @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
		* @param {string} gesture the gesture to trigger a handler for : PINCH or SWIPE {@link $.fn.swipe.gestures}
		* @return Boolean False, to indicate that the event should stop propagation, or void.
		* @inner
		*/
		function triggerHandlerForGesture(event, phase, gesture) {

			var ret=undefined;

			//SWIPES....
			if(gesture==SWIPE) {
				//Trigger status every time..

				//Trigger the event...
				$element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData]);

				//Fire the callback
				if (options.swipeStatus) {
					ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData);
					//If the status cancels, then dont run the subsequent event handlers..
					if(ret===false) return false;
				}




				if (phase == PHASE_END && validateSwipe()) {
					//Fire the catch all event
					$element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]);

					//Fire catch all callback
					if (options.swipe) {
						ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData);
						//If the status cancels, then dont run the subsequent event handlers..
						if(ret===false) return false;
					}

					//trigger direction specific event handlers
					switch (direction) {
						case LEFT:
							//Trigger the event
							$element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData]);

					        //Fire the callback
							if (options.swipeLeft) {
								ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData);
							}
							break;

						case RIGHT:
							//Trigger the event
					        $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData]);

					        //Fire the callback
							if (options.swipeRight) {
								ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData);
							}
							break;

						case UP:
							//Trigger the event
					        $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData]);

					        //Fire the callback
							if (options.swipeUp) {
								ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData);
							}
							break;

						case DOWN:
							//Trigger the event
					        $element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData]);

					        //Fire the callback
							if (options.swipeDown) {
								ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData);
							}
							break;
					}
				}
			}


			//PINCHES....
			if(gesture==PINCH) {
				//Trigger the event
			     $element.trigger('pinchStatus', [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);

                //Fire the callback
				if (options.pinchStatus) {
					ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
					//If the status cancels, then dont run the subsequent event handlers..
					if(ret===false) return false;
				}

				if(phase==PHASE_END && validatePinch()) {

					switch (pinchDirection) {
						case IN:
							//Trigger the event
                            $element.trigger('pinchIn', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);

                            //Fire the callback
                            if (options.pinchIn) {
								ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
							}
							break;

						case OUT:
							//Trigger the event
                            $element.trigger('pinchOut', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);

                            //Fire the callback
                            if (options.pinchOut) {
								ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
							}
							break;
					}
				}
			}





			if(gesture==TAP) {
				if(phase === PHASE_CANCEL || phase === PHASE_END) {


    			    //Cancel any existing double tap
				    clearTimeout(singleTapTimeout);
    			    //Cancel hold timeout
				    clearTimeout(holdTimeout);

					//If we are also looking for doubelTaps, wait incase this is one...
				    if(hasDoubleTap() && !inDoubleTap()) {
				        //Cache the time of this tap
                        doubleTapStartTime = getTimeStamp();

				        //Now wait for the double tap timeout, and trigger this single tap
				        //if its not cancelled by a double tap
				        singleTapTimeout = setTimeout($.proxy(function() {
        			        doubleTapStartTime=null;
        			        //Trigger the event
                			$element.trigger('tap', [event.target]);


                            //Fire the callback
                            if(options.tap) {
                                ret = options.tap.call($element, event, event.target);
                            }
    			        }, this), options.doubleTapThreshold );

    			    } else {
                        doubleTapStartTime=null;

                        //Trigger the event
                        $element.trigger('tap', [event.target]);


                        //Fire the callback
                        if(options.tap) {
                            ret = options.tap.call($element, event, event.target);
                        }
	    		    }
	    		}
			}

			else if (gesture==DOUBLE_TAP) {
				if(phase === PHASE_CANCEL || phase === PHASE_END) {
					//Cancel any pending singletap
				    clearTimeout(singleTapTimeout);
				    doubleTapStartTime=null;

                    //Trigger the event
                    $element.trigger('doubletap', [event.target]);

                    //Fire the callback
                    if(options.doubleTap) {
                        ret = options.doubleTap.call($element, event, event.target);
                    }
	    		}
			}

			else if (gesture==LONG_TAP) {
				if(phase === PHASE_CANCEL || phase === PHASE_END) {
					//Cancel any pending singletap (shouldnt be one)
				    clearTimeout(singleTapTimeout);
				    doubleTapStartTime=null;

                    //Trigger the event
                    $element.trigger('longtap', [event.target]);

                    //Fire the callback
                    if(options.longTap) {
                        ret = options.longTap.call($element, event, event.target);
                    }
	    		}
			}

			return ret;
		}




		//
		// GESTURE VALIDATION
		//

		/**
		* Checks the user has swipe far enough
		* @return Boolean if <code>threshold</code> has been set, return true if the threshold was met, else false.
		* If no threshold was set, then we return true.
		* @inner
		*/
		function validateSwipeDistance() {
			var valid = true;
			//If we made it past the min swipe distance..
			if (options.threshold !== null) {
				valid = distance >= options.threshold;
			}

            return valid;
		}

		/**
		* Checks the user has swiped back to cancel.
		* @return Boolean if <code>cancelThreshold</code> has been set, return true if the cancelThreshold was met, else false.
		* If no cancelThreshold was set, then we return true.
		* @inner
		*/
		function didSwipeBackToCancel() {
            var cancelled = false;
    		if(options.cancelThreshold !== null && direction !==null)  {
    		    cancelled =  (getMaxDistance( direction ) - distance) >= options.cancelThreshold;
			}

			return cancelled;
		}

		/**
		* Checks the user has pinched far enough
		* @return Boolean if <code>pinchThreshold</code> has been set, return true if the threshold was met, else false.
		* If no threshold was set, then we return true.
		* @inner
		*/
		function validatePinchDistance() {
			if (options.pinchThreshold !== null) {
				return pinchDistance >= options.pinchThreshold;
			}
			return true;
		}

		/**
		* Checks that the time taken to swipe meets the minimum / maximum requirements
		* @return Boolean
		* @inner
		*/
		function validateSwipeTime() {
			var result;
			//If no time set, then return true

			if (options.maxTimeThreshold) {
				if (duration >= options.maxTimeThreshold) {
					result = false;
				} else {
					result = true;
				}
			}
			else {
				result = true;
			}

			return result;
		}


		/**
		* Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring.
		* This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object.
		* @param {object} jqEvent The normalised jQuery representation of the event object.
		* @param {string} direction The direction of the event. See {@link $.fn.swipe.directions}
		* @see $.fn.swipe.directions
		* @inner
		*/
		function validateDefaultEvent(jqEvent, direction) {
			if (options.allowPageScroll === NONE || hasPinches()) {
				jqEvent.preventDefault();
			} else {
				var auto = options.allowPageScroll === AUTO;

				switch (direction) {
					case LEFT:
						if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
							jqEvent.preventDefault();
						}
						break;

					case RIGHT:
						if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
							jqEvent.preventDefault();
						}
						break;

					case UP:
						if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
							jqEvent.preventDefault();
						}
						break;

					case DOWN:
						if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
							jqEvent.preventDefault();
						}
						break;
				}
			}

		}


		// PINCHES
		/**
		 * Returns true of the current pinch meets the thresholds
		 * @return Boolean
		 * @inner
		*/
		function validatePinch() {
		    var hasCorrectFingerCount = validateFingers();
		    var hasEndPoint = validateEndPoint();
			var hasCorrectDistance = validatePinchDistance();
			return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance;

		}

		/**
		 * Returns true if any Pinch events have been registered
		 * @return Boolean
		 * @inner
		*/
		function hasPinches() {
			//Enure we dont return 0 or null for false values
			return !!(options.pinchStatus || options.pinchIn || options.pinchOut);
		}

		/**
		 * Returns true if we are detecting pinches, and have one
		 * @return Boolean
		 * @inner
		 */
		function didPinch() {
			//Enure we dont return 0 or null for false values
			return !!(validatePinch() && hasPinches());
		}




		// SWIPES
		/**
		 * Returns true if the current swipe meets the thresholds
		 * @return Boolean
		 * @inner
		*/
		function validateSwipe() {
			//Check validity of swipe
			var hasValidTime = validateSwipeTime();
			var hasValidDistance = validateSwipeDistance();
			var hasCorrectFingerCount = validateFingers();
		    var hasEndPoint = validateEndPoint();
		    var didCancel = didSwipeBackToCancel();

			// if the user swiped more than the minimum length, perform the appropriate action
			// hasValidDistance is null when no distance is set
			var valid =  !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime;

			return valid;
		}

		/**
		 * Returns true if any Swipe events have been registered
		 * @return Boolean
		 * @inner
		*/
		function hasSwipes() {
			//Enure we dont return 0 or null for false values
			return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown);
		}


		/**
		 * Returns true if we are detecting swipes and have one
		 * @return Boolean
		 * @inner
		*/
		function didSwipe() {
			//Enure we dont return 0 or null for false values
			return !!(validateSwipe() && hasSwipes());
		}

        /**
		 * Returns true if we have matched the number of fingers we are looking for
		 * @return Boolean
		 * @inner
		*/
        function validateFingers() {
            //The number of fingers we want were matched, or on desktop we ignore
    		return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH);
    	}

        /**
		 * Returns true if we have an end point for the swipe
		 * @return Boolean
		 * @inner
		*/
        function validateEndPoint() {
            //We have an end value for the finger
		    return fingerData[0].end.x !== 0;
        }

		// TAP / CLICK
		/**
		 * Returns true if a click / tap events have been registered
		 * @return Boolean
		 * @inner
		*/
		function hasTap() {
			//Enure we dont return 0 or null for false values
			return !!(options.tap) ;
		}

		/**
		 * Returns true if a double tap events have been registered
		 * @return Boolean
		 * @inner
		*/
		function hasDoubleTap() {
			//Enure we dont return 0 or null for false values
			return !!(options.doubleTap) ;
		}

		/**
		 * Returns true if any long tap events have been registered
		 * @return Boolean
		 * @inner
		*/
		function hasLongTap() {
			//Enure we dont return 0 or null for false values
			return !!(options.longTap) ;
		}

		/**
		 * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past.
		 * @return Boolean
		 * @inner
		*/
		function validateDoubleTap() {
		    if(doubleTapStartTime==null){
		        return false;
		    }
		    var now = getTimeStamp();
		    return (hasDoubleTap() && ((now-doubleTapStartTime) <= options.doubleTapThreshold));
		}

		/**
		 * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past.
		 * @return Boolean
		 * @inner
		*/
		function inDoubleTap() {
		    return validateDoubleTap();
		}


		/**
		 * Returns true if we have a valid tap
		 * @return Boolean
		 * @inner
		*/
		function validateTap() {
		    return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold));
		}

		/**
		 * Returns true if we have a valid long tap
		 * @return Boolean
		 * @inner
		*/
		function validateLongTap() {
		    //slight threshold on moving finger
            return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD));
		}

		/**
		 * Returns true if we are detecting taps and have one
		 * @return Boolean
		 * @inner
		*/
		function didTap() {
		    //Enure we dont return 0 or null for false values
			return !!(validateTap() && hasTap());
		}


		/**
		 * Returns true if we are detecting double taps and have one
		 * @return Boolean
		 * @inner
		*/
		function didDoubleTap() {
		    //Enure we dont return 0 or null for false values
			return !!(validateDoubleTap() && hasDoubleTap());
		}

		/**
		 * Returns true if we are detecting long taps and have one
		 * @return Boolean
		 * @inner
		*/
		function didLongTap() {
		    //Enure we dont return 0 or null for false values
			return !!(validateLongTap() && hasLongTap());
		}




		// MULTI FINGER TOUCH
		/**
		 * Starts tracking the time between 2 finger releases, and keeps track of how many fingers we initially had up
		 * @inner
		*/
		function startMultiFingerRelease() {
			previousTouchEndTime = getTimeStamp();
			previousTouchFingerCount = event.touches.length+1;
		}

		/**
		 * Cancels the tracking of time between 2 finger releases, and resets counters
		 * @inner
		*/
		function cancelMultiFingerRelease() {
			previousTouchEndTime = 0;
			previousTouchFingerCount = 0;
		};

		/**
		 * Checks if we are in the threshold between 2 fingers being released
		 * @return Boolean
		 * @inner
		*/
		function inMultiFingerRelease() {

			var withinThreshold = false;

			if(previousTouchEndTime) {
				var diff = getTimeStamp() - previousTouchEndTime;
				if( diff<=options.fingerReleaseThreshold ) {
					withinThreshold = true;
				};
			};

			return withinThreshold;
		};


		/**
		* gets a data flag to indicate that a touch is in progress
		* @return Boolean
		* @inner
		*/
		function getTouchInProgress() {
			//strict equality to ensure only true and false are returned
			return !!($element.data(PLUGIN_NS+'_intouch') === true);
		}

		/**
		* Sets a data flag to indicate that a touch is in progress
		* @param {boolean} val The value to set the property to
		* @inner
		*/
		function setTouchInProgress(val) {

			//Add or remove event listeners depending on touch status
			if(val===true) {
				$element.bind(MOVE_EV, touchMove);
				$element.bind(END_EV, touchEnd);

				//we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
				if(LEAVE_EV) {
					$element.bind(LEAVE_EV, touchLeave);
				}
			} else {
				$element.unbind(MOVE_EV, touchMove, false);
				$element.unbind(END_EV, touchEnd, false);

				//we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
				if(LEAVE_EV) {
					$element.unbind(LEAVE_EV, touchLeave, false);
				}
			}


			//strict equality to ensure only true and false can update the value
			$element.data(PLUGIN_NS+'_intouch', val === true);
		}


		/**
		 * Creates the finger data for the touch/finger in the event object.
		 * @param {int} index The index in the array to store the finger data (usually the order the fingers were pressed)
		 * @param {object} evt The event object containing finger data
		 * @return finger data object
		 * @inner
		*/
		function createFingerData( index, evt ) {
			var id = evt.identifier!==undefined ? evt.identifier : 0;

			fingerData[index].identifier = id;
			fingerData[index].start.x = fingerData[index].end.x = evt.pageX||evt.clientX;
			fingerData[index].start.y = fingerData[index].end.y = evt.pageY||evt.clientY;

			return fingerData[index];
		}

		/**
		 * Updates the finger data for a particular event object
		 * @param {object} evt The event object containing the touch/finger data to upadte
		 * @return a finger data object.
		 * @inner
		*/
		function updateFingerData(evt) {

			var id = evt.identifier!==undefined ? evt.identifier : 0;
			var f = getFingerData( id );

			f.end.x = evt.pageX||evt.clientX;
			f.end.y = evt.pageY||evt.clientY;

			return f;
		}

		/**
		 * Returns a finger data object by its event ID.
		 * Each touch event has an identifier property, which is used
		 * to track repeat touches
		 * @param {int} id The unique id of the finger in the sequence of touch events.
		 * @return a finger data object.
		 * @inner
		*/
		function getFingerData( id ) {
			for(var i=0; i<fingerData.length; i++) {
				if(fingerData[i].identifier == id) {
					return fingerData[i];
				}
			}
		}

		/**
		 * Creats all the finger onjects and returns an array of finger data
		 * @return Array of finger objects
		 * @inner
		*/
		function createAllFingerData() {
			var fingerData=[];
			for (var i=0; i<=5; i++) {
				fingerData.push({
					start:{ x: 0, y: 0 },
					end:{ x: 0, y: 0 },
					identifier:0
				});
			}

			return fingerData;
		}

		/**
		 * Sets the maximum distance swiped in the given direction.
		 * If the new value is lower than the current value, the max value is not changed.
		 * @param {string}  direction The direction of the swipe
		 * @param {int}  distance The distance of the swipe
		 * @inner
		*/
		function setMaxDistance(direction, distance) {
    		distance = Math.max(distance, getMaxDistance(direction) );
    		maximumsMap[direction].distance = distance;
		}

        /**
		 * gets the maximum distance swiped in the given direction.
		 * @param {string}  direction The direction of the swipe
		 * @return int  The distance of the swipe
		 * @inner
		*/
		function getMaxDistance(direction) {
			if (maximumsMap[direction]) return maximumsMap[direction].distance;
			return undefined;
		}

		/**
		 * Creats a map of directions to maximum swiped values.
		 * @return Object A dictionary of maximum values, indexed by direction.
		 * @inner
		*/
		function createMaximumsData() {
			var maxData={};
			maxData[LEFT]=createMaximumVO(LEFT);
			maxData[RIGHT]=createMaximumVO(RIGHT);
			maxData[UP]=createMaximumVO(UP);
			maxData[DOWN]=createMaximumVO(DOWN);

			return maxData;
		}

		/**
		 * Creates a map maximum swiped values for a given swipe direction
		 * @param {string} The direction that these values will be associated with
		 * @return Object Maximum values
		 * @inner
		*/
		function createMaximumVO(dir) {
		    return {
		        direction:dir,
		        distance:0
		    }
		}


		//
		// MATHS / UTILS
		//

		/**
		* Calculate the duration of the swipe
		* @return int
		* @inner
		*/
		function calculateDuration() {
			return endTime - startTime;
		}

		/**
		* Calculate the distance between 2 touches (pinch)
		* @param {point} startPoint A point object containing x and y co-ordinates
	    * @param {point} endPoint A point object containing x and y co-ordinates
	    * @return int;
		* @inner
		*/
		function calculateTouchesDistance(startPoint, endPoint) {
			var diffX = Math.abs(startPoint.x - endPoint.x);
			var diffY = Math.abs(startPoint.y - endPoint.y);

			return Math.round(Math.sqrt(diffX*diffX+diffY*diffY));
		}

		/**
		* Calculate the zoom factor between the start and end distances
		* @param {int} startDistance Distance (between 2 fingers) the user started pinching at
	    * @param {int} endDistance Distance (between 2 fingers) the user ended pinching at
	    * @return float The zoom value from 0 to 1.
		* @inner
		*/
		function calculatePinchZoom(startDistance, endDistance) {
			var percent = (endDistance/startDistance) * 1;
			return percent.toFixed(2);
		}


		/**
		* Returns the pinch direction, either IN or OUT for the given points
		* @return string Either {@link $.fn.swipe.directions.IN} or {@link $.fn.swipe.directions.OUT}
		* @see $.fn.swipe.directions
		* @inner
		*/
		function calculatePinchDirection() {
			if(pinchZoom<1) {
				return OUT;
			}
			else {
				return IN;
			}
		}


		/**
		* Calculate the length / distance of the swipe
		* @param {point} startPoint A point object containing x and y co-ordinates
	    * @param {point} endPoint A point object containing x and y co-ordinates
	    * @return int
		* @inner
		*/
		function calculateDistance(startPoint, endPoint) {
			return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)));
		}

		/**
		* Calculate the angle of the swipe
		* @param {point} startPoint A point object containing x and y co-ordinates
	    * @param {point} endPoint A point object containing x and y co-ordinates
	    * @return int
		* @inner
		*/
		function calculateAngle(startPoint, endPoint) {
			var x = startPoint.x - endPoint.x;
			var y = endPoint.y - startPoint.y;
			var r = Math.atan2(y, x); //radians
			var angle = Math.round(r * 180 / Math.PI); //degrees

			//ensure value is positive
			if (angle < 0) {
				angle = 360 - Math.abs(angle);
			}

			return angle;
		}

		/**
		* Calculate the direction of the swipe
		* This will also call calculateAngle to get the latest angle of swipe
		* @param {point} startPoint A point object containing x and y co-ordinates
	    * @param {point} endPoint A point object containing x and y co-ordinates
	    * @return string Either {@link $.fn.swipe.directions.LEFT} / {@link $.fn.swipe.directions.RIGHT} / {@link $.fn.swipe.directions.DOWN} / {@link $.fn.swipe.directions.UP}
		* @see $.fn.swipe.directions
		* @inner
		*/
		function calculateDirection(startPoint, endPoint ) {
			var angle = calculateAngle(startPoint, endPoint);

			if ((angle <= 45) && (angle >= 0)) {
				return LEFT;
			} else if ((angle <= 360) && (angle >= 315)) {
				return LEFT;
			} else if ((angle >= 135) && (angle <= 225)) {
				return RIGHT;
			} else if ((angle > 45) && (angle < 135)) {
				return DOWN;
			} else {
				return UP;
			}
		}


		/**
		* Returns a MS time stamp of the current time
		* @return int
		* @inner
		*/
		function getTimeStamp() {
			var now = new Date();
			return now.getTime();
		}



		/**
		 * Returns a bounds object with left, right, top and bottom properties for the element specified.
		 * @param {DomNode} The DOM node to get the bounds for.
		 */
		function getbounds( el ) {
			el = $(el);
			var offset = el.offset();

			var bounds = {
					left:offset.left,
					right:offset.left+el.outerWidth(),
					top:offset.top,
					bottom:offset.top+el.outerHeight()
					};

			return bounds;
		}


		/**
		 * Checks if the point object is in the bounds object.
		 * @param {object} point A point object.
		 * @param {int} point.x The x value of the point.
		 * @param {int} point.y The x value of the point.
		 * @param {object} bounds The bounds object to test
		 * @param {int} bounds.left The leftmost value
		 * @param {int} bounds.right The righttmost value
		 * @param {int} bounds.top The topmost value
		* @param {int} bounds.bottom The bottommost value
		 */
		function isInBounds(point, bounds) {
			return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom);
		};


	}




/**
 * A catch all handler that is triggered for all swipe directions.
 * @name $.fn.swipe#swipe
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user swiped
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {object} fingerData The coordinates of fingers in event
 */




/**
 * A handler that is triggered for "left" swipes.
 * @name $.fn.swipe#swipeLeft
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user swiped
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {object} fingerData The coordinates of fingers in event
 */

/**
 * A handler that is triggered for "right" swipes.
 * @name $.fn.swipe#swipeRight
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user swiped
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {object} fingerData The coordinates of fingers in event
 */

/**
 * A handler that is triggered for "up" swipes.
 * @name $.fn.swipe#swipeUp
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user swiped
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {object} fingerData The coordinates of fingers in event
 */

/**
 * A handler that is triggered for "down" swipes.
 * @name $.fn.swipe#swipeDown
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user swiped
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {object} fingerData The coordinates of fingers in event
 */

/**
 * A handler triggered for every phase of the swipe. This handler is constantly fired for the duration of the pinch.
 * This is triggered regardless of swipe thresholds.
 * @name $.fn.swipe#swipeStatus
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {string} phase The phase of the swipe event. See {@link $.fn.swipe.phases}
 * @param {string} direction The direction the user swiped in. This is null if the user has yet to move. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user swiped. This is 0 if the user has yet to move.
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {object} fingerData The coordinates of fingers in event
 */

/**
 * A handler triggered for pinch in events.
 * @name $.fn.swipe#pinchIn
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user pinched
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
 * @param {object} fingerData The coordinates of fingers in event
 */

/**
 * A handler triggered for pinch out events.
 * @name $.fn.swipe#pinchOut
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user pinched
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
 * @param {object} fingerData The coordinates of fingers in event
 */

/**
 * A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds.
 * @name $.fn.swipe#pinchStatus
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
 * @param {int} distance The distance the user pinched
 * @param {int} duration The duration of the swipe in milliseconds
 * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
 * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
 * @param {object} fingerData The coordinates of fingers in event
 */

/**
 * A click handler triggered when a user simply clicks, rather than swipes on an element.
 * This is deprecated since version 1.6.2, any assignment to click will be assigned to the tap handler.
 * You cannot use <code>on</code> to bind to this event as the default jQ <code>click</code> event will be triggered.
 * Use the <code>tap</code> event instead.
 * @name $.fn.swipe#click
 * @event
 * @deprecated since version 1.6.2, please use {@link $.fn.swipe#tap} instead
 * @default null
 * @param {EventObject} event The original event object
 * @param {DomObject} target The element clicked on.
 */

 /**
 * A click / tap handler triggered when a user simply clicks or taps, rather than swipes on an element.
 * @name $.fn.swipe#tap
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {DomObject} target The element clicked on.
 */

/**
 * A double tap handler triggered when a user double clicks or taps on an element.
 * You can set the time delay for a double tap with the {@link $.fn.swipe.defaults#doubleTapThreshold} property.
 * Note: If you set both <code>doubleTap</code> and <code>tap</code> handlers, the <code>tap</code> event will be delayed by the <code>doubleTapThreshold</code>
 * as the script needs to check if its a double tap.
 * @name $.fn.swipe#doubleTap
 * @see  $.fn.swipe.defaults#doubleTapThreshold
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {DomObject} target The element clicked on.
 */

 /**
 * A long tap handler triggered once a tap has been release if the tap was longer than the longTapThreshold.
 * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property.
 * @name $.fn.swipe#longTap
 * @see  $.fn.swipe.defaults#longTapThreshold
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {DomObject} target The element clicked on.
 */

  /**
 * A hold tap handler triggered as soon as the longTapThreshold is reached
 * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property.
 * @name $.fn.swipe#hold
 * @see  $.fn.swipe.defaults#longTapThreshold
 * @event
 * @default null
 * @param {EventObject} event The original event object
 * @param {DomObject} target The element clicked on.
 */

}));
;/*
 *	jQuery carouFredSel 6.2.1
 *	Demo's and documentation:
 *	caroufredsel.dev7studios.com
 *
 *	Copyright (c) 2013 Fred Heusschen
 *	www.frebsite.nl
 *
 *	Dual licensed under the MIT and GPL licenses.
 *	http://en.wikipedia.org/wiki/MIT_License
 *	http://en.wikipedia.org/wiki/GNU_General_Public_License
 */


(function($) {


	//	LOCAL

	if ( $.fn.carouFredSel )
	{
		return;
	}

	$.fn.caroufredsel = $.fn.carouFredSel = function(options, configs)
	{

		//	no element
		if (this.length == 0)
		{
			debug( true, 'No element found for "' + this.selector + '".' );
			return this;
		}

		//	multiple elements
		if (this.length > 1)
		{
			return this.each(function() {
				$(this).carouFredSel(options, configs);
			});
		}


		var $cfs = this,
			$tt0 = this[0],
			starting_position = false;

		if ($cfs.data('_cfs_isCarousel'))
		{
			starting_position = $cfs.triggerHandler('_cfs_triggerEvent', 'currentPosition');
			$cfs.trigger('_cfs_triggerEvent', ['destroy', true]);
		}

		var FN = {};

		FN._init = function(o, setOrig, start)
		{
			o = go_getObject($tt0, o);

			o.items = go_getItemsObject($tt0, o.items);
			o.scroll = go_getScrollObject($tt0, o.scroll);
			o.auto = go_getAutoObject($tt0, o.auto);
			o.prev = go_getPrevNextObject($tt0, o.prev);
			o.next = go_getPrevNextObject($tt0, o.next);
			o.pagination = go_getPaginationObject($tt0, o.pagination);
			o.swipe = go_getSwipeObject($tt0, o.swipe);
			o.mousewheel = go_getMousewheelObject($tt0, o.mousewheel);

			if (setOrig)
			{
				opts_orig = $.extend(true, {}, $.fn.carouFredSel.defaults, o);
			}

			opts = $.extend(true, {}, $.fn.carouFredSel.defaults, o);
			opts.d = cf_getDimensions(opts);

			crsl.direction = (opts.direction == 'up' || opts.direction == 'left') ? 'next' : 'prev';

			var	a_itm = $cfs.children(),
				avail_primary = ms_getParentSize($wrp, opts, 'width');

			if (is_true(opts.cookie))
			{
				opts.cookie = 'caroufredsel_cookie_' + conf.serialNumber;
			}

			opts.maxDimension = ms_getMaxDimension(opts, avail_primary);

			//	complement items and sizes
			opts.items = in_complementItems(opts.items, opts, a_itm, start);
			opts[opts.d['width']] = in_complementPrimarySize(opts[opts.d['width']], opts, a_itm);
			opts[opts.d['height']] = in_complementSecondarySize(opts[opts.d['height']], opts, a_itm);

			//	primary size not set for a responsive carousel
			if (opts.responsive)
			{
				if (!is_percentage(opts[opts.d['width']]))
				{
					opts[opts.d['width']] = '100%';
				}
			}

			//	primary size is percentage
			if (is_percentage(opts[opts.d['width']]))
			{
				crsl.upDateOnWindowResize = true;
				crsl.primarySizePercentage = opts[opts.d['width']];
				opts[opts.d['width']] = ms_getPercentage(avail_primary, crsl.primarySizePercentage);
				if (!opts.items.visible)
				{
					opts.items.visibleConf.variable = true;
				}
			}

			if (opts.responsive)
			{
				opts.usePadding = false;
				opts.padding = [0, 0, 0, 0];
				opts.align = false;
				opts.items.visibleConf.variable = false;
			}
			else
			{
				//	visible-items not set
				if (!opts.items.visible)
				{
					opts = in_complementVisibleItems(opts, avail_primary);
				}

				//	primary size not set -> calculate it or set to "variable"
				if (!opts[opts.d['width']])
				{
					if (!opts.items.visibleConf.variable && is_number(opts.items[opts.d['width']]) && opts.items.filter == '*')
					{
						opts[opts.d['width']] = opts.items.visible * opts.items[opts.d['width']];
						opts.align = false;
					}
					else
					{
						opts[opts.d['width']] = 'variable';
					}
				}
				//	align not set -> set to center if primary size is number
				if (is_undefined(opts.align))
				{
					opts.align = (is_number(opts[opts.d['width']]))
						? 'center'
						: false;
				}
				//	set variabe visible-items
				if (opts.items.visibleConf.variable)
				{
					opts.items.visible = gn_getVisibleItemsNext(a_itm, opts, 0);
				}
			}

			//	set visible items by filter
			if (opts.items.filter != '*' && !opts.items.visibleConf.variable)
			{
				opts.items.visibleConf.org = opts.items.visible;
				opts.items.visible = gn_getVisibleItemsNextFilter(a_itm, opts, 0);
			}

			opts.items.visible = cf_getItemsAdjust(opts.items.visible, opts, opts.items.visibleConf.adjust, $tt0);
			opts.items.visibleConf.old = opts.items.visible;

			if (opts.responsive)
			{
				if (!opts.items.visibleConf.min)
				{
					opts.items.visibleConf.min = opts.items.visible;
				}
				if (!opts.items.visibleConf.max)
				{
					opts.items.visibleConf.max = opts.items.visible;
				}
				opts = in_getResponsiveValues(opts, a_itm, avail_primary);
			}
			else
			{
				opts.padding = cf_getPadding(opts.padding);

				if (opts.align == 'top')
				{
					opts.align = 'left';
				}
				else if (opts.align == 'bottom')
				{
					opts.align = 'right';
				}

				switch (opts.align)
				{
					//	align: center, left or right
					case 'center':
					case 'left':
					case 'right':
						if (opts[opts.d['width']] != 'variable')
						{
							opts = in_getAlignPadding(opts, a_itm);
							opts.usePadding = true;
						}
						break;

					//	padding
					default:
						opts.align = false;
						opts.usePadding = (
							opts.padding[0] == 0 &&
							opts.padding[1] == 0 &&
							opts.padding[2] == 0 &&
							opts.padding[3] == 0
						) ? false : true;
						break;
				}
			}

			if (!is_number(opts.scroll.duration))
			{
				opts.scroll.duration = 500;
			}
			if (is_undefined(opts.scroll.items))
			{
				opts.scroll.items = (opts.responsive || opts.items.visibleConf.variable || opts.items.filter != '*')
					? 'visible'
					: opts.items.visible;
			}

			opts.auto = $.extend(true, {}, opts.scroll, opts.auto);
			opts.prev = $.extend(true, {}, opts.scroll, opts.prev);
			opts.next = $.extend(true, {}, opts.scroll, opts.next);
			opts.pagination = $.extend(true, {}, opts.scroll, opts.pagination);
			//	swipe and mousewheel extend later on, per direction

			opts.auto = go_complementAutoObject($tt0, opts.auto);
			opts.prev = go_complementPrevNextObject($tt0, opts.prev);
			opts.next = go_complementPrevNextObject($tt0, opts.next);
			opts.pagination = go_complementPaginationObject($tt0, opts.pagination);
			opts.swipe = go_complementSwipeObject($tt0, opts.swipe);
			opts.mousewheel = go_complementMousewheelObject($tt0, opts.mousewheel);

			if (opts.synchronise)
			{
				opts.synchronise = cf_getSynchArr(opts.synchronise);
			}


			//	DEPRECATED
			if (opts.auto.onPauseStart)
			{
				opts.auto.onTimeoutStart = opts.auto.onPauseStart;
				deprecated('auto.onPauseStart', 'auto.onTimeoutStart');
			}
			if (opts.auto.onPausePause)
			{
				opts.auto.onTimeoutPause = opts.auto.onPausePause;
				deprecated('auto.onPausePause', 'auto.onTimeoutPause');
			}
			if (opts.auto.onPauseEnd)
			{
				opts.auto.onTimeoutEnd = opts.auto.onPauseEnd;
				deprecated('auto.onPauseEnd', 'auto.onTimeoutEnd');
			}
			if (opts.auto.pauseDuration)
			{
				opts.auto.timeoutDuration = opts.auto.pauseDuration;
				deprecated('auto.pauseDuration', 'auto.timeoutDuration');
			}
			//	/DEPRECATED


		};	//	/init


		FN._build = function() {
			$cfs.data('_cfs_isCarousel', true);

			var a_itm = $cfs.children(),
				orgCSS = in_mapCss($cfs, ['textAlign', 'float', 'position', 'top', 'right', 'bottom', 'left', 'zIndex', 'width', 'height', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft']),
				newPosition = 'relative';

			switch (orgCSS.position)
			{
				case 'absolute':
				case 'fixed':
					newPosition = orgCSS.position;
					break;
			}

			if (conf.wrapper == 'parent')
			{
				sz_storeOrigCss($wrp);
			}
			else
			{
				$wrp.css(orgCSS);
			}
			$wrp.css({
				'overflow'		: 'hidden',
				'position'		: newPosition
			});

			sz_storeOrigCss($cfs);
			$cfs.data('_cfs_origCssZindex', orgCSS.zIndex);
			$cfs.css({
				'textAlign'		: 'left',
				'float'			: 'none',
				'position'		: 'absolute',
				'top'			: 0,
				'right'			: 'auto',
				'bottom'		: 'auto',
				'left'			: 0,
				'marginTop'		: 0,
				'marginRight'	: 0,
				'marginBottom'	: 0,
				'marginLeft'	: 0
			});

			sz_storeMargin(a_itm, opts);
			sz_storeOrigCss(a_itm);
			if (opts.responsive)
			{
				sz_setResponsiveSizes(opts, a_itm);
			}

		};	//	/build


		FN._bind_events = function() {
			FN._unbind_events();


			//	stop event
			$cfs.bind(cf_e('stop', conf), function(e, imm) {
				e.stopPropagation();

				//	button
				if (!crsl.isStopped)
				{
					if (opts.auto.button)
					{
						opts.auto.button.addClass(cf_c('stopped', conf));
					}
				}

				//	set stopped
				crsl.isStopped = true;

				if (opts.auto.play)
				{
					opts.auto.play = false;
					$cfs.trigger(cf_e('pause', conf), imm);
				}
				return true;
			});


			//	finish event
			$cfs.bind(cf_e('finish', conf), function(e) {
				e.stopPropagation();
				if (crsl.isScrolling)
				{
					sc_stopScroll(scrl);
				}
				return true;
			});


			//	pause event
			$cfs.bind(cf_e('pause', conf), function(e, imm, res) {
				e.stopPropagation();
				tmrs = sc_clearTimers(tmrs);

				//	immediately pause
				if (imm && crsl.isScrolling)
				{
					scrl.isStopped = true;
					var nst = getTime() - scrl.startTime;
					scrl.duration -= nst;
					if (scrl.pre)
					{
						scrl.pre.duration -= nst;
					}
					if (scrl.post)
					{
						scrl.post.duration -= nst;
					}
					sc_stopScroll(scrl, false);
				}

				//	update remaining pause-time
				if (!crsl.isPaused && !crsl.isScrolling)
				{
					if (res)
					{
						tmrs.timePassed += getTime() - tmrs.startTime;
					}
				}

				//	button
				if (!crsl.isPaused)
				{
					if (opts.auto.button)
					{
						opts.auto.button.addClass(cf_c('paused', conf));
					}
				}

				//	set paused
				crsl.isPaused = true;

				//	pause pause callback
				if (opts.auto.onTimeoutPause)
				{
					var dur1 = opts.auto.timeoutDuration - tmrs.timePassed,
						perc = 100 - Math.ceil( dur1 * 100 / opts.auto.timeoutDuration );

					opts.auto.onTimeoutPause.call($tt0, perc, dur1);
				}
				return true;
			});


			//	play event
			$cfs.bind(cf_e('play', conf), function(e, dir, del, res) {
				e.stopPropagation();
				tmrs = sc_clearTimers(tmrs);

				//	sort params
				var v = [dir, del, res],
					t = ['string', 'number', 'boolean'],
					a = cf_sortParams(v, t);

				dir = a[0];
				del = a[1];
				res = a[2];

				if (dir != 'prev' && dir != 'next')
				{
					dir = crsl.direction;
				}
				if (!is_number(del))
				{
					del = 0;
				}
				if (!is_boolean(res))
				{
					res = false;
				}

				//	stopped?
				if (res)
				{
					crsl.isStopped = false;
					opts.auto.play = true;
				}
				if (!opts.auto.play)
				{
					e.stopImmediatePropagation();
					return debug(conf, 'Carousel stopped: Not scrolling.');
				}

				//	button
				if (crsl.isPaused)
				{
					if (opts.auto.button)
					{
						opts.auto.button.removeClass(cf_c('stopped', conf));
						opts.auto.button.removeClass(cf_c('paused', conf));
					}
				}

				//	set playing
				crsl.isPaused = false;
				tmrs.startTime = getTime();

				//	timeout the scrolling
				var dur1 = opts.auto.timeoutDuration + del;
					dur2 = dur1 - tmrs.timePassed;
					perc = 100 - Math.ceil(dur2 * 100 / dur1);

				if (opts.auto.progress)
				{
					tmrs.progress = setInterval(function() {
						var pasd = getTime() - tmrs.startTime + tmrs.timePassed,
							perc = Math.ceil(pasd * 100 / dur1);
						opts.auto.progress.updater.call(opts.auto.progress.bar[0], perc);
					}, opts.auto.progress.interval);
				}

				tmrs.auto = setTimeout(function() {
					if (opts.auto.progress)
					{
						opts.auto.progress.updater.call(opts.auto.progress.bar[0], 100);
					}
					if (opts.auto.onTimeoutEnd)
					{
						opts.auto.onTimeoutEnd.call($tt0, perc, dur2);
					}
					if (crsl.isScrolling)
					{
						$cfs.trigger(cf_e('play', conf), dir);
					}
					else
					{
						$cfs.trigger(cf_e(dir, conf), opts.auto);
					}
				}, dur2);

				//	pause start callback
				if (opts.auto.onTimeoutStart)
				{
					opts.auto.onTimeoutStart.call($tt0, perc, dur2);
				}

				return true;
			});


			//	resume event
			$cfs.bind(cf_e('resume', conf), function(e) {
				e.stopPropagation();
				if (scrl.isStopped)
				{
					scrl.isStopped = false;
					crsl.isPaused = false;
					crsl.isScrolling = true;
					scrl.startTime = getTime();
					sc_startScroll(scrl, conf);
				}
				else
				{
					$cfs.trigger(cf_e('play', conf));
				}
				return true;
			});


			//	prev + next events
			$cfs.bind(cf_e('prev', conf)+' '+cf_e('next', conf), function(e, obj, num, clb, que) {
				e.stopPropagation();

				//	stopped or hidden carousel, don't scroll, don't queue
				if (crsl.isStopped || $cfs.is(':hidden'))
				{
					e.stopImmediatePropagation();
					return debug(conf, 'Carousel stopped or hidden: Not scrolling.');
				}

				//	not enough items
				var minimum = (is_number(opts.items.minimum)) ? opts.items.minimum : opts.items.visible + 1;
				if (minimum > itms.total)
				{
					e.stopImmediatePropagation();
					return debug(conf, 'Not enough items ('+itms.total+' total, '+minimum+' needed): Not scrolling.');
				}

				//	get config
				var v = [obj, num, clb, que],
					t = ['object', 'number/string', 'function', 'boolean'],
					a = cf_sortParams(v, t);

				obj = a[0];
				num = a[1];
				clb = a[2];
				que = a[3];

				var eType = e.type.slice(conf.events.prefix.length);

				if (!is_object(obj))
				{
					obj = {};
				}
				if (is_function(clb))
				{
					obj.onAfter = clb;
				}
				if (is_boolean(que))
				{
					obj.queue = que;
				}
				obj = $.extend(true, {}, opts[eType], obj);

				//	test conditions callback
				if (obj.conditions && !obj.conditions.call($tt0, eType))
				{
					e.stopImmediatePropagation();
					return debug(conf, 'Callback "conditions" returned false.');
				}

				if (!is_number(num))
				{
					if (opts.items.filter != '*')
					{
						num = 'visible';
					}
					else
					{
						var arr = [num, obj.items, opts[eType].items];
						for (var a = 0, l = arr.length; a < l; a++)
						{
							if (is_number(arr[a]) || arr[a] == 'page' || arr[a] == 'visible') {
								num = arr[a];
								break;
							}
						}
					}
					switch(num) {
						case 'page':
							e.stopImmediatePropagation();
							return $cfs.triggerHandler(cf_e(eType+'Page', conf), [obj, clb]);
							break;

						case 'visible':
							if (!opts.items.visibleConf.variable && opts.items.filter == '*')
							{
								num = opts.items.visible;
							}
							break;
					}
				}

				//	resume animation, add current to queue
				if (scrl.isStopped)
				{
					$cfs.trigger(cf_e('resume', conf));
					$cfs.trigger(cf_e('queue', conf), [eType, [obj, num, clb]]);
					e.stopImmediatePropagation();
					return debug(conf, 'Carousel resumed scrolling.');
				}

				//	queue if scrolling
				if (obj.duration > 0)
				{
					if (crsl.isScrolling)
					{
						if (obj.queue)
						{
							if (obj.queue == 'last')
							{
								queu = [];
							}
							if (obj.queue != 'first' || queu.length == 0)
							{
								$cfs.trigger(cf_e('queue', conf), [eType, [obj, num, clb]]);
							}
						}
						e.stopImmediatePropagation();
						return debug(conf, 'Carousel currently scrolling.');
					}
				}

				tmrs.timePassed = 0;
				$cfs.trigger(cf_e('slide_'+eType, conf), [obj, num]);

				//	synchronise
				if (opts.synchronise)
				{
					var s = opts.synchronise,
						c = [obj, num];

					for (var j = 0, l = s.length; j < l; j++) {
						var d = eType;
						if (!s[j][2])
						{
							d = (d == 'prev') ? 'next' : 'prev';
						}
						if (!s[j][1])
						{
							c[0] = s[j][0].triggerHandler('_cfs_triggerEvent', ['configuration', d]);
						}
						c[1] = num + s[j][3];
						s[j][0].trigger('_cfs_triggerEvent', ['slide_'+d, c]);
					}
				}
				return true;
			});


			//	prev event
			$cfs.bind(cf_e('slide_prev', conf), function(e, sO, nI) {
				e.stopPropagation();
				var a_itm = $cfs.children();

				//	non-circular at start, scroll to end
				if (!opts.circular)
				{
					if (itms.first == 0)
					{
						if (opts.infinite)
						{
							$cfs.trigger(cf_e('next', conf), itms.total-1);
						}
						return e.stopImmediatePropagation();
					}
				}

				sz_resetMargin(a_itm, opts);

				//	find number of items to scroll
				if (!is_number(nI))
				{
					if (opts.items.visibleConf.variable)
					{
						nI = gn_getVisibleItemsPrev(a_itm, opts, itms.total-1);
					}
					else if (opts.items.filter != '*')
					{
						var xI = (is_number(sO.items)) ? sO.items : gn_getVisibleOrg($cfs, opts);
						nI = gn_getScrollItemsPrevFilter(a_itm, opts, itms.total-1, xI);
					}
					else
					{
						nI = opts.items.visible;
					}
					nI = cf_getAdjust(nI, opts, sO.items, $tt0);
				}

				//	prevent non-circular from scrolling to far
				if (!opts.circular)
				{
					if (itms.total - nI < itms.first)
					{
						nI = itms.total - itms.first;
					}
				}

				//	set new number of visible items
				opts.items.visibleConf.old = opts.items.visible;
				if (opts.items.visibleConf.variable)
				{
					var vI = cf_getItemsAdjust(gn_getVisibleItemsNext(a_itm, opts, itms.total-nI), opts, opts.items.visibleConf.adjust, $tt0);
					if (opts.items.visible+nI <= vI && nI < itms.total)
					{
						nI++;
						vI = cf_getItemsAdjust(gn_getVisibleItemsNext(a_itm, opts, itms.total-nI), opts, opts.items.visibleConf.adjust, $tt0);
					}
					opts.items.visible = vI;
				}
				else if (opts.items.filter != '*')
				{
					var vI = gn_getVisibleItemsNextFilter(a_itm, opts, itms.total-nI);
					opts.items.visible = cf_getItemsAdjust(vI, opts, opts.items.visibleConf.adjust, $tt0);
				}

				sz_resetMargin(a_itm, opts, true);

				//	scroll 0, don't scroll
				if (nI == 0)
				{
					e.stopImmediatePropagation();
					return debug(conf, '0 items to scroll: Not scrolling.');
				}
				debug(conf, 'Scrolling '+nI+' items backward.');


				//	save new config
				itms.first += nI;
				while (itms.first >= itms.total)
				{
					itms.first -= itms.total;
				}

				//	non-circular callback
				if (!opts.circular)
				{
					if (itms.first == 0 && sO.onEnd)
					{
						sO.onEnd.call($tt0, 'prev');
					}
					if (!opts.infinite)
					{
						nv_enableNavi(opts, itms.first, conf);
					}
				}

				//	rearrange items
				$cfs.children().slice(itms.total-nI, itms.total).prependTo($cfs);
				if (itms.total < opts.items.visible + nI)
				{
					$cfs.children().slice(0, (opts.items.visible+nI)-itms.total).clone(true).appendTo($cfs);
				}

				//	the needed items
				var a_itm = $cfs.children(),
					i_old = gi_getOldItemsPrev(a_itm, opts, nI),
					i_new = gi_getNewItemsPrev(a_itm, opts),
					i_cur_l = a_itm.eq(nI-1),
					i_old_l = i_old.last(),
					i_new_l = i_new.last();

				sz_resetMargin(a_itm, opts);

				var pL = 0,
					pR = 0;

				if (opts.align)
				{
					var p = cf_getAlignPadding(i_new, opts);
					pL = p[0];
					pR = p[1];
				}
				var oL = (pL < 0) ? opts.padding[opts.d[3]] : 0;

				//	hide items for fx directscroll
				var hiddenitems = false,
					i_skp = $();
				if (opts.items.visible < nI)
				{
					i_skp = a_itm.slice(opts.items.visibleConf.old, nI);
					if (sO.fx == 'directscroll')
					{
						var orgW = opts.items[opts.d['width']];
						hiddenitems = i_skp;
						i_cur_l = i_new_l;
						sc_hideHiddenItems(hiddenitems);
						opts.items[opts.d['width']] = 'variable';
					}
				}

				//	save new sizes
				var $cf2 = false,
					i_siz = ms_getTotalSize(a_itm.slice(0, nI), opts, 'width'),
					w_siz = cf_mapWrapperSizes(ms_getSizes(i_new, opts, true), opts, !opts.usePadding),
					i_siz_vis = 0,
					a_cfs = {},
					a_wsz = {},
					a_cur = {},
					a_old = {},
					a_new = {},
					a_lef = {},
					a_lef_vis = {},
					a_dur = sc_getDuration(sO, opts, nI, i_siz);

				switch(sO.fx)
				{
					case 'cover':
					case 'cover-fade':
						i_siz_vis = ms_getTotalSize(a_itm.slice(0, opts.items.visible), opts, 'width');
						break;
				}

				if (hiddenitems)
				{
					opts.items[opts.d['width']] = orgW;
				}

				sz_resetMargin(a_itm, opts, true);
				if (pR >= 0)
				{
					sz_resetMargin(i_old_l, opts, opts.padding[opts.d[1]]);
				}
				if (pL >= 0)
				{
					sz_resetMargin(i_cur_l, opts, opts.padding[opts.d[3]]);
				}

				if (opts.align)
				{
					opts.padding[opts.d[1]] = pR;
					opts.padding[opts.d[3]] = pL;
				}

				a_lef[opts.d['left']] = -(i_siz - oL);
				a_lef_vis[opts.d['left']] = -(i_siz_vis - oL);
				a_wsz[opts.d['left']] = w_siz[opts.d['width']];

				//	scrolling functions
				var _s_wrapper = function() {},
					_a_wrapper = function() {},
					_s_paddingold = function() {},
					_a_paddingold = function() {},
					_s_paddingnew = function() {},
					_a_paddingnew = function() {},
					_s_paddingcur = function() {},
					_a_paddingcur = function() {},
					_onafter = function() {},
					_moveitems = function() {},
					_position = function() {};

				//	clone carousel
				switch(sO.fx)
				{
					case 'crossfade':
					case 'cover':
					case 'cover-fade':
					case 'uncover':
					case 'uncover-fade':
						$cf2 = $cfs.clone(true).appendTo($wrp);
						break;
				}
				switch(sO.fx)
				{
					case 'crossfade':
					case 'uncover':
					case 'uncover-fade':
						$cf2.children().slice(0, nI).remove();
						$cf2.children().slice(opts.items.visibleConf.old).remove();
						break;

					case 'cover':
					case 'cover-fade':
						$cf2.children().slice(opts.items.visible).remove();
						$cf2.css(a_lef_vis);
						break;
				}

				$cfs.css(a_lef);

				//	reset all scrolls
				scrl = sc_setScroll(a_dur, sO.easing, conf);

				//	animate / set carousel
				a_cfs[opts.d['left']] = (opts.usePadding) ? opts.padding[opts.d[3]] : 0;

				// ThemeFusion eidt for Avada theme: animate the line-height of the main ul element to correct wrapper height
				if ( opts['centerVertically'] ) {
					a_cfs['line-height'] = w_siz['height'] + 'px';
				}

				//	animate / set wrapper
				if (opts[opts.d['width']] == 'variable' || opts[opts.d['height']] == 'variable')
				{
					_s_wrapper = function() {
						$wrp.css(w_siz);
					};
					_a_wrapper = function() {
						scrl.anims.push([$wrp, w_siz]);
					};
				}

				//	animate / set items
				if (opts.usePadding)
				{
					if (i_new_l.not(i_cur_l).length)
					{
			 			a_cur[opts.d['marginRight']] = i_cur_l.data('_cfs_origCssMargin');

						if (pL < 0)
						{
							i_cur_l.css(a_cur);
						}
						else
						{
							_s_paddingcur = function() {
								i_cur_l.css(a_cur);
							};
							_a_paddingcur = function() {
								scrl.anims.push([i_cur_l, a_cur]);
							};
						}
					}
					switch(sO.fx)
					{
						case 'cover':
						case 'cover-fade':
							$cf2.children().eq(nI-1).css(a_cur);
							break;
					}

					if (i_new_l.not(i_old_l).length)
					{
						a_old[opts.d['marginRight']] = i_old_l.data('_cfs_origCssMargin');
						_s_paddingold = function() {
							i_old_l.css(a_old);
						};
						_a_paddingold = function() {
							scrl.anims.push([i_old_l, a_old]);
						};
					}

					if (pR >= 0)
					{
						a_new[opts.d['marginRight']] = i_new_l.data('_cfs_origCssMargin') + opts.padding[opts.d[1]];
						_s_paddingnew = function() {
							i_new_l.css(a_new);
						};
						_a_paddingnew = function() {
							scrl.anims.push([i_new_l, a_new]);
						};
					}
				}

				//	set position
				_position = function() {
					$cfs.css(a_cfs);
				};


				var overFill = opts.items.visible+nI-itms.total;

				//	rearrange items
				_moveitems = function() {
					if (overFill > 0)
					{
						$cfs.children().slice(itms.total).remove();
						i_old = $( $cfs.children().slice(itms.total-(opts.items.visible-overFill)).get().concat( $cfs.children().slice(0, overFill).get() ) );
					}
					sc_showHiddenItems(hiddenitems);

					if (opts.usePadding)
					{
						var l_itm = $cfs.children().eq(opts.items.visible+nI-1);
						l_itm.css(opts.d['marginRight'], l_itm.data('_cfs_origCssMargin'));
					}
				};


				var cb_arguments = sc_mapCallbackArguments(i_old, i_skp, i_new, nI, 'prev', a_dur, w_siz);

				//	fire onAfter callbacks
				_onafter = function() {
					sc_afterScroll($cfs, $cf2, sO);
					crsl.isScrolling = false;
					clbk.onAfter = sc_fireCallbacks($tt0, sO, 'onAfter', cb_arguments, clbk);
					queu = sc_fireQueue($cfs, queu, conf);

					if (!crsl.isPaused)
					{
						$cfs.trigger(cf_e('play', conf));
					}
				};

				//	fire onBefore callback
				crsl.isScrolling = true;
				tmrs = sc_clearTimers(tmrs);
				clbk.onBefore = sc_fireCallbacks($tt0, sO, 'onBefore', cb_arguments, clbk);

				switch(sO.fx)
				{
					case 'none':
						$cfs.css(a_cfs);
						_s_wrapper();
						_s_paddingold();
						_s_paddingnew();
						_s_paddingcur();
						_position();
						_moveitems();
						_onafter();
						break;

					case 'fade':
						scrl.anims.push([$cfs, { 'opacity': 0 }, function() {
							_s_wrapper();
							_s_paddingold();
							_s_paddingnew();
							_s_paddingcur();
							_position();
							_moveitems();
							scrl = sc_setScroll(a_dur, sO.easing, conf);
							scrl.anims.push([$cfs, { 'opacity': 1 }, _onafter]);
							sc_startScroll(scrl, conf);
						}]);
						break;

					case 'crossfade':
						$cfs.css({ 'opacity': 0 });
						scrl.anims.push([$cf2, { 'opacity': 0 }]);
						scrl.anims.push([$cfs, { 'opacity': 1 }, _onafter]);
						_a_wrapper();
						_s_paddingold();
						_s_paddingnew();
						_s_paddingcur();
						_position();
						_moveitems();
						break;

					case 'cover':
						scrl.anims.push([$cf2, a_cfs, function() {
							_s_paddingold();
							_s_paddingnew();
							_s_paddingcur();
							_position();
							_moveitems();
							_onafter();
						}]);
						_a_wrapper();
						break;

					case 'cover-fade':
						scrl.anims.push([$cfs, { 'opacity': 0 }]);
						scrl.anims.push([$cf2, a_cfs, function() {
							_s_paddingold();
							_s_paddingnew();
							_s_paddingcur();
							_position();
							_moveitems();
							_onafter();
						}]);
						_a_wrapper();
						break;

					case 'uncover':
						scrl.anims.push([$cf2, a_wsz, _onafter]);
						_a_wrapper();
						_s_paddingold();
						_s_paddingnew();
						_s_paddingcur();
						_position();
						_moveitems();
						break;

					case 'uncover-fade':
						$cfs.css({ 'opacity': 0 });
						scrl.anims.push([$cfs, { 'opacity': 1 }]);
						scrl.anims.push([$cf2, a_wsz, _onafter]);
						_a_wrapper();
						_s_paddingold();
						_s_paddingnew();
						_s_paddingcur();
						_position();
						_moveitems();
						break;

					default:
						scrl.anims.push([$cfs, a_cfs, function() {
							_moveitems();
							_onafter();
						}]);
						_a_wrapper();
						_a_paddingold();
						_a_paddingnew();
						_a_paddingcur();
						break;
				}

				sc_startScroll(scrl, conf);
				cf_setCookie(opts.cookie, $cfs, conf);

				$cfs.trigger(cf_e('updatePageStatus', conf), [false, w_siz]);

				return true;
			});


			//	next event
			$cfs.bind(cf_e('slide_next', conf), function(e, sO, nI) {
				e.stopPropagation();
				var a_itm = $cfs.children();

				//	non-circular at end, scroll to start
				if (!opts.circular)
				{
					if (itms.first == opts.items.visible)
					{
						if (opts.infinite)
						{
							$cfs.trigger(cf_e('prev', conf), itms.total-1);
						}
						return e.stopImmediatePropagation();
					}
				}

				sz_resetMargin(a_itm, opts);

				//	find number of items to scroll
				if (!is_number(nI))
				{
					if (opts.items.filter != '*')
					{
						var xI = (is_number(sO.items)) ? sO.items : gn_getVisibleOrg($cfs, opts);
						nI = gn_getScrollItemsNextFilter(a_itm, opts, 0, xI);
					}
					else
					{
						nI = opts.items.visible;
					}
					nI = cf_getAdjust(nI, opts, sO.items, $tt0);
				}

				var lastItemNr = (itms.first == 0) ? itms.total : itms.first;

				//	prevent non-circular from scrolling to far
				if (!opts.circular)
				{
					if (opts.items.visibleConf.variable)
					{
						var vI = gn_getVisibleItemsNext(a_itm, opts, nI),
							xI = gn_getVisibleItemsPrev(a_itm, opts, lastItemNr-1);
					}
					else
					{
						var vI = opts.items.visible,
							xI = opts.items.visible;
					}

					if (nI + vI > lastItemNr)
					{
						nI = lastItemNr - xI;
					}
				}

				//	set new number of visible items
				opts.items.visibleConf.old = opts.items.visible;
				if (opts.items.visibleConf.variable)
				{
					var vI = cf_getItemsAdjust(gn_getVisibleItemsNextTestCircular(a_itm, opts, nI, lastItemNr), opts, opts.items.visibleConf.adjust, $tt0);
					while (opts.items.visible-nI >= vI && nI < itms.total)
					{
						nI++;
						vI = cf_getItemsAdjust(gn_getVisibleItemsNextTestCircular(a_itm, opts, nI, lastItemNr), opts, opts.items.visibleConf.adjust, $tt0);
					}
					opts.items.visible = vI;
				}
				else if (opts.items.filter != '*')
				{
					var vI = gn_getVisibleItemsNextFilter(a_itm, opts, nI);
					opts.items.visible = cf_getItemsAdjust(vI, opts, opts.items.visibleConf.adjust, $tt0);
				}

				sz_resetMargin(a_itm, opts, true);

				//	scroll 0, don't scroll
				if (nI == 0)
				{
					e.stopImmediatePropagation();
					return debug(conf, '0 items to scroll: Not scrolling.');
				}
				debug(conf, 'Scrolling '+nI+' items forward.');


				//	save new config
				itms.first -= nI;
				while (itms.first < 0)
				{
					itms.first += itms.total;
				}

				//	non-circular callback
				if (!opts.circular)
				{
					if (itms.first == opts.items.visible && sO.onEnd)
					{
						sO.onEnd.call($tt0, 'next');
					}
					if (!opts.infinite)
					{
						nv_enableNavi(opts, itms.first, conf);
					}
				}

				//	rearrange items
				if (itms.total < opts.items.visible+nI)
				{
					$cfs.children().slice(0, (opts.items.visible+nI)-itms.total).clone(true).appendTo($cfs);
				}

				//	the needed items
				var a_itm = $cfs.children(),
					i_old = gi_getOldItemsNext(a_itm, opts),
					i_new = gi_getNewItemsNext(a_itm, opts, nI),
					i_cur_l = a_itm.eq(nI-1),
					i_old_l = i_old.last(),
					i_new_l = i_new.last();

				sz_resetMargin(a_itm, opts);

				var pL = 0,
					pR = 0;

				if (opts.align)
				{
					var p = cf_getAlignPadding(i_new, opts);
					pL = p[0];
					pR = p[1];
				}

				//	hide items for fx directscroll
				var hiddenitems = false,
					i_skp = $();
				if (opts.items.visibleConf.old < nI)
				{
					i_skp = a_itm.slice(opts.items.visibleConf.old, nI);
					if (sO.fx == 'directscroll')
					{
						var orgW = opts.items[opts.d['width']];
						hiddenitems = i_skp;
						i_cur_l = i_old_l;
						sc_hideHiddenItems(hiddenitems);
						opts.items[opts.d['width']] = 'variable';
					}
				}

				//	save new sizes
				var $cf2 = false,
					i_siz = ms_getTotalSize(a_itm.slice(0, nI), opts, 'width'),
					w_siz = cf_mapWrapperSizes(ms_getSizes(i_new, opts, true), opts, !opts.usePadding),
					i_siz_vis = 0,
					a_cfs = {},
					a_cfs_vis = {},
					a_cur = {},
					a_old = {},
					a_lef = {},
					a_dur = sc_getDuration(sO, opts, nI, i_siz);

				switch(sO.fx)
				{
					case 'uncover':
					case 'uncover-fade':
						i_siz_vis = ms_getTotalSize(a_itm.slice(0, opts.items.visibleConf.old), opts, 'width');
						break;
				}

				if (hiddenitems)
				{
					opts.items[opts.d['width']] = orgW;
				}

				if (opts.align)
				{
					if (opts.padding[opts.d[1]] < 0)
					{
						opts.padding[opts.d[1]] = 0;
					}
				}
				sz_resetMargin(a_itm, opts, true);
				sz_resetMargin(i_old_l, opts, opts.padding[opts.d[1]]);

				if (opts.align)
				{
					opts.padding[opts.d[1]] = pR;
					opts.padding[opts.d[3]] = pL;
				}

				a_lef[opts.d['left']] = (opts.usePadding) ? opts.padding[opts.d[3]] : 0;

				//	scrolling functions
				var _s_wrapper = function() {},
					_a_wrapper = function() {},
					_s_paddingold = function() {},
					_a_paddingold = function() {},
					_s_paddingcur = function() {},
					_a_paddingcur = function() {},
					_onafter = function() {},
					_moveitems = function() {},
					_position = function() {};

				//	clone carousel
				switch(sO.fx)
				{
					case 'crossfade':
					case 'cover':
					case 'cover-fade':
					case 'uncover':
					case 'uncover-fade':
						$cf2 = $cfs.clone(true).appendTo($wrp);
						$cf2.children().slice(opts.items.visibleConf.old).remove();
						break;
				}
				switch(sO.fx)
				{
					case 'crossfade':
					case 'cover':
					case 'cover-fade':
						$cfs.css('zIndex', 1);
						$cf2.css('zIndex', 0);
						break;
				}

				//	reset all scrolls
				scrl = sc_setScroll(a_dur, sO.easing, conf);

				//	animate / set carousel
				a_cfs[opts.d['left']] = -i_siz;

				// ThemeFusion eidt for Avada theme: animate the line-height of the main ul element to correct wrapper height
				if ( opts['centerVertically'] ) {
					a_cfs['line-height'] = w_siz['height'] + 'px';
				}

				a_cfs_vis[opts.d['left']] = -i_siz_vis;

				if (pL < 0)
				{
					a_cfs[opts.d['left']] += pL;
				}

				//	animate / set wrapper
				if (opts[opts.d['width']] == 'variable' || opts[opts.d['height']] == 'variable')
				{
					_s_wrapper = function() {
						$wrp.css(w_siz);
					};

					_a_wrapper = function() {
						scrl.anims.push([$wrp, w_siz]);
					};
				}

				//	animate / set items
				if (opts.usePadding)
				{
					var i_new_l_m = i_new_l.data('_cfs_origCssMargin');

					if (pR >= 0)
					{
						i_new_l_m += opts.padding[opts.d[1]];
					}
					i_new_l.css(opts.d['marginRight'], i_new_l_m);

					if (i_cur_l.not(i_old_l).length)
					{
						a_old[opts.d['marginRight']] = i_old_l.data('_cfs_origCssMargin');
					}
					_s_paddingold = function() {
						i_old_l.css(a_old);
					};
					_a_paddingold = function() {
						scrl.anims.push([i_old_l, a_old]);
					};

					var i_cur_l_m = i_cur_l.data('_cfs_origCssMargin');
					if (pL > 0)
					{
						i_cur_l_m += opts.padding[opts.d[3]];
					}

					a_cur[opts.d['marginRight']] = i_cur_l_m;

					_s_paddingcur = function() {
						i_cur_l.css(a_cur);
					};
					_a_paddingcur = function() {
						scrl.anims.push([i_cur_l, a_cur]);
					};
				}

				//	set position
				_position = function() {
					$cfs.css(a_lef);
				};


				var overFill = opts.items.visible+nI-itms.total;

				//	rearrange items
				_moveitems = function() {
					if (overFill > 0)
					{
						$cfs.children().slice(itms.total).remove();
					}
					var l_itm = $cfs.children().slice(0, nI).appendTo($cfs).last();
					if (overFill > 0)
					{
						i_new = gi_getCurrentItems(a_itm, opts);
					}
					sc_showHiddenItems(hiddenitems);

					if (opts.usePadding)
					{
						if (itms.total < opts.items.visible+nI) {
							var i_cur_l = $cfs.children().eq(opts.items.visible-1);
							i_cur_l.css(opts.d['marginRight'], i_cur_l.data('_cfs_origCssMargin') + opts.padding[opts.d[1]]);
						}
						l_itm.css(opts.d['marginRight'], l_itm.data('_cfs_origCssMargin'));
					}
				};

				var cb_arguments = sc_mapCallbackArguments(i_old, i_skp, i_new, nI, 'next', a_dur, w_siz);

				//	fire onAfter callbacks
				_onafter = function() {
					$cfs.css('zIndex', $cfs.data('_cfs_origCssZindex'));
					sc_afterScroll($cfs, $cf2, sO);
					crsl.isScrolling = false;
					clbk.onAfter = sc_fireCallbacks($tt0, sO, 'onAfter', cb_arguments, clbk);
					queu = sc_fireQueue($cfs, queu, conf);

					if (!crsl.isPaused)
					{
						$cfs.trigger(cf_e('play', conf));
					}
				};

				//	fire onBefore callbacks
				crsl.isScrolling = true;
				tmrs = sc_clearTimers(tmrs);
				clbk.onBefore = sc_fireCallbacks($tt0, sO, 'onBefore', cb_arguments, clbk);

				switch(sO.fx)
				{
					case 'none':
						$cfs.css(a_cfs);
						_s_wrapper();
						_s_paddingold();
						_s_paddingcur();
						_position();
						_moveitems();
						_onafter();
						break;

					case 'fade':
						scrl.anims.push([$cfs, { 'opacity': 0 }, function() {
							_s_wrapper();
							_s_paddingold();
							_s_paddingcur();
							_position();
							_moveitems();
							scrl = sc_setScroll(a_dur, sO.easing, conf);
							scrl.anims.push([$cfs, { 'opacity': 1 }, _onafter]);
							sc_startScroll(scrl, conf);
						}]);
						break;

					case 'crossfade':
						$cfs.css({ 'opacity': 0 });
						scrl.anims.push([$cf2, { 'opacity': 0 }]);
						scrl.anims.push([$cfs, { 'opacity': 1 }, _onafter]);
						_a_wrapper();
						_s_paddingold();
						_s_paddingcur();
						_position();
						_moveitems();
						break;

					case 'cover':
						$cfs.css(opts.d['left'], $wrp[opts.d['width']]());
						scrl.anims.push([$cfs, a_lef, _onafter]);
						_a_wrapper();
						_s_paddingold();
						_s_paddingcur();
						_moveitems();
						break;

					case 'cover-fade':
						$cfs.css(opts.d['left'], $wrp[opts.d['width']]());
						scrl.anims.push([$cf2, { 'opacity': 0 }]);
						scrl.anims.push([$cfs, a_lef, _onafter]);
						_a_wrapper();
						_s_paddingold();
						_s_paddingcur();
						_moveitems();
						break;

					case 'uncover':
						scrl.anims.push([$cf2, a_cfs_vis, _onafter]);
						_a_wrapper();
						_s_paddingold();
						_s_paddingcur();
						_position();
						_moveitems();
						break;

					case 'uncover-fade':
						$cfs.css({ 'opacity': 0 });
						scrl.anims.push([$cfs, { 'opacity': 1 }]);
						scrl.anims.push([$cf2, a_cfs_vis, _onafter]);
						_a_wrapper();
						_s_paddingold();
						_s_paddingcur();
						_position();
						_moveitems();
						break;

					default:
						scrl.anims.push([$cfs, a_cfs, function() {
							_position();
							_moveitems();
							_onafter();
						}]);
						_a_wrapper();
						_a_paddingold();
						_a_paddingcur();
						break;
				}

				sc_startScroll(scrl, conf);
				cf_setCookie(opts.cookie, $cfs, conf);

				$cfs.trigger(cf_e('updatePageStatus', conf), [false, w_siz]);

				return true;
			});


			//	slideTo event
			$cfs.bind(cf_e('slideTo', conf), function(e, num, dev, org, obj, dir, clb) {
				e.stopPropagation();

				var v = [num, dev, org, obj, dir, clb],
					t = ['string/number/object', 'number', 'boolean', 'object', 'string', 'function'],
					a = cf_sortParams(v, t);

				obj = a[3];
				dir = a[4];
				clb = a[5];

				num = gn_getItemIndex(a[0], a[1], a[2], itms, $cfs);

				if (num == 0)
				{
					return false;
				}
				if (!is_object(obj))
				{
					obj = false;
				}

				if (dir != 'prev' && dir != 'next')
				{
					if (opts.circular)
					{
						dir = (num <= itms.total / 2) ? 'next' : 'prev';
					}
					else
					{
						dir = (itms.first == 0 || itms.first > num) ? 'next' : 'prev';
					}
				}

				if (dir == 'prev')
				{
					num = itms.total-num;
				}
				$cfs.trigger(cf_e(dir, conf), [obj, num, clb]);

				return true;
			});


			//	prevPage event
			$cfs.bind(cf_e('prevPage', conf), function(e, obj, clb) {
				e.stopPropagation();
				var cur = $cfs.triggerHandler(cf_e('currentPage', conf));
				return $cfs.triggerHandler(cf_e('slideToPage', conf), [cur-1, obj, 'prev', clb]);
			});


			//	nextPage event
			$cfs.bind(cf_e('nextPage', conf), function(e, obj, clb) {
				e.stopPropagation();
				var cur = $cfs.triggerHandler(cf_e('currentPage', conf));
				return $cfs.triggerHandler(cf_e('slideToPage', conf), [cur+1, obj, 'next', clb]);
			});


			//	slideToPage event
			$cfs.bind(cf_e('slideToPage', conf), function(e, pag, obj, dir, clb) {
				e.stopPropagation();
				if (!is_number(pag))
				{
					pag = $cfs.triggerHandler(cf_e('currentPage', conf));
				}
				var ipp = opts.pagination.items || opts.items.visible,
					max = Math.ceil(itms.total / ipp)-1;

				if (pag < 0)
				{
					pag = max;
				}
				if (pag > max)
				{
					pag = 0;
				}
				return $cfs.triggerHandler(cf_e('slideTo', conf), [pag*ipp, 0, true, obj, dir, clb]);
			});

			//	jumpToStart event
			$cfs.bind(cf_e('jumpToStart', conf), function(e, s) {
				e.stopPropagation();
				if (s)
				{
					s = gn_getItemIndex(s, 0, true, itms, $cfs);
				}
				else
				{
					s = 0;
				}

				s += itms.first;
				if (s != 0)
				{
					if (itms.total > 0)
					{
						while (s > itms.total)
						{
							s -= itms.total;
						}
					}
					$cfs.prepend($cfs.children().slice(s, itms.total));
				}
				return true;
			});


			//	synchronise event
			$cfs.bind(cf_e('synchronise', conf), function(e, s) {
				e.stopPropagation();
				if (s)
				{
					s = cf_getSynchArr(s);
				}
				else if (opts.synchronise)
				{
					s = opts.synchronise;
				}
				else
				{
					return debug(conf, 'No carousel to synchronise.');
				}

				var n = $cfs.triggerHandler(cf_e('currentPosition', conf)),
					x = true;

				for (var j = 0, l = s.length; j < l; j++)
				{
					if (!s[j][0].triggerHandler(cf_e('slideTo', conf), [n, s[j][3], true]))
					{
						x = false;
					}
				}
				return x;
			});


			//	queue event
			$cfs.bind(cf_e('queue', conf), function(e, dir, opt) {
				e.stopPropagation();
				if (is_function(dir))
				{
					dir.call($tt0, queu);
				}
				else if (is_array(dir))
				{
					queu = dir;
				}
				else if (!is_undefined(dir))
				{
					queu.push([dir, opt]);
				}
				return queu;
			});


			//	insertItem event
			$cfs.bind(cf_e('insertItem', conf), function(e, itm, num, org, dev) {
				e.stopPropagation();

				var v = [itm, num, org, dev],
					t = ['string/object', 'string/number/object', 'boolean', 'number'],
					a = cf_sortParams(v, t);

				itm = a[0];
				num = a[1];
				org = a[2];
				dev = a[3];

				if (is_object(itm) && !is_jquery(itm))
				{
					itm = $(itm);
				}
				else if (is_string(itm))
				{
					itm = $(itm);
				}
				if (!is_jquery(itm) || itm.length == 0)
				{
					return debug(conf, 'Not a valid object.');
				}

				if (is_undefined(num))
				{
					num = 'end';
				}

				sz_storeMargin(itm, opts);
				sz_storeOrigCss(itm);

				var orgNum = num,
					before = 'before';

				if (num == 'end')
				{
					if (org)
					{
						if (itms.first == 0)
						{
							num = itms.total-1;
							before = 'after';
						}
						else
						{
							num = itms.first;
							itms.first += itm.length;
						}
						if (num < 0)
						{
							num = 0;
						}
					}
					else
					{
						num = itms.total-1;
						before = 'after';
					}
				}
				else
				{
					num = gn_getItemIndex(num, dev, org, itms, $cfs);
				}

				var $cit = $cfs.children().eq(num);
				if ($cit.length)
				{
					$cit[before](itm);
				}
				else
				{
					debug(conf, 'Correct insert-position not found! Appending item to the end.');
					$cfs.append(itm);
				}

				if (orgNum != 'end' && !org)
				{
					if (num < itms.first)
					{
						itms.first += itm.length;
					}
				}
				itms.total = $cfs.children().length;
				if (itms.first >= itms.total)
				{
					itms.first -= itms.total;
				}

				$cfs.trigger(cf_e('updateSizes', conf));
				$cfs.trigger(cf_e('linkAnchors', conf));

				return true;
			});


			//	removeItem event
			$cfs.bind(cf_e('removeItem', conf), function(e, num, org, dev) {
				e.stopPropagation();

				var v = [num, org, dev],
					t = ['string/number/object', 'boolean', 'number'],
					a = cf_sortParams(v, t);

				num = a[0];
				org = a[1];
				dev = a[2];

				var removed = false;

				if (num instanceof $ && num.length > 1)
				{
					$removed = $();
					num.each(function(i, el) {
						var $rem = $cfs.trigger(cf_e('removeItem', conf), [$(this), org, dev]);
						if ( $rem )
						{
							$removed = $removed.add($rem);
						}
					});
					return $removed;
				}

				if (is_undefined(num) || num == 'end')
				{
					$removed = $cfs.children().last();
				}
				else
				{
					num = gn_getItemIndex(num, dev, org, itms, $cfs);
					var $removed = $cfs.children().eq(num);
					if ( $removed.length )
					{
						if (num < itms.first)
						{
							itms.first -= $removed.length;
						}
					}
				}
				if ( $removed && $removed.length )
				{
					$removed.detach();
					itms.total = $cfs.children().length;
					$cfs.trigger(cf_e('updateSizes', conf));
				}

				return $removed;
			});


			//	onBefore and onAfter event
			$cfs.bind(cf_e('onBefore', conf)+' '+cf_e('onAfter', conf), function(e, fn) {
				e.stopPropagation();
				var eType = e.type.slice(conf.events.prefix.length);
				if (is_array(fn))
				{
					clbk[eType] = fn;
				}
				if (is_function(fn))
				{
					clbk[eType].push(fn);
				}
				return clbk[eType];
			});


			//	currentPosition event
			$cfs.bind(cf_e('currentPosition', conf), function(e, fn) {
				e.stopPropagation();
				if (itms.first == 0)
				{
					var val = 0;
				}
				else
				{
					var val = itms.total - itms.first;
				}
				if (is_function(fn))
				{
					fn.call($tt0, val);
				}
				return val;
			});


			//	currentPage event
			$cfs.bind(cf_e('currentPage', conf), function(e, fn) {
				e.stopPropagation();
				var ipp = opts.pagination.items || opts.items.visible,
					max = Math.ceil(itms.total/ipp-1),
					nr;
				if (itms.first == 0)
				{
					nr = 0;
				}
				else if (itms.first < itms.total % ipp)
				{
					nr = 0;
				}
				else if (itms.first == ipp && !opts.circular)
				{
					nr = max;
				}
				else
				{
					 nr = Math.round((itms.total-itms.first)/ipp);
				}
				if (nr < 0)
				{
					nr = 0;
				}
				if (nr > max)
				{
					nr = max;
				}
				if (is_function(fn))
				{
					fn.call($tt0, nr);
				}
				return nr;
			});


			//	currentVisible event
			$cfs.bind(cf_e('currentVisible', conf), function(e, fn) {
				e.stopPropagation();
				var $i = gi_getCurrentItems($cfs.children(), opts);
				if (is_function(fn))
				{
					fn.call($tt0, $i);
				}
				return $i;
			});


			//	slice event
			$cfs.bind(cf_e('slice', conf), function(e, f, l, fn) {
				e.stopPropagation();

				if (itms.total == 0)
				{
					return false;
				}

				var v = [f, l, fn],
					t = ['number', 'number', 'function'],
					a = cf_sortParams(v, t);

				f = (is_number(a[0])) ? a[0] : 0;
				l = (is_number(a[1])) ? a[1] : itms.total;
				fn = a[2];

				f += itms.first;
				l += itms.first;

				if (items.total > 0)
				{
					while (f > itms.total)
					{
						f -= itms.total;
					}
					while (l > itms.total)
					{
						l -= itms.total;
					}
					while (f < 0)
					{
						f += itms.total;
					}
					while (l < 0)
					{
						l += itms.total;
					}
				}
				var $iA = $cfs.children(),
					$i;

				if (l > f)
				{
					$i = $iA.slice(f, l);
				}
				else
				{
					$i = $( $iA.slice(f, itms.total).get().concat( $iA.slice(0, l).get() ) );
				}

				if (is_function(fn))
				{
					fn.call($tt0, $i);
				}
				return $i;
			});


			//	isPaused, isStopped and isScrolling events
			$cfs.bind(cf_e('isPaused', conf)+' '+cf_e('isStopped', conf)+' '+cf_e('isScrolling', conf), function(e, fn) {
				e.stopPropagation();
				var eType = e.type.slice(conf.events.prefix.length),
					value = crsl[eType];
				if (is_function(fn))
				{
					fn.call($tt0, value);
				}
				return value;
			});


			//	configuration event
			$cfs.bind(cf_e('configuration', conf), function(e, a, b, c) {
				e.stopPropagation();
				var reInit = false;

				//	return entire configuration-object
				if (is_function(a))
				{
					a.call($tt0, opts);
				}
				//	set multiple options via object
				else if (is_object(a))
				{
					opts_orig = $.extend(true, {}, opts_orig, a);
					if (b !== false) reInit = true;
					else opts = $.extend(true, {}, opts, a);

				}
				else if (!is_undefined(a))
				{

					//	callback function for specific option
					if (is_function(b))
					{
						var val = eval('opts.'+a);
						if (is_undefined(val))
						{
							val = '';
						}
						b.call($tt0, val);
					}
					//	set individual option
					else if (!is_undefined(b))
					{
						if (typeof c !== 'boolean') c = true;
						eval('opts_orig.'+a+' = b');
						if (c !== false) reInit = true;
						else eval('opts.'+a+' = b');
					}
					//	return value for specific option
					else
					{
						return eval('opts.'+a);
					}
				}
				if (reInit)
				{
					sz_resetMargin($cfs.children(), opts);
					FN._init(opts_orig);
					FN._bind_buttons();
					var sz = sz_setSizes($cfs, opts);
					$cfs.trigger(cf_e('updatePageStatus', conf), [true, sz]);
				}
				return opts;
			});


			//	linkAnchors event
			$cfs.bind(cf_e('linkAnchors', conf), function(e, $con, sel) {
				e.stopPropagation();

				if (is_undefined($con))
				{
					$con = $('body');
				}
				else if (is_string($con))
				{
					$con = $($con);
				}
				if (!is_jquery($con) || $con.length == 0)
				{
					return debug(conf, 'Not a valid object.');
				}
				if (!is_string(sel))
				{
					sel = 'a.caroufredsel';
				}

				$con.find(sel).each(function() {
					var h = this.hash || '';
					if (h.length > 0 && $cfs.children().index($(h)) != -1)
					{
						$(this).unbind('click').click(function(e) {
							e.preventDefault();
							$cfs.trigger(cf_e('slideTo', conf), h);
						});
					}
				});
				return true;
			});


			//	updatePageStatus event
			$cfs.bind(cf_e('updatePageStatus', conf), function(e, build, sizes) {
				e.stopPropagation();
				if (!opts.pagination.container)
				{
					return;
				}

				var ipp = opts.pagination.items || opts.items.visible,
					pgs = Math.ceil(itms.total/ipp);

				if (build)
				{
					if (opts.pagination.anchorBuilder)
					{
						opts.pagination.container.children().remove();
						opts.pagination.container.each(function() {
							for (var a = 0; a < pgs; a++)
							{
								var i = $cfs.children().eq( gn_getItemIndex(a*ipp, 0, true, itms, $cfs) );
								$(this).append(opts.pagination.anchorBuilder.call(i[0], a+1));
							}
						});
					}
					opts.pagination.container.each(function() {
						$(this).children().unbind(opts.pagination.event).each(function(a) {
							$(this).bind(opts.pagination.event, function(e) {
								e.preventDefault();
								$cfs.trigger(cf_e('slideTo', conf), [a*ipp, -opts.pagination.deviation, true, opts.pagination]);
							});
						});
					});
				}

				var selected = $cfs.triggerHandler(cf_e('currentPage', conf)) + opts.pagination.deviation;
				if (selected >= pgs)
				{
					selected = 0;
				}
				if (selected < 0)
				{
					selected = pgs-1;
				}
				opts.pagination.container.each(function() {
					$(this).children().removeClass(cf_c('selected', conf)).eq(selected).addClass(cf_c('selected', conf));
				});
				return true;
			});


			//	updateSizes event
			$cfs.bind(cf_e('updateSizes', conf), function(e) {
				var vI = opts.items.visible,
					a_itm = $cfs.children(),
					avail_primary = ms_getParentSize($wrp, opts, 'width');

				itms.total = a_itm.length;

				if (crsl.primarySizePercentage)
				{
					opts.maxDimension = avail_primary;
					opts[opts.d['width']] = ms_getPercentage(avail_primary, crsl.primarySizePercentage);
				}
				else
				{
					opts.maxDimension = ms_getMaxDimension(opts, avail_primary);
				}

				if (opts.responsive)
				{
					opts.items.width = opts.items.sizesConf.width;
					opts.items.height = opts.items.sizesConf.height;
					opts = in_getResponsiveValues(opts, a_itm, avail_primary);
					vI = opts.items.visible;
					sz_setResponsiveSizes(opts, a_itm);
				}
				else if (opts.items.visibleConf.variable)
				{
					vI = gn_getVisibleItemsNext(a_itm, opts, 0);
				}
				else if (opts.items.filter != '*')
				{
					vI = gn_getVisibleItemsNextFilter(a_itm, opts, 0);
				}

				if (!opts.circular && itms.first != 0 && vI > itms.first) {
					if (opts.items.visibleConf.variable)
					{
						var nI = gn_getVisibleItemsPrev(a_itm, opts, itms.first) - itms.first;
					}
					else if (opts.items.filter != '*')
					{
						var nI = gn_getVisibleItemsPrevFilter(a_itm, opts, itms.first) - itms.first;
					}
					else
					{
						var nI = opts.items.visible - itms.first;
					}
					debug(conf, 'Preventing non-circular: sliding '+nI+' items backward.');
					$cfs.trigger(cf_e('prev', conf), nI);
				}

				opts.items.visible = cf_getItemsAdjust(vI, opts, opts.items.visibleConf.adjust, $tt0);
				opts.items.visibleConf.old = opts.items.visible;
				opts = in_getAlignPadding(opts, a_itm);

				var sz = sz_setSizes($cfs, opts);
				$cfs.trigger(cf_e('updatePageStatus', conf), [true, sz]);
				nv_showNavi(opts, itms.total, conf);
				nv_enableNavi(opts, itms.first, conf);

				return sz;
			});


			//	destroy event
			$cfs.bind(cf_e('destroy', conf), function(e, orgOrder) {
				e.stopPropagation();
				tmrs = sc_clearTimers(tmrs);

				$cfs.data('_cfs_isCarousel', false);
				$cfs.trigger(cf_e('finish', conf));
				if (orgOrder)
				{
					$cfs.trigger(cf_e('jumpToStart', conf));
				}
				sz_restoreOrigCss($cfs.children());
				sz_restoreOrigCss($cfs);
				FN._unbind_events();
				FN._unbind_buttons();
				if (conf.wrapper == 'parent')
				{
					sz_restoreOrigCss($wrp);
				}
				else
				{
					$wrp.replaceWith($cfs);
				}

				return true;
			});


			//	debug event
			$cfs.bind(cf_e('debug', conf), function(e) {
				debug(conf, 'Carousel width: ' + opts.width);
				debug(conf, 'Carousel height: ' + opts.height);
				debug(conf, 'Item widths: ' + opts.items.width);
				debug(conf, 'Item heights: ' + opts.items.height);
				debug(conf, 'Number of items visible: ' + opts.items.visible);
				if (opts.auto.play)
				{
					debug(conf, 'Number of items scrolled automatically: ' + opts.auto.items);
				}
				if (opts.prev.button)
				{
					debug(conf, 'Number of items scrolled backward: ' + opts.prev.items);
				}
				if (opts.next.button)
				{
					debug(conf, 'Number of items scrolled forward: ' + opts.next.items);
				}
				return conf.debug;
			});


			//	triggerEvent, making prefixed and namespaced events accessible from outside
			$cfs.bind('_cfs_triggerEvent', function(e, n, o) {
				e.stopPropagation();
				return $cfs.triggerHandler(cf_e(n, conf), o);
			});
		};	//	/bind_events


		FN._unbind_events = function() {
			$cfs.unbind(cf_e('', conf));
			$cfs.unbind(cf_e('', conf, false));
			$cfs.unbind('_cfs_triggerEvent');
		};	//	/unbind_events


		FN._bind_buttons = function() {
			FN._unbind_buttons();
			nv_showNavi(opts, itms.total, conf);
			nv_enableNavi(opts, itms.first, conf);

			if (opts.auto.pauseOnHover)
			{
				var pC = bt_pauseOnHoverConfig(opts.auto.pauseOnHover);
				$wrp.bind(cf_e('mouseenter', conf, false), function() { $cfs.trigger(cf_e('pause', conf), pC);	})
					.bind(cf_e('mouseleave', conf, false), function() { $cfs.trigger(cf_e('resume', conf));		});
			}

			//	play button
			if (opts.auto.button)
			{
				opts.auto.button.bind(cf_e(opts.auto.event, conf, false), function(e) {
					e.preventDefault();
					var ev = false,
						pC = null;

					if (crsl.isPaused)
					{
						ev = 'play';
					}
					else if (opts.auto.pauseOnEvent)
					{
						ev = 'pause';
						pC = bt_pauseOnHoverConfig(opts.auto.pauseOnEvent);
					}
					if (ev)
					{
						$cfs.trigger(cf_e(ev, conf), pC);
					}
				});
			}

			//	prev button
			if (opts.prev.button)
			{
				opts.prev.button.bind(cf_e(opts.prev.event, conf, false), function(e) {
					e.preventDefault();
					$cfs.trigger(cf_e('prev', conf));
				});
				if (opts.prev.pauseOnHover)
				{
					var pC = bt_pauseOnHoverConfig(opts.prev.pauseOnHover);
					opts.prev.button.bind(cf_e('mouseenter', conf, false), function() { $cfs.trigger(cf_e('pause', conf), pC);	})
									.bind(cf_e('mouseleave', conf, false), function() { $cfs.trigger(cf_e('resume', conf));		});
				}
			}

			//	next butotn
			if (opts.next.button)
			{
				opts.next.button.bind(cf_e(opts.next.event, conf, false), function(e) {
					e.preventDefault();
					$cfs.trigger(cf_e('next', conf));
				});
				if (opts.next.pauseOnHover)
				{
					var pC = bt_pauseOnHoverConfig(opts.next.pauseOnHover);
					opts.next.button.bind(cf_e('mouseenter', conf, false), function() { $cfs.trigger(cf_e('pause', conf), pC); 	})
									.bind(cf_e('mouseleave', conf, false), function() { $cfs.trigger(cf_e('resume', conf));		});
				}
			}

			//	pagination
			if (opts.pagination.container)
			{
				if (opts.pagination.pauseOnHover)
				{
					var pC = bt_pauseOnHoverConfig(opts.pagination.pauseOnHover);
					opts.pagination.container.bind(cf_e('mouseenter', conf, false), function() { $cfs.trigger(cf_e('pause', conf), pC);	})
											 .bind(cf_e('mouseleave', conf, false), function() { $cfs.trigger(cf_e('resume', conf));	});
				}
			}

			//	prev/next keys
			if (opts.prev.key || opts.next.key)
			{
				$(document).bind(cf_e('keyup', conf, false, true, true), function(e) {
					var k = e.keyCode;
					if (k == opts.next.key)
					{
						e.preventDefault();
						$cfs.trigger(cf_e('next', conf));
					}
					if (k == opts.prev.key)
					{
						e.preventDefault();
						$cfs.trigger(cf_e('prev', conf));
					}
				});
			}

			//	pagination keys
			if (opts.pagination.keys)
			{
				$(document).bind(cf_e('keyup', conf, false, true, true), function(e) {
					var k = e.keyCode;
					if (k >= 49 && k < 58)
					{
						k = (k-49) * opts.items.visible;
						if (k <= itms.total)
						{
							e.preventDefault();
							$cfs.trigger(cf_e('slideTo', conf), [k, 0, true, opts.pagination]);
						}
					}
				});
			}

			//	swipe
			if ($.fn.swipe)
			{
				var isTouch = 'ontouchstart' in window;
				if ((isTouch && opts.swipe.onTouch) || (!isTouch && opts.swipe.onMouse))
				{
					var scP = $.extend(true, {}, opts.prev, opts.swipe),
						scN = $.extend(true, {}, opts.next, opts.swipe),
						swP = function() { $cfs.trigger(cf_e('prev', conf), [scP]) },
						swN = function() { $cfs.trigger(cf_e('next', conf), [scN]) };

					switch (opts.direction)
					{
						case 'up':
						case 'down':
							opts.swipe.options.swipeUp = swN;
							opts.swipe.options.swipeDown = swP;
							break;
						default:
							opts.swipe.options.swipeLeft = swN;
							opts.swipe.options.swipeRight = swP;
					}
					if (crsl.swipe)
					{
						$cfs.swipe('destroy');
					}
					$wrp.swipe(opts.swipe.options);
					// ThemeFusion edit for Avada theme: cut out cursor appearance to style it in css
					crsl.swipe = true;
				}
			}

			//	mousewheel
			if ($.fn.mousewheel)
			{

				if (opts.mousewheel)
				{
					var mcP = $.extend(true, {}, opts.prev, opts.mousewheel),
						mcN = $.extend(true, {}, opts.next, opts.mousewheel);

					if (crsl.mousewheel)
					{
						$wrp.unbind(cf_e('mousewheel', conf, false));
					}
					$wrp.bind(cf_e('mousewheel', conf, false), function(e, delta) {
						e.preventDefault();
						if (delta > 0)
						{
							$cfs.trigger(cf_e('prev', conf), [mcP]);
						}
						else
						{
							$cfs.trigger(cf_e('next', conf), [mcN]);
						}
					});
					crsl.mousewheel = true;
				}
			}

			if (opts.auto.play)
			{
				$cfs.trigger(cf_e('play', conf), opts.auto.delay);
			}

			if (crsl.upDateOnWindowResize)
			{
				var resizeFn = function(e) {
					$cfs.trigger(cf_e('finish', conf));
					if (opts.auto.pauseOnResize && !crsl.isPaused)
					{
						$cfs.trigger(cf_e('play', conf));
					}
					sz_resetMargin($cfs.children(), opts);
					$cfs.trigger(cf_e('updateSizes', conf));
				};

				var $w = $(window),
					onResize = null;

				if ($.debounce && conf.onWindowResize == 'debounce')
				{
					onResize = $.debounce(200, resizeFn);
				}
				else if ($.throttle && conf.onWindowResize == 'throttle')
				{
					onResize = $.throttle(300, resizeFn);
				}
				else
				{
					var _windowWidth = 0,
						_windowHeight = 0;

					onResize = function() {
						var nw = $w.width(),
							nh = $w.height();

						if (nw != _windowWidth || nh != _windowHeight)
						{
							resizeFn();
							_windowWidth = nw;
							_windowHeight = nh;
						}
					};
				}
				$w.bind(cf_e('resize', conf, false, true, true), onResize);
			}
		};	//	/bind_buttons


		FN._unbind_buttons = function() {
			var ns1 = cf_e('', conf),
				ns2 = cf_e('', conf, false);
				ns3 = cf_e('', conf, false, true, true);

			$(document).unbind(ns3);
			$(window).unbind(ns3);
			$wrp.unbind(ns2);

			if (opts.auto.button)
			{
				opts.auto.button.unbind(ns2);
			}
			if (opts.prev.button)
			{
				opts.prev.button.unbind(ns2);
			}
			if (opts.next.button)
			{
				opts.next.button.unbind(ns2);
			}
			if (opts.pagination.container)
			{
				opts.pagination.container.unbind(ns2);
				if (opts.pagination.anchorBuilder)
				{
					opts.pagination.container.children().remove();
				}
			}
			if (crsl.swipe)
			{
				$cfs.swipe('destroy');
				$wrp.css('cursor', 'default');
				crsl.swipe = false;
			}
			if (crsl.mousewheel)
			{
				crsl.mousewheel = false;
			}

			nv_showNavi(opts, 'hide', conf);
			nv_enableNavi(opts, 'removeClass', conf);

		};	//	/unbind_buttons



		//	START

		if (is_boolean(configs))
		{
			configs = {
				'debug': configs
			};
		}

		//	set vars
		var crsl = {
				'direction'		: 'next',
				'isPaused'		: true,
				'isScrolling'	: false,
				'isStopped'		: false,
				'mousewheel'	: false,
				'swipe'			: false
			},
			itms = {
				'total'			: $cfs.children().length,
				'first'			: 0
			},
			tmrs = {
				'auto'			: null,
				'progress'		: null,
				'startTime'		: getTime(),
				'timePassed'	: 0
			},
			scrl = {
				'isStopped'		: false,
				'duration'		: 0,
				'startTime'		: 0,
				'easing'		: '',
				'anims'			: []
			},
			clbk = {
				'onBefore'		: [],
				'onAfter'		: []
			},
			queu = [],
			conf = $.extend(true, {}, $.fn.carouFredSel.configs, configs),
			opts = {},
			opts_orig = $.extend(true, {}, options),
			$wrp = (conf.wrapper == 'parent')
				? $cfs.parent()
				: $cfs.wrap('<'+conf.wrapper.element+' class="'+conf.wrapper.classname+'" />').parent();


		conf.selector		= $cfs.selector;
		conf.serialNumber	= $.fn.carouFredSel.serialNumber++;

		conf.transition = (conf.transition && $.fn.transition) ? 'transition' : 'animate';

		//	create carousel
		FN._init(opts_orig, true, starting_position);
		FN._build();
		FN._bind_events();
		FN._bind_buttons();

		//	find item to start
		if (is_array(opts.items.start))
		{
			var start_arr = opts.items.start;
		}
		else
		{
			var start_arr = [];
			if (opts.items.start != 0)
			{
				start_arr.push(opts.items.start);
			}
		}
		if (opts.cookie)
		{
			start_arr.unshift(parseInt(cf_getCookie(opts.cookie), 10));
		}

		if (start_arr.length > 0)
		{
			for (var a = 0, l = start_arr.length; a < l; a++)
			{
				var s = start_arr[a];
				if (s == 0)
				{
					continue;
				}
				if (s === true)
				{
					s = window.location.hash;
					if (s.length < 1)
					{
						continue;
					}
				}
				else if (s === 'random')
				{
					s = Math.floor(Math.random()*itms.total);
				}
				if ($cfs.triggerHandler(cf_e('slideTo', conf), [s, 0, true, { fx: 'none' }]))
				{
					break;
				}
			}
		}
		var siz = sz_setSizes($cfs, opts),
			itm = gi_getCurrentItems($cfs.children(), opts);

		if (opts.onCreate)
		{
			opts.onCreate.call($tt0, {
				'width': siz.width,
				'height': siz.height,
				'items': itm
			});
		}

		$cfs.trigger(cf_e('updatePageStatus', conf), [true, siz]);
		$cfs.trigger(cf_e('linkAnchors', conf));

		if (conf.debug)
		{
			$cfs.trigger(cf_e('debug', conf));
		}

		return $cfs;
	};



	//	GLOBAL PUBLIC

	$.fn.carouFredSel.serialNumber = 1;
	$.fn.carouFredSel.defaults = {
		'synchronise'	: false,
		'infinite'		: true,
		'circular'		: true,
		'responsive'	: false,
		'centerVertically' : false, // ThemeFusion edit for Avada theme: new param for vertically centering of items
		'direction'		: 'left',
		'items'			: {
			'start'			: 0
		},
		'scroll'		: {
			'easing'		: 'swing',
			'duration'		: 500,
			'pauseOnHover'	: false,
			'event'			: 'click',
			'queue'			: false
		}
	};
	$.fn.carouFredSel.configs = {
		'debug'			: false,
		'transition'	: false,
		'onWindowResize': 'throttle',
		'events'		: {
			'prefix'		: '',
			'namespace'		: 'cfs'
		},
		'wrapper'		: {
			'element'		: 'div',
			'classname'		: 'caroufredsel_wrapper'
		},
		'classnames'	: {}
	};
	$.fn.carouFredSel.pageAnchorBuilder = function(nr) {
		return '<a href="#"><span>'+nr+'</span></a>';
	};
	$.fn.carouFredSel.progressbarUpdater = function(perc) {
		$(this).css('width', perc+'%');
	};

	$.fn.carouFredSel.cookie = {
		get: function(n) {
			n += '=';
			var ca = document.cookie.split(';');
			for (var a = 0, l = ca.length; a < l; a++)
			{
				var c = ca[a];
				while (c.charAt(0) == ' ')
				{
					c = c.slice(1);
				}
				if (c.indexOf(n) == 0)
				{
					return c.slice(n.length);
				}
			}
			return 0;
		},
		set: function(n, v, d) {
			var e = "";
			if (d)
			{
				var date = new Date();
				date.setTime(date.getTime() + (d * 24 * 60 * 60 * 1000));
				e = "; expires=" + date.toGMTString();
			}
			document.cookie = n + '=' + v + e + '; path=/';
		},
		remove: function(n) {
			$.fn.carouFredSel.cookie.set(n, "", -1);
		}
	};


	//	GLOBAL PRIVATE

	//	scrolling functions
	function sc_setScroll(d, e, c) {
		if (c.transition == 'transition')
		{
			if (e == 'swing')
			{
				e = 'ease';
			}
		}
		return {
			anims: [],
			duration: d,
			orgDuration: d,
			easing: e,
			startTime: getTime()
		};
	}
	function sc_startScroll(s, c) {
		for (var a = 0, l = s.anims.length; a < l; a++)
		{
			var b = s.anims[a];
			if (!b)
			{
				continue;
			}
			b[0][c.transition](b[1], s.duration, s.easing, b[2]);
		}
	}
	function sc_stopScroll(s, finish) {
		if (!is_boolean(finish))
		{
			finish = true;
		}
		if (is_object(s.pre))
		{
			sc_stopScroll(s.pre, finish);
		}
		for (var a = 0, l = s.anims.length; a < l; a++)
		{
			var b = s.anims[a];
			b[0].stop(true);

			if (finish)
			{
				b[0].css(b[1]);
				if (is_function(b[2]))
				{
					b[2]();
				}
			}
		}
		if (is_object(s.post))
		{
			sc_stopScroll(s.post, finish);
		}
	}
	function sc_afterScroll( $c, $c2, o ) {
		if ($c2)
		{
			$c2.remove();
		}

		switch(o.fx) {
			case 'fade':
			case 'crossfade':
			case 'cover-fade':
			case 'uncover-fade':
				$c.css('opacity', 1);
				$c.css('filter', '');
				break;
		}
	}
	function sc_fireCallbacks($t, o, b, a, c) {
		if (o[b])
		{
			o[b].call($t, a);
		}
		if (c[b].length)
		{
			for (var i = 0, l = c[b].length; i < l; i++)
			{
				c[b][i].call($t, a);
			}
		}
		return [];
	}
	function sc_fireQueue($c, q, c) {

		if (q.length)
		{
			$c.trigger(cf_e(q[0][0], c), q[0][1]);
			q.shift();
		}
		return q;
	}
	function sc_hideHiddenItems(hiddenitems) {
		hiddenitems.each(function() {
			var hi = $(this);
			hi.data('_cfs_isHidden', hi.is(':hidden')).hide();
		});
	}
	function sc_showHiddenItems(hiddenitems) {
		if (hiddenitems)
		{
			hiddenitems.each(function() {
				var hi = $(this);
				if (!hi.data('_cfs_isHidden'))
				{
					hi.show();
				}
			});
		}
	}
	function sc_clearTimers(t) {
		if (t.auto)
		{
			clearTimeout(t.auto);
		}
		if (t.progress)
		{
			clearInterval(t.progress);
		}
		return t;
	}
	function sc_mapCallbackArguments(i_old, i_skp, i_new, s_itm, s_dir, s_dur, w_siz) {
		return {
			'width': w_siz.width,
			'height': w_siz.height,
			'items': {
				'old': i_old,
				'skipped': i_skp,
				'visible': i_new
			},
			'scroll': {
				'items': s_itm,
				'direction': s_dir,
				'duration': s_dur
			}
		};
	}
	function sc_getDuration( sO, o, nI, siz ) {
		var dur = sO.duration;
		if (sO.fx == 'none')
		{
			return 0;
		}
		if (dur == 'auto')
		{
			dur = o.scroll.duration / o.scroll.items * nI;
		}
		else if (dur < 10)
		{
			dur = siz / dur;
		}
		if (dur < 1)
		{
			return 0;
		}
		if (sO.fx == 'fade')
		{
			dur = dur / 2;
		}
		return Math.round(dur);
	}

	//	navigation functions
	function nv_showNavi(o, t, c) {
		var minimum = (is_number(o.items.minimum)) ? o.items.minimum : o.items.visible + 1;
		if (t == 'show' || t == 'hide')
		{
			var f = t;
		}
		else if (minimum > t)
		{
			debug(c, 'Not enough items ('+t+' total, '+minimum+' needed): Hiding navigation.');
			var f = 'hide';
		}
		else
		{
			var f = 'show';
		}
		var s = (f == 'show') ? 'removeClass' : 'addClass',
			h = cf_c('hidden', c);

		if (o.auto.button)
		{
			o.auto.button[f]()[s](h);
		}
		if (o.prev.button)
		{
			o.prev.button[f]()[s](h);
		}
		if (o.next.button)
		{
			o.next.button[f]()[s](h);
		}
		if (o.pagination.container)
		{
			o.pagination.container[f]()[s](h);
		}
	}
	function nv_enableNavi(o, f, c) {
		if (o.circular || o.infinite) return;
		var fx = (f == 'removeClass' || f == 'addClass') ? f : false,
			di = cf_c('disabled', c);

		if (o.auto.button && fx)
		{
			o.auto.button[fx](di);
		}
		if (o.prev.button)
		{
			var fn = fx || (f == 0) ? 'addClass' : 'removeClass';
			o.prev.button[fn](di);
		}
		if (o.next.button)
		{
			var fn = fx || (f == o.items.visible) ? 'addClass' : 'removeClass';
			o.next.button[fn](di);
		}
	}

	//	get object functions
	function go_getObject($tt, obj) {
		if (is_function(obj))
		{
			obj = obj.call($tt);
		}
		else if (is_undefined(obj))
		{
			obj = {};
		}
		return obj;
	}
	function go_getItemsObject($tt, obj) {
		obj = go_getObject($tt, obj);
		if (is_number(obj))
		{
			obj	= {
				'visible': obj
			};
		}
		else if (obj == 'variable')
		{
			obj = {
				'visible': obj,
				'width': obj,
				'height': obj
			};
		}
		else if (!is_object(obj))
		{
			obj = {};
		}
		return obj;
	}
	function go_getScrollObject($tt, obj) {
		obj = go_getObject($tt, obj);
		if (is_number(obj))
		{
			if (obj <= 50)
			{
				obj = {
					'items': obj
				};
			}
			else
			{
				obj = {
					'duration': obj
				};
			}
		}
		else if (is_string(obj))
		{
			obj = {
				'easing': obj
			};
		}
		else if (!is_object(obj))
		{
			obj = {};
		}
		return obj;
	}
	function go_getNaviObject($tt, obj) {
		obj = go_getObject($tt, obj);
		if (is_string(obj))
		{
			var temp = cf_getKeyCode(obj);
			if (temp == -1)
			{
				obj = $(obj);
			}
			else
			{
				obj = temp;
			}
		}
		return obj;
	}

	function go_getAutoObject($tt, obj) {
		obj = go_getNaviObject($tt, obj);
		if (is_jquery(obj))
		{
			obj = {
				'button': obj
			};
		}
		else if (is_boolean(obj))
		{
			obj = {
				'play': obj
			};
		}
		else if (is_number(obj))
		{
			obj = {
				'timeoutDuration': obj
			};
		}
		if (obj.progress)
		{
			if (is_string(obj.progress) || is_jquery(obj.progress))
			{
				obj.progress = {
					'bar': obj.progress
				};
			}
		}
		return obj;
	}
	function go_complementAutoObject($tt, obj) {
		if (is_function(obj.button))
		{
			obj.button = obj.button.call($tt);
		}
		if (is_string(obj.button))
		{
			obj.button = $(obj.button);
		}
		if (!is_boolean(obj.play))
		{
			obj.play = true;
		}
		if (!is_number(obj.delay))
		{
			obj.delay = 0;
		}
		if (is_undefined(obj.pauseOnEvent))
		{
			obj.pauseOnEvent = true;
		}
		if (!is_boolean(obj.pauseOnResize))
		{
			obj.pauseOnResize = true;
		}
		if (!is_number(obj.timeoutDuration))
		{
			obj.timeoutDuration = (obj.duration < 10)
				? 2500
				: obj.duration * 5;
		}
		if (obj.progress)
		{
			if (is_function(obj.progress.bar))
			{
				obj.progress.bar = obj.progress.bar.call($tt);
			}
			if (is_string(obj.progress.bar))
			{
				obj.progress.bar = $(obj.progress.bar);
			}
			if (obj.progress.bar)
			{
				if (!is_function(obj.progress.updater))
				{
					obj.progress.updater = $.fn.carouFredSel.progressbarUpdater;
				}
				if (!is_number(obj.progress.interval))
				{
					obj.progress.interval = 50;
				}
			}
			else
			{
				obj.progress = false;
			}
		}
		return obj;
	}

	function go_getPrevNextObject($tt, obj) {
		obj = go_getNaviObject($tt, obj);
		if (is_jquery(obj))
		{
			obj = {
				'button': obj
			};
		}
		else if (is_number(obj))
		{
			obj = {
				'key': obj
			};
		}
		return obj;
	}
	function go_complementPrevNextObject($tt, obj) {
		if (is_function(obj.button))
		{
			obj.button = obj.button.call($tt);
		}
		if (is_string(obj.button))
		{
			obj.button = $(obj.button);
		}
		if (is_string(obj.key))
		{
			obj.key = cf_getKeyCode(obj.key);
		}
		return obj;
	}

	function go_getPaginationObject($tt, obj) {
		obj = go_getNaviObject($tt, obj);
		if (is_jquery(obj))
		{
			obj = {
				'container': obj
			};
		}
		else if (is_boolean(obj))
		{
			obj = {
				'keys': obj
			};
		}
		return obj;
	}
	function go_complementPaginationObject($tt, obj) {
		if (is_function(obj.container))
		{
			obj.container = obj.container.call($tt);
		}
		if (is_string(obj.container))
		{
			obj.container = $(obj.container);
		}
		if (!is_number(obj.items))
		{
			obj.items = false;
		}
		if (!is_boolean(obj.keys))
		{
			obj.keys = false;
		}
		if (!is_function(obj.anchorBuilder) && !is_false(obj.anchorBuilder))
		{
			obj.anchorBuilder = $.fn.carouFredSel.pageAnchorBuilder;
		}
		if (!is_number(obj.deviation))
		{
			obj.deviation = 0;
		}
		return obj;
	}

	function go_getSwipeObject($tt, obj) {
		if (is_function(obj))
		{
			obj = obj.call($tt);
		}
		if (is_undefined(obj))
		{
			obj = {
				'onTouch': false
			};
		}
		if (is_true(obj))
		{
			obj = {
				'onTouch': obj
			};
		}
		else if (is_number(obj))
		{
			obj = {
				'items': obj
			};
		}
		return obj;
	}
	function go_complementSwipeObject($tt, obj) {
		if (!is_boolean(obj.onTouch))
		{
			obj.onTouch = true;
		}
		if (!is_boolean(obj.onMouse))
		{
			obj.onMouse = false;
		}
		if (!is_object(obj.options))
		{
			obj.options = {};
		}
		if (!is_boolean(obj.options.triggerOnTouchEnd))
		{
			obj.options.triggerOnTouchEnd = false;
		}
		return obj;
	}
	function go_getMousewheelObject($tt, obj) {
		if (is_function(obj))
		{
			obj = obj.call($tt);
		}
		if (is_true(obj))
		{
			obj = {};
		}
		else if (is_number(obj))
		{
			obj = {
				'items': obj
			};
		}
		else if (is_undefined(obj))
		{
			obj = false;
		}
		return obj;
	}
	function go_complementMousewheelObject($tt, obj) {
		return obj;
	}

	//	get number functions
	function gn_getItemIndex(num, dev, org, items, $cfs) {
		if (is_string(num))
		{
			num = $(num, $cfs);
		}

		if (is_object(num))
		{
			num = $(num, $cfs);
		}
		if (is_jquery(num))
		{
			num = $cfs.children().index(num);
			if (!is_boolean(org))
			{
				org = false;
			}
		}
		else
		{
			if (!is_boolean(org))
			{
				org = true;
			}
		}
		if (!is_number(num))
		{
			num = 0;
		}
		if (!is_number(dev))
		{
			dev = 0;
		}

		if (org)
		{
			num += items.first;
		}
		num += dev;
		if (items.total > 0)
		{
			while (num >= items.total)
			{
				num -= items.total;
			}
			while (num < 0)
			{
				num += items.total;
			}
		}
		return num;
	}

	//	items prev
	function gn_getVisibleItemsPrev(i, o, s) {
		var t = 0,
			x = 0;

		for (var a = s; a >= 0; a--)
		{
			var j = i.eq(a);
			t += (j.is(':visible')) ? j[o.d['outerWidth']](true) : 0;
			if (t > o.maxDimension)
			{
				return x;
			}
			if (a == 0)
			{
				a = i.length;
			}
			x++;
		}
	}
	function gn_getVisibleItemsPrevFilter(i, o, s) {
		return gn_getItemsPrevFilter(i, o.items.filter, o.items.visibleConf.org, s);
	}
	function gn_getScrollItemsPrevFilter(i, o, s, m) {
		return gn_getItemsPrevFilter(i, o.items.filter, m, s);
	}
	function gn_getItemsPrevFilter(i, f, m, s) {
		var t = 0,
			x = 0;

		for (var a = s, l = i.length; a >= 0; a--)
		{
			x++;
			if (x == l)
			{
				return x;
			}

			var j = i.eq(a);
			if (j.is(f))
			{
				t++;
				if (t == m)
				{
					return x;
				}
			}
			if (a == 0)
			{
				a = l;
			}
		}
	}

	function gn_getVisibleOrg($c, o) {
		return o.items.visibleConf.org || $c.children().slice(0, o.items.visible).filter(o.items.filter).length;
	}

	//	items next
	function gn_getVisibleItemsNext(i, o, s) {
		var t = 0,
			x = 0;

		for (var a = s, l = i.length-1; a <= l; a++)
		{
			var j = i.eq(a);

			t += (j.is(':visible')) ? j[o.d['outerWidth']](true) : 0;
			if (t > o.maxDimension)
			{
				return x;
			}

			x++;
			if (x == l+1)
			{
				return x;
			}
			if (a == l)
			{
				a = -1;
			}
		}
	}
	function gn_getVisibleItemsNextTestCircular(i, o, s, l) {
		var v = gn_getVisibleItemsNext(i, o, s);
		if (!o.circular)
		{
			if (s + v > l)
			{
				v = l - s;
			}
		}
		return v;
	}
	function gn_getVisibleItemsNextFilter(i, o, s) {
		return gn_getItemsNextFilter(i, o.items.filter, o.items.visibleConf.org, s, o.circular);
	}
	function gn_getScrollItemsNextFilter(i, o, s, m) {
		return gn_getItemsNextFilter(i, o.items.filter, m+1, s, o.circular) - 1;
	}
	function gn_getItemsNextFilter(i, f, m, s, c) {
		var t = 0,
			x = 0;

		for (var a = s, l = i.length-1; a <= l; a++)
		{
			x++;
			if (x >= l)
			{
				return x;
			}

			var j = i.eq(a);
			if (j.is(f))
			{
				t++;
				if (t == m)
				{
					return x;
				}
			}
			if (a == l)
			{
				a = -1;
			}
		}
	}

	//	get items functions
	function gi_getCurrentItems(i, o) {
		return i.slice(0, o.items.visible);
	}
	function gi_getOldItemsPrev(i, o, n) {
		return i.slice(n, o.items.visibleConf.old+n);
	}
	function gi_getNewItemsPrev(i, o) {
		return i.slice(0, o.items.visible);
	}
	function gi_getOldItemsNext(i, o) {
		return i.slice(0, o.items.visibleConf.old);
	}
	function gi_getNewItemsNext(i, o, n) {
		return i.slice(n, o.items.visible+n);
	}

	//	sizes functions
	function sz_storeMargin(i, o, d) {
		if (o.usePadding)
		{
			if (!is_string(d))
			{
				d = '_cfs_origCssMargin';
			}
			i.each(function() {
				var j = $(this),
					m = parseInt(j.css(o.d['marginRight']), 10);
				if (!is_number(m))
				{
					m = 0;
				}
				j.data(d, m);
			});
		}
	}
	function sz_resetMargin(i, o, m) {
		if (o.usePadding)
		{
			var x = (is_boolean(m)) ? m : false;
			if (!is_number(m))
			{
				m = 0;
			}
			sz_storeMargin(i, o, '_cfs_tempCssMargin');
			i.each(function() {
				var j = $(this);
				j.css(o.d['marginRight'], ((x) ? j.data('_cfs_tempCssMargin') : m + j.data('_cfs_origCssMargin')));
			});
		}
	}
	function sz_storeOrigCss(i) {
		i.each(function() {
			var j = $(this);
			j.data('_cfs_origCss', j.attr('style') || '');
		});
	}
	function sz_restoreOrigCss(i) {
		i.each(function() {
			var j = $(this);
			j.attr('style', j.data('_cfs_origCss') || '');
		});
	}
	function sz_setResponsiveSizes(o, all) {
		var visb = o.items.visible,
			newS = o.items[o.d['width']],
			seco = o[o.d['height']],
			secp = is_percentage(seco);

		all.each(function() {
			var $t = $(this),
				nw = newS - ms_getPaddingBorderMargin($t, o, 'Width');

			$t[o.d['width']](nw);
			if (secp)
			{
				$t[o.d['height']](ms_getPercentage(nw, seco));
			}
		});
	}
	function sz_setSizes($c, o) {
		var $w = $c.parent(),
			$i = $c.children(),
			$v = gi_getCurrentItems($i, o),
			sz = cf_mapWrapperSizes(ms_getSizes($v, o, true), o, false);

		$w.css(sz);

		if (o.usePadding)
		{
			var p = o.padding,
				r = p[o.d[1]];

			if (o.align && r < 0)
			{
				r = 0;
			}
			var $l = $v.last();
			$l.css(o.d['marginRight'], $l.data('_cfs_origCssMargin') + r);
			$c.css(o.d['top'], p[o.d[0]]);
			$c.css(o.d['left'], p[o.d[3]]);
		}

		$c.css(o.d['width'], sz[o.d['width']]+(ms_getTotalSize($i, o, 'width')*2));
		$c.css(o.d['height'], ms_getLargestSize($i, o, 'height'));

		// ThemeFusion edit for Avada theme: set the correct line-height on the carousel main ul element on window resize
		if ( o['centerVertically'] ) {
			$c.css( 'line-height', sz['height'] + 'px' );
		}

		return sz;
	}

	//	measuring functions
	function ms_getSizes(i, o, wrapper) {
		return [ms_getTotalSize(i, o, 'width', wrapper), ms_getLargestSize(i, o, 'height', wrapper)];
	}
	function ms_getLargestSize(i, o, dim, wrapper) {
		if (!is_boolean(wrapper))
		{
			wrapper = false;
		}
		if (is_number(o[o.d[dim]]) && wrapper)
		{
			return o[o.d[dim]];
		}
		if (is_number(o.items[o.d[dim]]))
		{
			return o.items[o.d[dim]];
		}
		dim = (dim.toLowerCase().indexOf('width') > -1) ? 'outerWidth' : 'outerHeight';
		return ms_getTrueLargestSize(i, o, dim);
	}
	function ms_getTrueLargestSize(i, o, dim) {
		var s = 0;

		for (var a = 0, l = i.length; a < l; a++)
		{
			// ThemeFusion eidit for Avada theme: extract height from the actual image and not from wrapping containers (line-height)
			var j = i.eq(a).find( '.fusion-carousel-item-wrapper' );

			var m = (j.is(':visible')) ? j[o.d[dim]](true) : 0;
			if (s < m)
			{
				s = m;
			}
		}
		return s;
	}

	function ms_getTotalSize(i, o, dim, wrapper) {
		if (!is_boolean(wrapper))
		{
			wrapper = false;
		}
		if (is_number(o[o.d[dim]]) && wrapper)
		{
			return o[o.d[dim]];
		}
		if (is_number(o.items[o.d[dim]]))
		{
			return o.items[o.d[dim]] * i.length;
		}

		var d = (dim.toLowerCase().indexOf('width') > -1) ? 'outerWidth' : 'outerHeight',
			s = 0;

		for (var a = 0, l = i.length; a < l; a++)
		{
			var j = i.eq(a);
			s += (j.is(':visible')) ? j[o.d[d]](true) : 0;
		}
		return s;
	}
	function ms_getParentSize($w, o, d) {
		var isVisible = $w.is(':visible');
		if (isVisible)
		{
			$w.hide();
		}
		var s = $w.parent()[o.d[d]]();
		if (isVisible)
		{
			$w.show();
		}
		return s;
	}
	function ms_getMaxDimension(o, a) {
		return (is_number(o[o.d['width']])) ? o[o.d['width']] : a;
	}
	function ms_hasVariableSizes(i, o, dim) {
		var s = false,
			v = false;

		for (var a = 0, l = i.length; a < l; a++)
		{
			var j = i.eq(a);

			var c = (j.is(':visible')) ? j[o.d[dim]](true) : 0;
			if (s === false)
			{
				s = c;
			}
			else if (s != c)
			{
				v = true;
			}
			if (s == 0)
			{
				v = true;
			}
		}
		return v;
	}
	function ms_getPaddingBorderMargin(i, o, d) {
		return i[o.d['outer'+d]](true) - i[o.d[d.toLowerCase()]]();
	}
	function ms_getPercentage(s, o) {
		if (is_percentage(o))
		{
			o = parseInt( o.slice(0, -1), 10 );
			if (!is_number(o))
			{
				return s;
			}
			s *= o/100;
		}
		return s;
	}

	//	config functions
	function cf_e(n, c, pf, ns, rd) {
		if (!is_boolean(pf))
		{
			pf = true;
		}
		if (!is_boolean(ns))
		{
			ns = true;
		}
		if (!is_boolean(rd))
		{
			rd = false;
		}

		if (pf)
		{
			n = c.events.prefix + n;
		}
		if (ns)
		{
			n = n +'.'+ c.events.namespace;
		}
		if (ns && rd)
		{
			n += c.serialNumber;
		}

		return n;
	}
	function cf_c(n, c) {
		return (is_string(c.classnames[n])) ? c.classnames[n] : n;
	}
	function cf_mapWrapperSizes(ws, o, p) {
		if (!is_boolean(p))
		{
			p = true;
		}
		var pad = (o.usePadding && p) ? o.padding : [0, 0, 0, 0];
		var wra = {};

		wra[o.d['width']] = ws[0] + pad[1] + pad[3];
		wra[o.d['height']] = ws[1] + pad[0] + pad[2];

		return wra;
	}
	function cf_sortParams(vals, typs) {
		var arr = [];
		for (var a = 0, l1 = vals.length; a < l1; a++)
		{
			for (var b = 0, l2 = typs.length; b < l2; b++)
			{
				if (typs[b].indexOf(typeof vals[a]) > -1 && is_undefined(arr[b]))
				{
					arr[b] = vals[a];
					break;
				}
			}
		}
		return arr;
	}
	function cf_getPadding(p) {
		if (is_undefined(p))
		{
			return [0, 0, 0, 0];
		}
		if (is_number(p))
		{
			return [p, p, p, p];
		}
		if (is_string(p))
		{
			p = p.split('px').join('').split('em').join('').split(' ');
		}

		if (!is_array(p))
		{
			return [0, 0, 0, 0];
		}
		for (var i = 0; i < 4; i++)
		{
			p[i] = parseInt(p[i], 10);
		}
		switch (p.length)
		{
			case 0:
				return [0, 0, 0, 0];
			case 1:
				return [p[0], p[0], p[0], p[0]];
			case 2:
				return [p[0], p[1], p[0], p[1]];
			case 3:
				return [p[0], p[1], p[2], p[1]];
			default:
				return [p[0], p[1], p[2], p[3]];
		}
	}
	function cf_getAlignPadding(itm, o) {
		var x = (is_number(o[o.d['width']])) ? Math.ceil(o[o.d['width']] - ms_getTotalSize(itm, o, 'width')) : 0;
		switch (o.align)
		{
			case 'left':
				return [0, x];
			case 'right':
				return [x, 0];
			case 'center':
			default:
				return [Math.ceil(x/2), Math.floor(x/2)];
		}
	}
	function cf_getDimensions(o) {
		var dm = [
				['width'	, 'innerWidth'	, 'outerWidth'	, 'height'	, 'innerHeight'	, 'outerHeight'	, 'left', 'top'	, 'marginRight'	, 0, 1, 2, 3],
				['height'	, 'innerHeight'	, 'outerHeight'	, 'width'	, 'innerWidth'	, 'outerWidth'	, 'top'	, 'left', 'marginBottom', 3, 2, 1, 0]
			];

		var dl = dm[0].length,
			dx = (o.direction == 'right' || o.direction == 'left') ? 0 : 1;

		var dimensions = {};
		for (var d = 0; d < dl; d++)
		{
			dimensions[dm[0][d]] = dm[dx][d];
		}
		return dimensions;
	}
	function cf_getAdjust(x, o, a, $t) {
		var v = x;
		if (is_function(a))
		{
			v = a.call($t, v);

		}
		else if (is_string(a))
		{
			var p = a.split('+'),
				m = a.split('-');

			if (m.length > p.length)
			{
				var neg = true,
					sta = m[0],
					adj = m[1];
			}
			else
			{
				var neg = false,
					sta = p[0],
					adj = p[1];
			}

			switch(sta)
			{
				case 'even':
					v = (x % 2 == 1) ? x-1 : x;
					break;
				case 'odd':
					v = (x % 2 == 0) ? x-1 : x;
					break;
				default:
					v = x;
					break;
			}
			adj = parseInt(adj, 10);
			if (is_number(adj))
			{
				if (neg)
				{
					adj = -adj;
				}
				v += adj;
			}
		}
		if (!is_number(v) || v < 1)
		{
			v = 1;
		}
		return v;
	}
	function cf_getItemsAdjust(x, o, a, $t) {
		return cf_getItemAdjustMinMax(cf_getAdjust(x, o, a, $t), o.items.visibleConf);
	}
	function cf_getItemAdjustMinMax(v, i) {
		if (is_number(i.min) && v < i.min)
		{
			v = i.min;
		}
		if (is_number(i.max) && v > i.max)
		{
			v = i.max;
		}
		if (v < 1)
		{
			v = 1;
		}
		return v;
	}
	function cf_getSynchArr(s) {
		if (!is_array(s))
		{
			s = [[s]];
		}
		if (!is_array(s[0]))
		{
			s = [s];
		}
		for (var j = 0, l = s.length; j < l; j++)
		{
			if (is_string(s[j][0]))
			{
				s[j][0] = $(s[j][0]);
			}
			if (!is_boolean(s[j][1]))
			{
				s[j][1] = true;
			}
			if (!is_boolean(s[j][2]))
			{
				s[j][2] = true;
			}
			if (!is_number(s[j][3]))
			{
				s[j][3] = 0;
			}
		}
		return s;
	}
	function cf_getKeyCode(k) {
		if (k == 'right')
		{
			return 39;
		}
		if (k == 'left')
		{
			return 37;
		}
		if (k == 'up')
		{
			return 38;
		}
		if (k == 'down')
		{
			return 40;
		}
		return -1;
	}
	function cf_setCookie(n, $c, c) {
		if (n)
		{
			var v = $c.triggerHandler(cf_e('currentPosition', c));
			$.fn.carouFredSel.cookie.set(n, v);
		}
	}
	function cf_getCookie(n) {
		var c = $.fn.carouFredSel.cookie.get(n);
		return (c == '') ? 0 : c;
	}

	//	init function
	function in_mapCss($elem, props) {
		var css = {};
		for (var p = 0, l = props.length; p < l; p++)
		{
			css[props[p]] = $elem.css(props[p]);
		}
		return css;
	}
	function in_complementItems(obj, opt, itm, sta) {
		if (!is_object(obj.visibleConf))
		{
			obj.visibleConf = {};
		}
		if (!is_object(obj.sizesConf))
		{
			obj.sizesConf = {};
		}

		if (obj.start == 0 && is_number(sta))
		{
			obj.start = sta;
		}

		//	visible items
		if (is_object(obj.visible))
		{
			obj.visibleConf.min = obj.visible.min;
			obj.visibleConf.max = obj.visible.max;
			obj.visible = false;
		}
		else if (is_string(obj.visible))
		{
			//	variable visible items
			if (obj.visible == 'variable')
			{
				obj.visibleConf.variable = true;
			}
			//	adjust string visible items
			else
			{
				obj.visibleConf.adjust = obj.visible;
			}
			obj.visible = false;
		}
		else if (is_function(obj.visible))
		{
			obj.visibleConf.adjust = obj.visible;
			obj.visible = false;
		}

		//	set items filter
		if (!is_string(obj.filter))
		{
			obj.filter = (itm.filter(':hidden').length > 0) ? ':visible' : '*';
		}

		//	primary item-size not set
		if (!obj[opt.d['width']])
		{
			//	responsive carousel -> set to largest
			if (opt.responsive)
			{
				debug(true, 'Set a '+opt.d['width']+' for the items!');
				obj[opt.d['width']] = ms_getTrueLargestSize(itm, opt, 'outerWidth');
			}
			//	 non-responsive -> measure it or set to "variable"
			else
			{
				obj[opt.d['width']] = (ms_hasVariableSizes(itm, opt, 'outerWidth'))
					? 'variable'
					: itm[opt.d['outerWidth']](true);
			}
		}

		//	secondary item-size not set -> measure it or set to "variable"
		if (!obj[opt.d['height']])
		{
			obj[opt.d['height']] = (ms_hasVariableSizes(itm, opt, 'outerHeight'))
				? 'variable'
				: itm[opt.d['outerHeight']](true);
		}

		obj.sizesConf.width = obj.width;
		obj.sizesConf.height = obj.height;
		return obj;
	}
	function in_complementVisibleItems(opt, avl) {
		//	primary item-size variable -> set visible items variable
		if (opt.items[opt.d['width']] == 'variable')
		{
			opt.items.visibleConf.variable = true;
		}
		if (!opt.items.visibleConf.variable) {
			//	primary size is number -> calculate visible-items
			if (is_number(opt[opt.d['width']]))
			{
				opt.items.visible = Math.floor(opt[opt.d['width']] / opt.items[opt.d['width']]);
			}
			//	measure and calculate primary size and visible-items
			else
			{
				opt.items.visible = Math.floor(avl / opt.items[opt.d['width']]);
				opt[opt.d['width']] = opt.items.visible * opt.items[opt.d['width']];
				if (!opt.items.visibleConf.adjust)
				{
					opt.align = false;
				}
			}
			if (opt.items.visible == 'Infinity' || opt.items.visible < 1)
			{
				debug(true, 'Not a valid number of visible items: Set to "variable".');
				opt.items.visibleConf.variable = true;
			}
		}
		return opt;
	}
	function in_complementPrimarySize(obj, opt, all) {
		//	primary size set to auto -> measure largest item-size and set it
		if (obj == 'auto')
		{
			obj = ms_getTrueLargestSize(all, opt, 'outerWidth');
		}
		return obj;
	}
	function in_complementSecondarySize(obj, opt, all) {
		//	secondary size set to auto -> measure largest item-size and set it
		if (obj == 'auto')
		{
			obj = ms_getTrueLargestSize(all, opt, 'outerHeight');
		}
		//	secondary size not set -> set to secondary item-size
		if (!obj)
		{
			obj = opt.items[opt.d['height']];
		}
		return obj;
	}
	function in_getAlignPadding(o, all) {
		var p = cf_getAlignPadding(gi_getCurrentItems(all, o), o);
		o.padding[o.d[1]] = p[1];
		o.padding[o.d[3]] = p[0];
		return o;
	}
	function in_getResponsiveValues(o, all, avl) {

		var visb = cf_getItemAdjustMinMax(Math.ceil(o[o.d['width']] / o.items[o.d['width']]), o.items.visibleConf);
		if (visb > all.length)
		{
			visb = all.length;
		}

		var newS = Math.floor(o[o.d['width']]/visb);

		o.items.visible = visb;
		o.items[o.d['width']] = newS;
		o[o.d['width']] = visb * newS;
		return o;
	}


	//	buttons functions
	function bt_pauseOnHoverConfig(p) {
		if (is_string(p))
		{
			var i = (p.indexOf('immediate') > -1) ? true : false,
				r = (p.indexOf('resume') 	> -1) ? true : false;
		}
		else
		{
			var i = r = false;
		}
		return [i, r];
	}
	function bt_mousesheelNumber(mw) {
		return (is_number(mw)) ? mw : null
	}

	//	helper functions
	function is_null(a) {
		return (a === null);
	}
	function is_undefined(a) {
		return (is_null(a) || typeof a == 'undefined' || a === '' || a === 'undefined');
	}
	function is_array(a) {
		return (a instanceof Array);
	}
	function is_jquery(a) {
		return (a instanceof jQuery);
	}
	function is_object(a) {
		return ((a instanceof Object || typeof a == 'object') && !is_null(a) && !is_jquery(a) && !is_array(a) && !is_function(a));
	}
	function is_number(a) {
		return ((a instanceof Number || typeof a == 'number') && !isNaN(a));
	}
	function is_string(a) {
		return ((a instanceof String || typeof a == 'string') && !is_undefined(a) && !is_true(a) && !is_false(a));
	}
	function is_function(a) {
		return (a instanceof Function || typeof a == 'function');
	}
	function is_boolean(a) {
		return (a instanceof Boolean || typeof a == 'boolean' || is_true(a) || is_false(a));
	}
	function is_true(a) {
		return (a === true || a === 'true');
	}
	function is_false(a) {
		return (a === false || a === 'false');
	}
	function is_percentage(x) {
		return (is_string(x) && x.slice(-1) == '%');
	}


	function getTime() {
		return new Date().getTime();
	}

	function deprecated( o, n ) {
		debug(true, o+' is DEPRECATED, support for it will be removed. Use '+n+' instead.');
	}
	function debug(d, m) {
		if (!is_undefined(window.console) && !is_undefined(window.console.log))
		{
			if (is_object(d))
			{
				var s = ' ('+d.selector+')';
				d = d.debug;
			}
			else
			{
				var s = '';
			}
			if (!d)
			{
				return false;
			}

			if (is_string(m))
			{
				m = 'carouFredSel'+s+': ' + m;
			}
			else
			{
				m = ['carouFredSel'+s+':', m];
			}
			window.console.log(m);
		}
		return false;
	}



	//	EASING FUNCTIONS
	$.extend($.easing, {
		'quadratic': function(t) {
			var t2 = t * t;
			return t * (-t2 * t + 4 * t2 - 6 * t + 4);
		},
		'cubic': function(t) {
			return t * (4 * t * t - 9 * t + 6);
		},
		'elastic': function(t) {
			var t2 = t * t;
			return t * (33 * t2 * t2 - 106 * t2 * t + 126 * t2 - 67 * t + 15);
		}
	});


})(jQuery);;(function ($) {
	$.fn.countTo = function (options) {
		options = options || {};

		return $(this).each(function () {
			// set options for current element
			var settings = $.extend({}, $.fn.countTo.defaults, {
				from:            $(this).data('from'),
				to:              $(this).data('to'),
				speed:           $(this).data('speed'),
				refreshInterval: $(this).data('refresh-interval'),
				decimals:        $(this).data('decimals')
			}, options);

			// how many times to update the value, and how much to increment the value on each update
			var loops = Math.ceil(settings.speed / settings.refreshInterval),
				increment = (settings.to - settings.from) / loops;

			// references & variables that will change with each update
			var self = this,
				$self = $(this),
				loopCount = 0,
				value = settings.from,
				data = $self.data('countTo') || {};

			$self.data('countTo', data);

			// if an existing interval can be found, clear it first
			if (data.interval) {
				clearInterval(data.interval);
			}
			data.interval = setInterval(updateTimer, settings.refreshInterval);

			// initialize the element with the starting value
			render(value);

			function updateTimer() {
				value += increment;
				loopCount++;

				render(value);

				if (typeof(settings.onUpdate) == 'function') {
					settings.onUpdate.call(self, value);
				}

				if (loopCount >= loops) {
					// remove the interval
					$self.removeData('countTo');
					clearInterval(data.interval);
					value = settings.to;

					if (typeof(settings.onComplete) == 'function') {
						settings.onComplete.call(self, value);
					}
				}
			}

			function render(value) {
				var formattedValue = settings.formatter.call(self, value, settings);
				$self.text(formattedValue);
			}
		});
	};

	$.fn.countTo.defaults = {
		from: 0,               // the number the element should start at
		to: 0,                 // the number the element should end at
		speed: 1000,           // how long it should take to count between the target numbers
		refreshInterval: 100,  // how often the element should be updated
		decimals: 0,           // the number of decimal places to show
		formatter: formatter,  // handler for formatting the value before rendering
		onUpdate: null,        // callback method for every time the element is updated
		onComplete: null       // callback method for when the element finishes updating
	};

	function formatter(value, settings) {
		return value.toFixed(settings.decimals);
	}
}(jQuery));;/*!
 * jQuery Countdown plugin v1.0
 * http://www.littlewebthings.com/projects/countdown/
 *
 * Copyright 2010, Vassilis Dourdounis
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
(function($){


	$.fn.countDown = function (options) {

		config = {};

		$.extend(config, options);

		diffSecs = this.setCountDown(config);

		if (config.onComplete)
		{
			$.data($(this)[0], 'callback', config.onComplete);
		}
		if (config.omitWeeks)
		{
			$.data($(this)[0], 'omitWeeks', config.omitWeeks);
		}

		$('#' + $(this).attr('id') + ' .fusion-digit').html('<div class="top"></div><div class="bottom"></div>');
		$(this).doCountDown($(this).attr('id'), diffSecs, 500);


		return this;

	};

	$.fn.stopCountDown = function () {
		clearTimeout($.data(this[0], 'timer'));
	};

	$.fn.startCountDown = function () {
		this.doCountDown($(this).attr('id'),$.data(this[0], 'diffSecs'), 500);
	};

	$.fn.setCountDown = function (options) {
		var targetTime = new Date();

		if (options.targetDate)
		{
			targetTime = new Date(options.targetDate.month + '/' + options.targetDate.day + '/' + options.targetDate.year + ' ' + options.targetDate.hour + ':' + options.targetDate.min + ':' + options.targetDate.sec + (options.targetDate.utc ? ' UTC' : ''));
		}
		else if (options.targetOffset)
		{
			targetTime.setFullYear(options.targetOffset.year + targetTime.getFullYear());
			targetTime.setMonth(options.targetOffset.month + targetTime.getMonth());
			targetTime.setDate(options.targetOffset.day + targetTime.getDate());
			targetTime.setHours(options.targetOffset.hour + targetTime.getHours());
			targetTime.setMinutes(options.targetOffset.min + targetTime.getMinutes());
			targetTime.setSeconds(options.targetOffset.sec + targetTime.getSeconds());
		}

		var nowTime = new Date();

		// ThemeFusion edit for Avada theme:
		// Calculate start time according to site time offset
		if ( options.gmtOffset ) {
			var site_offset = options.gmtOffset*60*60000,
				user_offset = nowTime.getTimezoneOffset()*60000;
			nowTime = new Date( nowTime.getTime() + site_offset + user_offset );

		}

		diffSecs = Math.floor((targetTime.valueOf()-nowTime.valueOf())/1000);

		$.data(this[0], 'diffSecs', diffSecs);

		return diffSecs;
	};

	$.fn.doCountDown = function (id, diffSecs, duration) {

		$this = $('#' + id);

		if (diffSecs <= 0)
		{
			diffSecs = 0;
			if ( $this.data( 'timer' ) )
			{
				clearTimeout( $this.data( 'timer' ) );
			}
		}

		secs = diffSecs % 60;
		mins = Math.floor(diffSecs/60)%60;
		hours = Math.floor(diffSecs/60/60)%24;

		if ($this.data( 'omitWeeks' ) == true )
		{
			days = Math.floor(diffSecs/60/60/24);
			weeks = Math.floor(diffSecs/60/60/24/7);
		}
		else
		{
			days = Math.floor(diffSecs/60/60/24)%7;
			weeks = Math.floor(diffSecs/60/60/24/7);
		}

		if ( days > 99 ) {
			$this.find( '.fusion-dash-days' ).find( '.fusion-first-digit' ).css( 'display', 'inline-block' );
		}

		$this.dashChangeTo(id, 'fusion-dash-seconds', secs, duration ? duration : 800);
		$this.dashChangeTo(id, 'fusion-dash-minutes', mins, duration ? duration : 1200);
		$this.dashChangeTo(id, 'fusion-dash-hours', hours, duration ? duration : 1200);
		$this.dashChangeTo(id, 'fusion-dash-days', days, duration ? duration : 1200);
		$this.dashChangeTo(id, 'fusion-dash-weeks', weeks, duration ? duration : 1200);

		$.data($this[0], 'diffSecs', diffSecs);
		if (diffSecs > 0)
		{
			e = $this;
			t = setTimeout(function() { e.doCountDown(id, diffSecs-1) } , 1000);
			$.data(e[0], 'timer', t);
		}
		else if (cb = $.data($this[0], 'callback'))
		{
			$.data($this[0], 'callback')();
		}

	};

	$.fn.dashChangeTo = function(id, dash, n, duration) {
		  $this = $('#' + id);

		  for (var i=($this.find('.' + dash + ' .fusion-digit').length-1); i>=0; i--)
		  {
				var d = n%10;
				n = (n - d) / 10;
				$this.digitChangeTo('#' + $this.attr('id') + ' .' + dash + ' .fusion-digit:eq('+i+')', d, duration);
		  }
	};

	$.fn.digitChangeTo = function (digit, n, duration) {

		var top_digit = $(digit + ' div.top'),
			bottom_digit = $(digit + ' div.bottom');

		if (!duration)
		{
			duration = 800;
		}

		if (top_digit.html() != n + '' && top_digit.not(':animated').length)
		{
			top_digit.css({'display': 'none'});
			top_digit.html((n ? n : '0')).fadeOut(duration, function()
			{
				bottom_digit.html(top_digit.html());
				bottom_digit.css({'display': 'block', 'height': 'auto'});
				top_digit.css({'display': 'none'});
			});

		}
	};

})(jQuery);

;/*!
 * jQuery Cycle Plugin (with Transition Definitions)
 * Examples and documentation at: http://jquery.malsup.com/cycle/
 * Copyright (c) 2007-2013 M. Alsup
 * Version: 3.0.3 (11-JUL-2013)
 * Dual licensed under the MIT and GPL licenses.
 * http://jquery.malsup.com/license.html
 * Requires: jQuery v1.7.1 or later
 */
;(function($, undefined) {
"use strict";

var ver = '3.0.3';

function debug(s) {
	if ($.fn.cycle.debug)
		log(s);
}
function log() {
	/*global console */
	if (window.console && console.log) {
		//console.log('[cycle] ' + Array.prototype.join.call(arguments,' '));
	}
}
$.expr[':'].paused = function(el) {
	return el.cyclePause;
};


// the options arg can be...
//   a number  - indicates an immediate transition should occur to the given slide index
//   a string  - 'pause', 'resume', 'toggle', 'next', 'prev', 'stop', 'destroy' or the name of a transition effect (ie, 'fade', 'zoom', etc)
//   an object - properties to control the slideshow
//
// the arg2 arg can be...
//   the name of an fx (only used in conjunction with a numeric value for 'options')
//   the value true (only used in first arg == 'resume') and indicates
//	 that the resume should occur immediately (not wait for next timeout)

$.fn.cycle = function(options, arg2) {
	var o = { s: this.selector, c: this.context };

	// in 1.3+ we can fix mistakes with the ready state
	if (this.length === 0 && options != 'stop') {
		if (!$.isReady && o.s) {
			log('DOM not ready, queuing slideshow');
			$(function() {
				$(o.s,o.c).cycle(options,arg2);
			});
			return this;
		}
		// is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
		log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
		return this;
	}

	// iterate the matched nodeset
	return this.each(function() {
		var opts = handleArguments(this, options, arg2);
		if (opts === false)
			return;

		opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink;

		// stop existing slideshow for this container (if there is one)
		if (this.cycleTimeout)
			clearTimeout(this.cycleTimeout);
		this.cycleTimeout = this.cyclePause = 0;
		this.cycleStop = 0; // issue #108

		var $cont = $(this);
		var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children();
		var els = $slides.get();

		if (els.length < 2) {
			log('terminating; too few slides: ' + els.length);
			return;
		}

		var opts2 = buildOptions($cont, $slides, els, opts, o);
		if (opts2 === false)
			return;

		var startTime = opts2.continuous ? 10 : getTimeout(els[opts2.currSlide], els[opts2.nextSlide], opts2, !opts2.backwards);

		// if it's an auto slideshow, kick it off
		if (startTime) {
			startTime += (opts2.delay || 0);
			if (startTime < 10)
				startTime = 10;
			debug('first timeout: ' + startTime);
			this.cycleTimeout = setTimeout(function(){go(els,opts2,0,!opts.backwards);}, startTime);
		}
	});
};

function triggerPause(cont, byHover, onPager) {
	var opts = $(cont).data('cycle.opts');
	if (!opts)
		return;
	var paused = !!cont.cyclePause;
	if (paused && opts.paused)
		opts.paused(cont, opts, byHover, onPager);
	else if (!paused && opts.resumed)
		opts.resumed(cont, opts, byHover, onPager);
}

// process the args that were passed to the plugin fn
function handleArguments(cont, options, arg2) {
	if (cont.cycleStop === undefined)
		cont.cycleStop = 0;
	if (options === undefined || options === null)
		options = {};
	if (options.constructor == String) {
		switch(options) {
		case 'destroy':
		case 'stop':
			var opts = $(cont).data('cycle.opts');
			if (!opts)
				return false;
			cont.cycleStop++; // callbacks look for change
			if (cont.cycleTimeout)
				clearTimeout(cont.cycleTimeout);
			cont.cycleTimeout = 0;
			if (opts.elements)
				$(opts.elements).stop();
			$(cont).removeData('cycle.opts');
			if (options == 'destroy')
				destroy(cont, opts);
			return false;
		case 'toggle':
			cont.cyclePause = (cont.cyclePause === 1) ? 0 : 1;
			checkInstantResume(cont.cyclePause, arg2, cont);
			triggerPause(cont);
			return false;
		case 'pause':
			cont.cyclePause = 1;
			triggerPause(cont);
			return false;
		case 'resume':
			cont.cyclePause = 0;
			checkInstantResume(false, arg2, cont);
			triggerPause(cont);
			return false;
		case 'prev':
		case 'next':
			opts = $(cont).data('cycle.opts');
			if (!opts) {
				log('options not found, "prev/next" ignored');
				return false;
			}
			if (typeof arg2 == 'string')
				opts.oneTimeFx = arg2;
			$.fn.cycle[options](opts);
			return false;
		default:
			options = { fx: options };
		}
		return options;
	}
	else if (options.constructor == Number) {
		// go to the requested slide
		var num = options;
		options = $(cont).data('cycle.opts');
		if (!options) {
			log('options not found, can not advance slide');
			return false;
		}
		if (num < 0 || num >= options.elements.length) {
			log('invalid slide index: ' + num);
			return false;
		}
		options.nextSlide = num;
		if (cont.cycleTimeout) {
			clearTimeout(cont.cycleTimeout);
			cont.cycleTimeout = 0;
		}
		if (typeof arg2 == 'string')
			options.oneTimeFx = arg2;
		go(options.elements, options, 1, num >= options.currSlide);
		return false;
	}
	return options;

	function checkInstantResume(isPaused, arg2, cont) {
		if (!isPaused && arg2 === true) { // resume now!
			var options = $(cont).data('cycle.opts');
			if (!options) {
				log('options not found, can not resume');
				return false;
			}
			if (cont.cycleTimeout) {
				clearTimeout(cont.cycleTimeout);
				cont.cycleTimeout = 0;
			}
			go(options.elements, options, 1, !options.backwards);
		}
	}
}

function removeFilter(el, opts) {
	if (!$.support.opacity && opts.cleartype && el.style.filter) {
		try { el.style.removeAttribute('filter'); }
		catch(smother) {} // handle old opera versions
	}
}

// unbind event handlers
function destroy(cont, opts) {
	if (opts.next)
		$(opts.next).unbind(opts.prevNextEvent);
	if (opts.prev)
		$(opts.prev).unbind(opts.prevNextEvent);

	if (opts.pager || opts.pagerAnchorBuilder)
		$.each(opts.pagerAnchors || [], function() {
			this.unbind().remove();
		});
	opts.pagerAnchors = null;
	$(cont).unbind('mouseenter.cycle mouseleave.cycle');
	if (opts.destroy) // callback
		opts.destroy(opts);
}

// one-time initialization
function buildOptions($cont, $slides, els, options, o) {
	var startingSlideSpecified;
	// support metadata plugin (v1.0 and v2.0)
	var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {});
	var meta = $.isFunction($cont.data) ? $cont.data(opts.metaAttr) : null;
	if (meta)
		opts = $.extend(opts, meta);
	if (opts.autostop)
		opts.countdown = opts.autostopCount || els.length;

	var cont = $cont[0];
	$cont.data('cycle.opts', opts);
	opts.$cont = $cont;
	opts.stopCount = cont.cycleStop;
	opts.elements = els;
	opts.before = opts.before ? [opts.before] : [];
	opts.after = opts.after ? [opts.after] : [];

	// push some after callbacks
	if (!$.support.opacity && opts.cleartype)
		opts.after.push(function() { removeFilter(this, opts); });
	if (opts.continuous)
		opts.after.push(function() { go(els,opts,0,!opts.backwards); });

	saveOriginalOpts(opts);

	// clearType corrections
	if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
		clearTypeFix($slides);

	// container requires non-static position so that slides can be position within
	if ($cont.css('position') == 'static')
		$cont.css('position', 'relative');
	if (opts.width)
		$cont.width(opts.width);
	if (opts.height && opts.height != 'auto')
		$cont.height(opts.height);

	if (opts.startingSlide !== undefined) {
		opts.startingSlide = parseInt(opts.startingSlide,10);
		if (opts.startingSlide >= els.length || opts.startSlide < 0) {
			opts.startingSlide = 0; // catch bogus input
		} else {
			startingSlideSpecified = true;
		}
	} else if (opts.backwards) {
		opts.startingSlide = els.length - 1;
	} else {
		opts.startingSlide = 0;
	}

	// if random, mix up the slide array
	if (opts.random) {
		opts.randomMap = [];
		for (var i = 0; i < els.length; i++)
			opts.randomMap.push(i);
		opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
		if (startingSlideSpecified) {
			// try to find the specified starting slide and if found set start slide index in the map accordingly
			for ( var cnt = 0; cnt < els.length; cnt++ ) {
				if ( opts.startingSlide == opts.randomMap[cnt] ) {
					opts.randomIndex = cnt;
				}
			}
		}
		else {
			opts.randomIndex = 1;
			opts.startingSlide = opts.randomMap[1];
		}
	}
	else if (opts.startingSlide >= els.length)
		opts.startingSlide = 0; // catch bogus input
	opts.currSlide = opts.startingSlide || 0;
	var first = opts.startingSlide;

	// set position and zIndex on all the slides
	$slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) {
		var z;
		if (opts.backwards) {
			z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i;
		} else {
			z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i;
		}
		$(this).css('z-index', z);
	});

	// make sure first slide is visible
	$(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case
	removeFilter(els[first], opts);

	// stretch slides
	if (opts.fit) {
		if (!opts.aspect) {
	        if (opts.width)
	            $slides.width(opts.width);
	        if (opts.height && opts.height != 'auto')
	            $slides.height(opts.height);
		} else {
			$slides.each(function(){
				var $slide = $(this);
				var ratio = (opts.aspect === true) ? $slide.width()/$slide.height() : opts.aspect;
				if( opts.width && $slide.width() != opts.width ) {
					$slide.width( opts.width );
					$slide.height( opts.width / ratio );
				}

				if( opts.height && $slide.height() < opts.height ) {
					$slide.height( opts.height );
					$slide.width( opts.height * ratio );
				}
			});
		}
	}

	if (opts.center && ((!opts.fit) || opts.aspect)) {
		$slides.each(function(){
			var $slide = $(this);
			$slide.css({
				"margin-left": opts.width ?
					((opts.width - $slide.width()) / 2) + "px" :
					0,
				"margin-top": opts.height ?
					((opts.height - $slide.height()) / 2) + "px" :
					0
			});
		});
	}

	if (opts.center && !opts.fit && !opts.slideResize) {
		$slides.each(function(){
			var $slide = $(this);
			$slide.css({
				"margin-left": opts.width ? ((opts.width - $slide.width()) / 2) + "px" : 0,
				"margin-top": opts.height ? ((opts.height - $slide.height()) / 2) + "px" : 0
			});
		});
	}

	// stretch container
	var reshape = (opts.containerResize || opts.containerResizeHeight) && $cont.innerHeight() < 1;
	if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9
		var maxw = 0, maxh = 0;
		for(var j=0; j < els.length; j++) {
			var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight();
			if (!w) w = e.offsetWidth || e.width || $e.attr('width');
			if (!h) h = e.offsetHeight || e.height || $e.attr('height');
			maxw = w > maxw ? w : maxw;
			maxh = h > maxh ? h : maxh;
		}
		if (opts.containerResize && maxw > 0 && maxh > 0)
			//$cont.css({width:maxw+'px',height:maxh+'px'});
			$cont.animate({width:maxw+'px',height:maxh+'px'});
		if (opts.containerResizeHeight && maxh > 0)
			//$cont.css({height:maxh+'px'});
			$cont.animate({height:maxh+'px'});
	}

	var pauseFlag = false;  // https://github.com/malsup/cycle/issues/44
	if (opts.pause)
		$cont.bind('mouseenter.cycle', function(){
			pauseFlag = true;
			this.cyclePause++;
			triggerPause(cont, true);
		}).bind('mouseleave.cycle', function(){
				if (pauseFlag)
					this.cyclePause--;
				triggerPause(cont, true);
		});

	if (supportMultiTransitions(opts) === false)
		return false;

	// apparently a lot of people use image slideshows without height/width attributes on the images.
	// Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that.
	var requeue = false;
	options.requeueAttempts = options.requeueAttempts || 0;
	$slides.each(function() {
		// try to get height/width of each slide
		var $el = $(this);
		this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0);
		this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0);

		if ( $el.is('img') ) {
			var loading = (this.cycleH === 0 && this.cycleW === 0 && !this.complete);
			// don't requeue for images that are still loading but have a valid size
			if (loading) {
				if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever
					log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH);
					setTimeout(function() {$(o.s,o.c).cycle(options);}, opts.requeueTimeout);
					requeue = true;
					return false; // break each loop
				}
				else {
					log('could not determine size of image: '+this.src, this.cycleW, this.cycleH);
				}
			}
		}
		return true;
	});

	if (requeue)
		return false;

	opts.cssBefore = opts.cssBefore || {};
	opts.cssAfter = opts.cssAfter || {};
	opts.cssFirst = opts.cssFirst || {};
	opts.animIn = opts.animIn || {};
	opts.animOut = opts.animOut || {};

	$slides.not(':eq('+first+')').css(opts.cssBefore);
	$($slides[first]).css(opts.cssFirst);

	if (opts.timeout) {
		opts.timeout = parseInt(opts.timeout,10);
		// ensure that timeout and speed settings are sane
		if (opts.speed.constructor == String)
			opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10);
		if (!opts.sync)
			opts.speed = opts.speed / 2;

		var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250;
		while((opts.timeout - opts.speed) < buffer) // sanitize timeout
			opts.timeout += opts.speed;
	}
	if (opts.easing)
		opts.easeIn = opts.easeOut = opts.easing;
	if (!opts.speedIn)
		opts.speedIn = opts.speed;
	if (!opts.speedOut)
		opts.speedOut = opts.speed;

	opts.slideCount = els.length;
	opts.currSlide = opts.lastSlide = first;
	if (opts.random) {
		if (++opts.randomIndex == els.length)
			opts.randomIndex = 0;
		opts.nextSlide = opts.randomMap[opts.randomIndex];
	}
	else if (opts.backwards) {
		opts.nextSlide = opts.startingSlide === 0 ? (els.length-1) : opts.startingSlide-1;
	} else {
		opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1;
}

	// run transition init fn
	if (!opts.multiFx) {
		var init = $.fn.cycle.transitions[opts.fx];
		if ($.isFunction(init))
			init($cont, $slides, opts);
		else if (opts.fx != 'custom' && !opts.multiFx) {
			log('unknown transition: ' + opts.fx,'; slideshow terminating');
			return false;
		}
	}

	// fire artificial events
	var e0 = $slides[first];
	if (!opts.skipInitializationCallbacks) {
		if (opts.before.length)
			opts.before[0].apply(e0, [e0, e0, opts, true]);
		if (opts.after.length)
			opts.after[0].apply(e0, [e0, e0, opts, true]);
	}
	if (opts.next)
		$(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,1);});
	if (opts.prev)
		$(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,0);});
	if (opts.pager || opts.pagerAnchorBuilder)
		buildPager(els,opts);

	exposeAddSlide(opts, els);

	return opts;
}

// save off original opts so we can restore after clearing state
function saveOriginalOpts(opts) {
	opts.original = { before: [], after: [] };
	opts.original.cssBefore = $.extend({}, opts.cssBefore);
	opts.original.cssAfter  = $.extend({}, opts.cssAfter);
	opts.original.animIn	= $.extend({}, opts.animIn);
	opts.original.animOut   = $.extend({}, opts.animOut);
	$.each(opts.before, function() { opts.original.before.push(this); });
	$.each(opts.after,  function() { opts.original.after.push(this); });
}

function supportMultiTransitions(opts) {
	var i, tx, txs = $.fn.cycle.transitions;
	// look for multiple effects
	if (opts.fx.indexOf(',') > 0) {
		opts.multiFx = true;
		opts.fxs = opts.fx.replace(/\s*/g,'').split(',');
		// discard any bogus effect names
		for (i=0; i < opts.fxs.length; i++) {
			var fx = opts.fxs[i];
			tx = txs[fx];
			if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) {
				log('discarding unknown transition: ',fx);
				opts.fxs.splice(i,1);
				i--;
			}
		}
		// if we have an empty list then we threw everything away!
		if (!opts.fxs.length) {
			log('No valid transitions named; slideshow terminating.');
			return false;
		}
	}
	else if (opts.fx == 'all') {  // auto-gen the list of transitions
		opts.multiFx = true;
		opts.fxs = [];
		for (var p in txs) {
			if (txs.hasOwnProperty(p)) {
				tx = txs[p];
				if (txs.hasOwnProperty(p) && $.isFunction(tx))
					opts.fxs.push(p);
			}
		}
	}
	if (opts.multiFx && opts.randomizeEffects) {
		// munge the fxs array to make effect selection random
		var r1 = Math.floor(Math.random() * 20) + 30;
		for (i = 0; i < r1; i++) {
			var r2 = Math.floor(Math.random() * opts.fxs.length);
			opts.fxs.push(opts.fxs.splice(r2,1)[0]);
		}
		debug('randomized fx sequence: ',opts.fxs);
	}
	return true;
}

// provide a mechanism for adding slides after the slideshow has started
function exposeAddSlide(opts, els) {
	opts.addSlide = function(newSlide, prepend) {
		var $s = $(newSlide), s = $s[0];
		if (!opts.autostopCount)
			opts.countdown++;
		els[prepend?'unshift':'push'](s);
		if (opts.els)
			opts.els[prepend?'unshift':'push'](s); // shuffle needs this
		opts.slideCount = els.length;

		// add the slide to the random map and resort
		if (opts.random) {
			opts.randomMap.push(opts.slideCount-1);
			opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
		}

		$s.css('position','absolute');
		$s[prepend?'prependTo':'appendTo'](opts.$cont);

		if (prepend) {
			opts.currSlide++;
			opts.nextSlide++;
		}

		if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
			clearTypeFix($s);

		if (opts.fit && opts.width)
			$s.width(opts.width);
		if (opts.fit && opts.height && opts.height != 'auto')
			$s.height(opts.height);
		s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height();
		s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width();

		$s.css(opts.cssBefore);

		if (opts.pager || opts.pagerAnchorBuilder)
			$.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts);

		if ($.isFunction(opts.onAddSlide))
			opts.onAddSlide($s);
		else
			$s.hide(); // default behavior
	};
}

// reset internal state; we do this on every pass in order to support multiple effects
$.fn.cycle.resetState = function(opts, fx) {
	fx = fx || opts.fx;
	opts.before = []; opts.after = [];
	opts.cssBefore = $.extend({}, opts.original.cssBefore);
	opts.cssAfter  = $.extend({}, opts.original.cssAfter);
	opts.animIn	= $.extend({}, opts.original.animIn);
	opts.animOut   = $.extend({}, opts.original.animOut);
	opts.fxFn = null;
	$.each(opts.original.before, function() { opts.before.push(this); });
	$.each(opts.original.after,  function() { opts.after.push(this); });

	// re-init
	var init = $.fn.cycle.transitions[fx];
	if ($.isFunction(init))
		init(opts.$cont, $(opts.elements), opts);
};

// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt
function go(els, opts, manual, fwd) {
	var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide];

	// opts.busy is true if we're in the middle of an animation
	if (manual && opts.busy && opts.manualTrump) {
		// let manual transitions requests trump active ones
		debug('manualTrump in go(), stopping active transition');
		$(els).stop(true,true);
		opts.busy = 0;
		clearTimeout(p.cycleTimeout);
	}

	// don't begin another timeout-based transition if there is one active
	if (opts.busy) {
		debug('transition active, ignoring new tx request');
		return;
	}


	// stop cycling if we have an outstanding stop request
	if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual)
		return;

	// check to see if we should stop cycling based on autostop options
	if (!manual && !p.cyclePause && !opts.bounce &&
		((opts.autostop && (--opts.countdown <= 0)) ||
		(opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) {
		if (opts.end)
			opts.end(opts);
		return;
	}

	// if slideshow is paused, only transition on a manual trigger
	var changed = false;
	if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) {
		changed = true;
		var fx = opts.fx;
		// keep trying to get the slide size if we don't have it yet
		curr.cycleH = curr.cycleH || $(curr).height();
		curr.cycleW = curr.cycleW || $(curr).width();
		next.cycleH = next.cycleH || $(next).height();
		next.cycleW = next.cycleW || $(next).width();

		// support multiple transition types
		if (opts.multiFx) {
			if (fwd && (opts.lastFx === undefined || ++opts.lastFx >= opts.fxs.length))
				opts.lastFx = 0;
			else if (!fwd && (opts.lastFx === undefined || --opts.lastFx < 0))
				opts.lastFx = opts.fxs.length - 1;
			fx = opts.fxs[opts.lastFx];
		}

		// one-time fx overrides apply to:  $('div').cycle(3,'zoom');
		if (opts.oneTimeFx) {
			fx = opts.oneTimeFx;
			opts.oneTimeFx = null;
		}

		$.fn.cycle.resetState(opts, fx);

		// run the before callbacks
		if (opts.before.length)
			$.each(opts.before, function(i,o) {
				if (p.cycleStop != opts.stopCount) return;
				o.apply(next, [curr, next, opts, fwd]);
			});

		// stage the after callacks
		var after = function() {
			opts.busy = 0;
			$.each(opts.after, function(i,o) {
				if (p.cycleStop != opts.stopCount) return;
				o.apply(next, [curr, next, opts, fwd]);
			});
			if (!p.cycleStop) {
				// queue next transition
				queueNext();
			}
		};

		debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide);

		// get ready to perform the transition
		opts.busy = 1;
		if (opts.fxFn) { // fx function provided?
			opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
		} else if ($.isFunction($.fn.cycle[opts.fx])) { // fx plugin ?
			$.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent);
		} else {
			$.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
	}
	}
	else {
		queueNext();
	}

	if (changed || opts.nextSlide == opts.currSlide) {
		// calculate the next slide
		var roll;
		opts.lastSlide = opts.currSlide;
		if (opts.random) {
			opts.currSlide = opts.nextSlide;
			if (++opts.randomIndex == els.length) {
				opts.randomIndex = 0;
				opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
			}
			opts.nextSlide = opts.randomMap[opts.randomIndex];
			if (opts.nextSlide == opts.currSlide)
				opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1;
		}
		else if (opts.backwards) {
			roll = (opts.nextSlide - 1) < 0;
			if (roll && opts.bounce) {
				opts.backwards = !opts.backwards;
				opts.nextSlide = 1;
				opts.currSlide = 0;
			}
			else {
				opts.nextSlide = roll ? (els.length-1) : opts.nextSlide-1;
				opts.currSlide = roll ? 0 : opts.nextSlide+1;
			}
		}
		else { // sequence
			roll = (opts.nextSlide + 1) == els.length;
			if (roll && opts.bounce) {
				opts.backwards = !opts.backwards;
				opts.nextSlide = els.length-2;
				opts.currSlide = els.length-1;
			}
			else {
				opts.nextSlide = roll ? 0 : opts.nextSlide+1;
				opts.currSlide = roll ? els.length-1 : opts.nextSlide-1;
			}
		}
	}
	if (changed && opts.pager)
		opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass);

	function queueNext() {
		// stage the next transition
		var ms = 0, timeout = opts.timeout;
		if (opts.timeout && !opts.continuous) {
			ms = getTimeout(els[opts.currSlide], els[opts.nextSlide], opts, fwd);
         if (opts.fx == 'shuffle')
            ms -= opts.speedOut;
      }
		else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic
			ms = 10;
		if (ms > 0)
			p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.backwards); }, ms);
	}
}

// invoked after transition
$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) {
   $(pager).each(function() {
       $(this).children().removeClass(clsName).eq(currSlide).addClass(clsName);
   });
};

// calculate timeout value for current transition
function getTimeout(curr, next, opts, fwd) {
	if (opts.timeoutFn) {
		// call user provided calc fn
		var t = opts.timeoutFn.call(curr,curr,next,opts,fwd);
		while (opts.fx != 'none' && (t - opts.speed) < 250) // sanitize timeout
			t += opts.speed;
		debug('calculated timeout: ' + t + '; speed: ' + opts.speed);
		if (t !== false)
			return t;
	}
	return opts.timeout;
}

// expose next/prev function, caller must pass in state
$.fn.cycle.next = function(opts) { advance(opts,1); };
$.fn.cycle.prev = function(opts) { advance(opts,0);};

// advance slide forward or back
function advance(opts, moveForward) {
	var val = moveForward ? 1 : -1;
	var els = opts.elements;
	var p = opts.$cont[0], timeout = p.cycleTimeout;
	if (timeout) {
		clearTimeout(timeout);
		p.cycleTimeout = 0;
	}
	if (opts.random && val < 0) {
		// move back to the previously display slide
		opts.randomIndex--;
		if (--opts.randomIndex == -2)
			opts.randomIndex = els.length-2;
		else if (opts.randomIndex == -1)
			opts.randomIndex = els.length-1;
		opts.nextSlide = opts.randomMap[opts.randomIndex];
	}
	else if (opts.random) {
		opts.nextSlide = opts.randomMap[opts.randomIndex];
	}
	else {
		opts.nextSlide = opts.currSlide + val;
		if (opts.nextSlide < 0) {
			if (opts.nowrap) return false;
			opts.nextSlide = els.length - 1;
		}
		else if (opts.nextSlide >= els.length) {
			if (opts.nowrap) return false;
			opts.nextSlide = 0;
		}
	}

	var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated
	if ($.isFunction(cb))
		cb(val > 0, opts.nextSlide, els[opts.nextSlide]);
	go(els, opts, 1, moveForward);
	return false;
}

function buildPager(els, opts) {
	var $p = $(opts.pager);
	$.each(els, function(i,o) {
		$.fn.cycle.createPagerAnchor(i,o,$p,els,opts);
	});
	opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass);
}

$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
	var a;
	if ($.isFunction(opts.pagerAnchorBuilder)) {
		a = opts.pagerAnchorBuilder(i,el);
		debug('pagerAnchorBuilder('+i+', el) returned: ' + a);
	}
	else {
		a = '<a href="#"></a>';
}

	if (!a)
		return;
	var $a = $(a);
	// don't reparent if anchor is in the dom
	if ($a.parents('body').length === 0) {
		var arr = [];
		if ($p.length > 1) {
			$p.each(function() {
				var $clone = $a.clone(true);
				$(this).append($clone);
				arr.push($clone[0]);
			});
			$a = $(arr);
		}
		else {
			$a.appendTo($p);
		}
	}

	opts.pagerAnchors =  opts.pagerAnchors || [];
	opts.pagerAnchors.push($a);

	var pagerFn = function(e) {
		e.preventDefault();
		opts.nextSlide = i;
		var p = opts.$cont[0], timeout = p.cycleTimeout;
		if (timeout) {
			clearTimeout(timeout);
			p.cycleTimeout = 0;
		}
		var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated
		if ($.isFunction(cb))
			cb(opts.nextSlide, els[opts.nextSlide]);
		go(els,opts,1,opts.currSlide < i); // trigger the trans
//		return false; // <== allow bubble
	};

	if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) {
		$a.hover(pagerFn, function(){/* no-op */} );
	}
	else {
		$a.bind(opts.pagerEvent, pagerFn);
	}

	if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble)
		$a.bind('click.cycle', function(){return false;}); // suppress click

	var cont = opts.$cont[0];
	var pauseFlag = false; // https://github.com/malsup/cycle/issues/44
	if (opts.pauseOnPagerHover) {
		$a.hover(
			function() {
				pauseFlag = true;
				cont.cyclePause++;
				triggerPause(cont,true,true);
			}, function() {
				if (pauseFlag)
					cont.cyclePause--;
				triggerPause(cont,true,true);
			}
		);
	}
};

// helper fn to calculate the number of slides between the current and the next
$.fn.cycle.hopsFromLast = function(opts, fwd) {
	var hops, l = opts.lastSlide, c = opts.currSlide;
	if (fwd)
		hops = c > l ? c - l : opts.slideCount - l;
	else
		hops = c < l ? l - c : l + opts.slideCount - c;
	return hops;
};

// fix clearType problems in ie6 by setting an explicit bg color
// (otherwise text slides look horrible during a fade transition)
function clearTypeFix($slides) {
	debug('applying clearType background-color hack');
	function hex(s) {
		s = parseInt(s,10).toString(16);
		return s.length < 2 ? '0'+s : s;
	}
	function getBg(e) {
		for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) {
			var v = $.css(e,'background-color');
			if (v && v.indexOf('rgb') >= 0 ) {
				var rgb = v.match(/\d+/g);
				return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
			}
			if (v && v != 'transparent')
				return v;
		}
		return '#ffffff';
	}
	$slides.each(function() { $(this).css('background-color', getBg(this)); });
}

// reset common props before the next transition
$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) {
	$(opts.elements).not(curr).hide();
	if (typeof opts.cssBefore.opacity == 'undefined')
		opts.cssBefore.opacity = 1;
	opts.cssBefore.display = 'block';
	if (opts.slideResize && w !== false && next.cycleW > 0)
		opts.cssBefore.width = next.cycleW;
	if (opts.slideResize && h !== false && next.cycleH > 0)
		opts.cssBefore.height = next.cycleH;
	opts.cssAfter = opts.cssAfter || {};
	opts.cssAfter.display = 'none';
	$(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0));
	$(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1));
};

// the actual fn for effecting a transition
$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) {
	var $l = $(curr), $n = $(next);
	var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut, animInDelay = opts.animInDelay, animOutDelay = opts.animOutDelay;
	$n.css(opts.cssBefore);
	if (speedOverride) {
		if (typeof speedOverride == 'number')
			speedIn = speedOut = speedOverride;
		else
			speedIn = speedOut = 1;
		easeIn = easeOut = null;
	}
	var fn = function() {
		$n.delay(animInDelay).animate(opts.animIn, speedIn, easeIn, function() {
			cb();
		});
	};
	$l.delay(animOutDelay).animate(opts.animOut, speedOut, easeOut, function() {
		$l.css(opts.cssAfter);
		if (!opts.sync)
			fn();
	});
	if (opts.sync) fn();
};

// transition definitions - only fade is defined here, transition pack defines the rest
$.fn.cycle.transitions = {
	fade: function($cont, $slides, opts) {
		$slides.not(':eq('+opts.currSlide+')').css('opacity',0);
		opts.before.push(function(curr,next,opts) {
			$.fn.cycle.commonReset(curr,next,opts);
			opts.cssBefore.opacity = 0;
		});
		opts.animIn	   = { opacity: 1 };
		opts.animOut   = { opacity: 0 };
		opts.cssBefore = { top: 0, left: 0 };
	}
};

$.fn.cycle.ver = function() { return ver; };

// override these globally if you like (they are all optional)
$.fn.cycle.defaults = {
    activePagerClass: 'activeSlide', // class name used for the active pager link
    after:            null,     // transition callback (scope set to element that was shown):  function(currSlideElement, nextSlideElement, options, forwardFlag)
    allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling
    animIn:           null,     // properties that define how the slide animates in
    animInDelay:      0,        // allows delay before next slide transitions in
    animOut:          null,     // properties that define how the slide animates out
    animOutDelay:     0,        // allows delay before current slide transitions out
    aspect:           false,    // preserve aspect ratio during fit resizing, cropping if necessary (must be used with fit option)
    autostop:         0,        // true to end slideshow after X transitions (where X == slide count)
    autostopCount:    0,        // number of transitions (optionally used with autostop to define X)
    backwards:        false,    // true to start slideshow at last slide and move backwards through the stack
    before:           null,     // transition callback (scope set to element to be shown):     function(currSlideElement, nextSlideElement, options, forwardFlag)
    center:           null,     // set to true to have cycle add top/left margin to each slide (use with width and height options)
    cleartype:        !$.support.opacity,  // true if clearType corrections should be applied (for IE)
    cleartypeNoBg:    false,    // set to true to disable extra cleartype fixing (leave false to force background color setting on slides)
    containerResize:  1,        // resize container to fit largest slide
    containerResizeHeight:  0,  // resize containers height to fit the largest slide but leave the width dynamic
    continuous:       0,        // true to start next transition immediately after current one completes
    cssAfter:         null,     // properties that defined the state of the slide after transitioning out
    cssBefore:        null,     // properties that define the initial state of the slide before transitioning in
    delay:            0,        // additional delay (in ms) for first transition (hint: can be negative)
    easeIn:           null,     // easing for "in" transition
    easeOut:          null,     // easing for "out" transition
    easing:           null,     // easing method for both in and out transitions
    end:              null,     // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
    fastOnEvent:      0,        // force fast transitions when triggered manually (via pager or prev/next); value == time in ms
    fit:              0,        // force slides to fit container
    fx:               'fade',   // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle')
    fxFn:             null,     // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
    height:           'auto',   // container height (if the 'fit' option is true, the slides will be set to this height as well)
    manualTrump:      true,     // causes manual transition to stop an active transition instead of being ignored
    metaAttr:         'cycle',  // data- attribute that holds the option data for the slideshow
    next:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for next slide
    nowrap:           0,        // true to prevent slideshow from wrapping
    onPagerEvent:     null,     // callback fn for pager events: function(zeroBasedSlideIndex, slideElement)
    onPrevNextEvent:  null,     // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement)
    pager:            null,     // element, jQuery object, or jQuery selector string for the element to use as pager container
    pagerAnchorBuilder: null,   // callback fn for building anchor links:  function(index, DOMelement)
    pagerEvent:       'click.cycle', // name of event which drives the pager navigation
    pause:            0,        // true to enable "pause on hover"
    pauseOnPagerHover: 0,       // true to pause when hovering over pager link
    prev:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for previous slide
    prevNextEvent:    'click.cycle',// event which drives the manual transition to the previous or next slide
    random:           0,        // true for random, false for sequence (not applicable to shuffle fx)
    randomizeEffects: 1,        // valid when multiple effects are used; true to make the effect sequence random
    requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded
    requeueTimeout:   250,      // ms delay for requeue
    rev:              0,        // causes animations to transition in reverse (for effects that support it such as scrollHorz/scrollVert/shuffle)
    shuffle:          null,     // coords for shuffle animation, ex: { top:15, left: 200 }
    skipInitializationCallbacks: false, // set to true to disable the first before/after callback that occurs prior to any transition
    slideExpr:        null,     // expression for selecting slides (if something other than all children is required)
    slideResize:      1,        // force slide width/height to fixed size before every transition
    speed:            1000,     // speed of the transition (any valid fx speed value)
    speedIn:          null,     // speed of the 'in' transition
    speedOut:         null,     // speed of the 'out' transition
    startingSlide:    undefined,// zero-based index of the first slide to be displayed
    sync:             1,        // true if in/out transitions should occur simultaneously
    timeout:          4000,     // milliseconds between slide transitions (0 to disable auto advance)
    timeoutFn:        null,     // callback for determining per-slide timeout value:  function(currSlideElement, nextSlideElement, options, forwardFlag)
    updateActivePagerLink: null,// callback fn invoked to update the active pager link (adds/removes activePagerClass style)
    width:            null      // container width (if the 'fit' option is true, the slides will be set to this width as well)
};

})(jQuery);


/*!
 * jQuery Cycle Plugin Transition Definitions
 * This script is a plugin for the jQuery Cycle Plugin
 * Examples and documentation at: http://malsup.com/jquery/cycle/
 * Copyright (c) 2007-2010 M. Alsup
 * Version:	 2.73
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
(function($) {
"use strict";

//
// These functions define slide initialization and properties for the named
// transitions. To save file size feel free to remove any of these that you
// don't need.
//
$.fn.cycle.transitions.none = function($cont, $slides, opts) {
	opts.fxFn = function(curr,next,opts,after){
		$(next).show();
		$(curr).hide();
		after();
	};
};

// not a cross-fade, fadeout only fades out the top slide
$.fn.cycle.transitions.fadeout = function($cont, $slides, opts) {
	$slides.not(':eq('+opts.currSlide+')').css({ display: 'block', 'opacity': 1 });
	opts.before.push(function(curr,next,opts,w,h,rev) {
		$(curr).css('zIndex',opts.slideCount + (rev !== true ? 1 : 0));
		$(next).css('zIndex',opts.slideCount + (rev !== true ? 0 : 1));
	});
	opts.animIn.opacity = 1;
	opts.animOut.opacity = 0;
	opts.cssBefore.opacity = 1;
	opts.cssBefore.display = 'block';
	opts.cssAfter.zIndex = 0;
};

// scrollUp/Down/Left/Right
$.fn.cycle.transitions.scrollUp = function($cont, $slides, opts) {
	$cont.css('overflow','hidden');
	opts.before.push($.fn.cycle.commonReset);
	var h = $cont.height();
	opts.cssBefore.top = h;
	opts.cssBefore.left = 0;
	opts.cssFirst.top = 0;
	opts.animIn.top = 0;
	opts.animOut.top = -h;
};
$.fn.cycle.transitions.scrollDown = function($cont, $slides, opts) {
	$cont.css('overflow','hidden');
	opts.before.push($.fn.cycle.commonReset);
	var h = $cont.height();
	opts.cssFirst.top = 0;
	opts.cssBefore.top = -h;
	opts.cssBefore.left = 0;
	opts.animIn.top = 0;
	opts.animOut.top = h;
};
$.fn.cycle.transitions.scrollLeft = function($cont, $slides, opts) {
	$cont.css('overflow','hidden');
	opts.before.push($.fn.cycle.commonReset);
	var w = $cont.width();
	opts.cssFirst.left = 0;
	opts.cssBefore.left = w;
	opts.cssBefore.top = 0;
	opts.animIn.left = 0;
	opts.animOut.left = 0-w;
};
$.fn.cycle.transitions.scrollRight = function($cont, $slides, opts) {
	$cont.css('overflow','hidden');
	opts.before.push($.fn.cycle.commonReset);
	var w = $cont.width();
	opts.cssFirst.left = 0;
	opts.cssBefore.left = -w;
	opts.cssBefore.top = 0;
	opts.animIn.left = 0;
	opts.animOut.left = w;
};
$.fn.cycle.transitions.scrollHorz = function($cont, $slides, opts) {
	$cont.css('overflow','hidden').width();
	opts.before.push(function(curr, next, opts, fwd) {
		if (opts.rev)
			fwd = !fwd;
		$.fn.cycle.commonReset(curr,next,opts);
		opts.cssBefore.left = fwd ? (next.cycleW-1) : (1-next.cycleW);
		opts.animOut.left = fwd ? -curr.cycleW : curr.cycleW;
	});
	opts.cssFirst.left = 0;
	opts.cssBefore.top = 0;
	opts.animIn.left = 0;
	opts.animOut.top = 0;
};
$.fn.cycle.transitions.scrollVert = function($cont, $slides, opts) {
	$cont.css('overflow','hidden');
	opts.before.push(function(curr, next, opts, fwd) {
		if (opts.rev)
			fwd = !fwd;
		$.fn.cycle.commonReset(curr,next,opts);
		opts.cssBefore.top = fwd ? (1-next.cycleH) : (next.cycleH-1);
		opts.animOut.top = fwd ? curr.cycleH : -curr.cycleH;
	});
	opts.cssFirst.top = 0;
	opts.cssBefore.left = 0;
	opts.animIn.top = 0;
	opts.animOut.left = 0;
};

// slideX/slideY
$.fn.cycle.transitions.slideX = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$(opts.elements).not(curr).hide();
		$.fn.cycle.commonReset(curr,next,opts,false,true);
		opts.animIn.width = next.cycleW;
	});
	opts.cssBefore.left = 0;
	opts.cssBefore.top = 0;
	opts.cssBefore.width = 0;
	opts.animIn.width = 'show';
	opts.animOut.width = 0;
};
$.fn.cycle.transitions.slideY = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$(opts.elements).not(curr).hide();
		$.fn.cycle.commonReset(curr,next,opts,true,false);
		opts.animIn.height = next.cycleH;
	});
	opts.cssBefore.left = 0;
	opts.cssBefore.top = 0;
	opts.cssBefore.height = 0;
	opts.animIn.height = 'show';
	opts.animOut.height = 0;
};

// shuffle
$.fn.cycle.transitions.shuffle = function($cont, $slides, opts) {
	var i, w = $cont.css('overflow', 'visible').width();
	$slides.css({left: 0, top: 0});
	opts.before.push(function(curr,next,opts) {
		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
	});
	// only adjust speed once!
	if (!opts.speedAdjusted) {
		opts.speed = opts.speed / 2; // shuffle has 2 transitions
		opts.speedAdjusted = true;
	}
	opts.random = 0;
	opts.shuffle = opts.shuffle || {left:-w, top:15};
	opts.els = [];
	for (i=0; i < $slides.length; i++)
		opts.els.push($slides[i]);

	for (i=0; i < opts.currSlide; i++)
		opts.els.push(opts.els.shift());

	// custom transition fn (hat tip to Benjamin Sterling for this bit of sweetness!)
	opts.fxFn = function(curr, next, opts, cb, fwd) {
		if (opts.rev)
			fwd = !fwd;
		var $el = fwd ? $(curr) : $(next);
		$(next).css(opts.cssBefore);
		var count = opts.slideCount;
		$el.animate(opts.shuffle, opts.speedIn, opts.easeIn, function() {
			var hops = $.fn.cycle.hopsFromLast(opts, fwd);
			for (var k=0; k < hops; k++) {
				if (fwd)
					opts.els.push(opts.els.shift());
				else
					opts.els.unshift(opts.els.pop());
			}
			if (fwd) {
				for (var i=0, len=opts.els.length; i < len; i++)
					$(opts.els[i]).css('z-index', len-i+count);
			}
			else {
				var z = $(curr).css('z-index');
				$el.css('z-index', parseInt(z,10)+1+count);
			}
			$el.animate({left:0, top:0}, opts.speedOut, opts.easeOut, function() {
				$(fwd ? this : curr).hide();
				if (cb) cb();
			});
		});
	};
	$.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
};

// turnUp/Down/Left/Right
$.fn.cycle.transitions.turnUp = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,true,false);
		opts.cssBefore.top = next.cycleH;
		opts.animIn.height = next.cycleH;
		opts.animOut.width = next.cycleW;
	});
	opts.cssFirst.top = 0;
	opts.cssBefore.left = 0;
	opts.cssBefore.height = 0;
	opts.animIn.top = 0;
	opts.animOut.height = 0;
};
$.fn.cycle.transitions.turnDown = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,true,false);
		opts.animIn.height = next.cycleH;
		opts.animOut.top   = curr.cycleH;
	});
	opts.cssFirst.top = 0;
	opts.cssBefore.left = 0;
	opts.cssBefore.top = 0;
	opts.cssBefore.height = 0;
	opts.animOut.height = 0;
};
$.fn.cycle.transitions.turnLeft = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,false,true);
		opts.cssBefore.left = next.cycleW;
		opts.animIn.width = next.cycleW;
	});
	opts.cssBefore.top = 0;
	opts.cssBefore.width = 0;
	opts.animIn.left = 0;
	opts.animOut.width = 0;
};
$.fn.cycle.transitions.turnRight = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,false,true);
		opts.animIn.width = next.cycleW;
		opts.animOut.left = curr.cycleW;
	});
	$.extend(opts.cssBefore, { top: 0, left: 0, width: 0 });
	opts.animIn.left = 0;
	opts.animOut.width = 0;
};

// zoom
$.fn.cycle.transitions.zoom = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,false,false,true);
		opts.cssBefore.top = next.cycleH/2;
		opts.cssBefore.left = next.cycleW/2;
		$.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
		$.extend(opts.animOut, { width: 0, height: 0, top: curr.cycleH/2, left: curr.cycleW/2 });
	});
	opts.cssFirst.top = 0;
	opts.cssFirst.left = 0;
	opts.cssBefore.width = 0;
	opts.cssBefore.height = 0;
};

// fadeZoom
$.fn.cycle.transitions.fadeZoom = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,false,false);
		opts.cssBefore.left = next.cycleW/2;
		opts.cssBefore.top = next.cycleH/2;
		$.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
	});
	opts.cssBefore.width = 0;
	opts.cssBefore.height = 0;
	opts.animOut.opacity = 0;
};

// blindX
$.fn.cycle.transitions.blindX = function($cont, $slides, opts) {
	var w = $cont.css('overflow','hidden').width();
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts);
		opts.animIn.width = next.cycleW;
		opts.animOut.left   = curr.cycleW;
	});
	opts.cssBefore.left = w;
	opts.cssBefore.top = 0;
	opts.animIn.left = 0;
	opts.animOut.left = w;
};
// blindY
$.fn.cycle.transitions.blindY = function($cont, $slides, opts) {
	var h = $cont.css('overflow','hidden').height();
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts);
		opts.animIn.height = next.cycleH;
		opts.animOut.top   = curr.cycleH;
	});
	opts.cssBefore.top = h;
	opts.cssBefore.left = 0;
	opts.animIn.top = 0;
	opts.animOut.top = h;
};
// blindZ
$.fn.cycle.transitions.blindZ = function($cont, $slides, opts) {
	var h = $cont.css('overflow','hidden').height();
	var w = $cont.width();
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts);
		opts.animIn.height = next.cycleH;
		opts.animOut.top   = curr.cycleH;
	});
	opts.cssBefore.top = h;
	opts.cssBefore.left = w;
	opts.animIn.top = 0;
	opts.animIn.left = 0;
	opts.animOut.top = h;
	opts.animOut.left = w;
};

// growX - grow horizontally from centered 0 width
$.fn.cycle.transitions.growX = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,false,true);
		opts.cssBefore.left = this.cycleW/2;
		opts.animIn.left = 0;
		opts.animIn.width = this.cycleW;
		opts.animOut.left = 0;
	});
	opts.cssBefore.top = 0;
	opts.cssBefore.width = 0;
};
// growY - grow vertically from centered 0 height
$.fn.cycle.transitions.growY = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,true,false);
		opts.cssBefore.top = this.cycleH/2;
		opts.animIn.top = 0;
		opts.animIn.height = this.cycleH;
		opts.animOut.top = 0;
	});
	opts.cssBefore.height = 0;
	opts.cssBefore.left = 0;
};

// curtainX - squeeze in both edges horizontally
$.fn.cycle.transitions.curtainX = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,false,true,true);
		opts.cssBefore.left = next.cycleW/2;
		opts.animIn.left = 0;
		opts.animIn.width = this.cycleW;
		opts.animOut.left = curr.cycleW/2;
		opts.animOut.width = 0;
	});
	opts.cssBefore.top = 0;
	opts.cssBefore.width = 0;
};
// curtainY - squeeze in both edges vertically
$.fn.cycle.transitions.curtainY = function($cont, $slides, opts) {
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,true,false,true);
		opts.cssBefore.top = next.cycleH/2;
		opts.animIn.top = 0;
		opts.animIn.height = next.cycleH;
		opts.animOut.top = curr.cycleH/2;
		opts.animOut.height = 0;
	});
	opts.cssBefore.height = 0;
	opts.cssBefore.left = 0;
};

// cover - curr slide covered by next slide
$.fn.cycle.transitions.cover = function($cont, $slides, opts) {
	var d = opts.direction || 'left';
	var w = $cont.css('overflow','hidden').width();
	var h = $cont.height();
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts);
		opts.cssAfter.display = '';
		if (d == 'right')
			opts.cssBefore.left = -w;
		else if (d == 'up')
			opts.cssBefore.top = h;
		else if (d == 'down')
			opts.cssBefore.top = -h;
		else
			opts.cssBefore.left = w;
	});
	opts.animIn.left = 0;
	opts.animIn.top = 0;
	opts.cssBefore.top = 0;
	opts.cssBefore.left = 0;
};

// uncover - curr slide moves off next slide
$.fn.cycle.transitions.uncover = function($cont, $slides, opts) {
	var d = opts.direction || 'left';
	var w = $cont.css('overflow','hidden').width();
	var h = $cont.height();
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
		if (d == 'right')
			opts.animOut.left = w;
		else if (d == 'up')
			opts.animOut.top = -h;
		else if (d == 'down')
			opts.animOut.top = h;
		else
			opts.animOut.left = -w;
	});
	opts.animIn.left = 0;
	opts.animIn.top = 0;
	opts.cssBefore.top = 0;
	opts.cssBefore.left = 0;
};

// toss - move top slide and fade away
$.fn.cycle.transitions.toss = function($cont, $slides, opts) {
	var w = $cont.css('overflow','visible').width();
	var h = $cont.height();
	opts.before.push(function(curr, next, opts) {
		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
		// provide default toss settings if animOut not provided
		if (!opts.animOut.left && !opts.animOut.top)
			$.extend(opts.animOut, { left: w*2, top: -h/2, opacity: 0 });
		else
			opts.animOut.opacity = 0;
	});
	opts.cssBefore.left = 0;
	opts.cssBefore.top = 0;
	opts.animIn.left = 0;
};

// wipe - clip animation
$.fn.cycle.transitions.wipe = function($cont, $slides, opts) {
	var w = $cont.css('overflow','hidden').width();
	var h = $cont.height();
	opts.cssBefore = opts.cssBefore || {};
	var clip;
	if (opts.clip) {
		if (/l2r/.test(opts.clip))
			clip = 'rect(0px 0px '+h+'px 0px)';
		else if (/r2l/.test(opts.clip))
			clip = 'rect(0px '+w+'px '+h+'px '+w+'px)';
		else if (/t2b/.test(opts.clip))
			clip = 'rect(0px '+w+'px 0px 0px)';
		else if (/b2t/.test(opts.clip))
			clip = 'rect('+h+'px '+w+'px '+h+'px 0px)';
		else if (/zoom/.test(opts.clip)) {
			var top = parseInt(h/2,10);
			var left = parseInt(w/2,10);
			clip = 'rect('+top+'px '+left+'px '+top+'px '+left+'px)';
		}
	}

	opts.cssBefore.clip = opts.cssBefore.clip || clip || 'rect(0px 0px 0px 0px)';

	var d = opts.cssBefore.clip.match(/(\d+)/g);
	var t = parseInt(d[0],10), r = parseInt(d[1],10), b = parseInt(d[2],10), l = parseInt(d[3],10);

	opts.before.push(function(curr, next, opts) {
		if (curr == next) return;
		var $curr = $(curr), $next = $(next);
		$.fn.cycle.commonReset(curr,next,opts,true,true,false);
		opts.cssAfter.display = 'block';

		var step = 1, count = parseInt((opts.speedIn / 13),10) - 1;
		(function f() {
			var tt = t ? t - parseInt(step * (t/count),10) : 0;
			var ll = l ? l - parseInt(step * (l/count),10) : 0;
			var bb = b < h ? b + parseInt(step * ((h-b)/count || 1),10) : h;
			var rr = r < w ? r + parseInt(step * ((w-r)/count || 1),10) : w;
			$next.css({ clip: 'rect('+tt+'px '+rr+'px '+bb+'px '+ll+'px)' });
			(step++ <= count) ? setTimeout(f, 13) : $curr.css('display', 'none');
		})();
	});
	$.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
	opts.animIn	   = { left: 0 };
	opts.animOut   = { left: 0 };
};

})(jQuery);
;
/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 *
 * Open source under the BSD License.
 *
 * Copyright Â© 2008 George McGinley Smith
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 *
 * Neither the name of the author nor the names of contributors may be used to endorse
 * or promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(jQuery.easing.default);
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});;/**!
 * easy-pie-chart
 * Lightweight plugin to render simple, animated and retina optimized pie charts
 *
 * @license
 * @author Robert Fleischmann <rendro87@gmail.com> (http://robert-fleischmann.de)
 * @version 2.1.7
 **/

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module unless amdModuleId is set
    define(["jquery"], function (a0) {
      return (factory(a0));
    });
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory(require("jquery"));
  } else {
    factory(jQuery);
  }
}(this, function ($) {

/**
 * Renderer to render the chart on a canvas object
 * @param {DOMElement} el      DOM element to host the canvas (root of the plugin)
 * @param {object}     options options object of the plugin
 */
var CanvasRenderer = function(el, options) {
	var cachedBackground;
	var canvas = document.createElement('canvas');

	el.appendChild(canvas);

	if (typeof(G_vmlCanvasManager) === 'object') {
		G_vmlCanvasManager.initElement(canvas);
	}

	var ctx = canvas.getContext('2d');

	canvas.width = canvas.height = options.size;

	// canvas on retina devices
	var scaleBy = 1;
	if (window.devicePixelRatio > 1) {
		scaleBy = window.devicePixelRatio;
		canvas.style.width = canvas.style.height = [options.size, 'px'].join('');
		canvas.width = canvas.height = options.size * scaleBy;
		ctx.scale(scaleBy, scaleBy);
	}

	// move 0,0 coordinates to the center
	ctx.translate(options.size / 2, options.size / 2);

	// rotate canvas -90deg
	ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI);

	var radius = (options.size - options.lineWidth) / 2;
	if (options.scaleColor && options.scaleLength) {
		radius -= options.scaleLength + 2; // 2 is the distance between scale and bar
	}

	// IE polyfill for Date
	Date.now = Date.now || function() {
		return +(new Date());
	};

	/**
	 * Draw a circle around the center of the canvas
	 * @param {strong} color     Valid CSS color string
	 * @param {number} lineWidth Width of the line in px
	 * @param {number} percent   Percentage to draw (float between -1 and 1)
	 */
	var drawCircle = function(color, lineWidth, percent) {
		percent = Math.min(Math.max(-1, percent || 0), 1);
		var isNegative = percent <= 0 ? true : false;

		ctx.beginPath();
		ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, isNegative);

		ctx.strokeStyle = color;
		ctx.lineWidth = lineWidth;

		ctx.stroke();
	};

	/**
	 * Draw the scale of the chart
	 */
	var drawScale = function() {
		var offset;
		var length;

		ctx.lineWidth = 1;
		ctx.fillStyle = options.scaleColor;

		ctx.save();
		for (var i = 24; i > 0; --i) {
			if (i % 6 === 0) {
				length = options.scaleLength;
				offset = 0;
			} else {
				length = options.scaleLength * 0.6;
				offset = options.scaleLength - length;
			}
			ctx.fillRect(-options.size/2 + offset, 0, length, 1);
			ctx.rotate(Math.PI / 12);
		}
		ctx.restore();
	};

	/**
	 * Request animation frame wrapper with polyfill
	 * @return {function} Request animation frame method or timeout fallback
	 */
	var reqAnimationFrame = (function() {
		return  window.requestAnimationFrame ||
				window.webkitRequestAnimationFrame ||
				window.mozRequestAnimationFrame ||
				function(callback) {
					window.setTimeout(callback, 1000 / 60);
				};
	}());

	/**
	 * Draw the background of the plugin including the scale and the track
	 */
	var drawBackground = function() {
		if(options.scaleColor) drawScale();
		if(options.trackColor) drawCircle(options.trackColor, options.trackWidth || options.lineWidth, 1);
	};

  /**
    * Canvas accessor
   */
  this.getCanvas = function() {
    return canvas;
  };

  /**
    * Canvas 2D context 'ctx' accessor
   */
  this.getCtx = function() {
    return ctx;
  };

	/**
	 * Clear the complete canvas
	 */
	this.clear = function() {
		ctx.clearRect(options.size / -2, options.size / -2, options.size, options.size);
	};

	/**
	 * Draw the complete chart
	 * @param {number} percent Percent shown by the chart between -100 and 100
	 */
	this.draw = function(percent) {
		// do we need to render a background
		if (!!options.scaleColor || !!options.trackColor) {
			// getImageData and putImageData are supported
			if (ctx.getImageData && ctx.putImageData) {
				if (!cachedBackground) {
					drawBackground();
					cachedBackground = ctx.getImageData(0, 0, options.size * scaleBy, options.size * scaleBy);
				} else {
					ctx.putImageData(cachedBackground, 0, 0);
				}
			} else {
				this.clear();
				drawBackground();
			}
		} else {
			this.clear();
		}

		ctx.lineCap = options.lineCap;

		// if barcolor is a function execute it and pass the percent as a value
		var color;
		if (typeof(options.barColor) === 'function') {
			color = options.barColor(percent);
		} else {
			color = options.barColor;
		}

		// draw bar
		drawCircle(color, options.lineWidth, percent / 100);
	}.bind(this);

	/**
	 * Animate from some percent to some other percentage
	 * @param {number} from Starting percentage
	 * @param {number} to   Final percentage
	 */
	this.animate = function(from, to) {
		var startTime = Date.now();
		options.onStart(from, to);
		var animation = function() {
			var process = Math.min(Date.now() - startTime, options.animate.duration);
			var currentValue = options.easing(this, process, from, to - from, options.animate.duration);
			this.draw(currentValue);
			options.onStep(from, to, currentValue);
			if (process >= options.animate.duration) {
				options.onStop(from, to);
			} else {
				reqAnimationFrame(animation);
			}
		}.bind(this);

		reqAnimationFrame(animation);
	}.bind(this);
};

var EasyPieChart = function(el, opts) {
	var defaultOptions = {
		barColor: '#ef1e25',
		trackColor: '#f9f9f9',
		scaleColor: '#dfe0e0',
		scaleLength: 5,
		lineCap: 'round',
		lineWidth: 3,
		trackWidth: undefined,
		size: 110,
		rotate: 0,
		animate: {
			duration: 1000,
			enabled: true
		},
		easing: function (x, t, b, c, d) { // more can be found here: http://gsgd.co.uk/sandbox/jquery/easing/
			t = t / (d/2);
			if (t < 1) {
				return c / 2 * t * t + b;
			}
			return -c/2 * ((--t)*(t-2) - 1) + b;
		},
		onStart: function(from, to) {
			return;
		},
		onStep: function(from, to, currentValue) {
			return;
		},
		onStop: function(from, to) {
			return;
		}
	};

	// detect present renderer
	if (typeof(CanvasRenderer) !== 'undefined') {
		defaultOptions.renderer = CanvasRenderer;
	} else if (typeof(SVGRenderer) !== 'undefined') {
		defaultOptions.renderer = SVGRenderer;
	} else {
		throw new Error('Please load either the SVG- or the CanvasRenderer');
	}

	var options = {};
	var currentValue = 0;

	/**
	 * Initialize the plugin by creating the options object and initialize rendering
	 */
	var init = function() {
		this.el = el;
		this.options = options;

		// merge user options into default options
		for (var i in defaultOptions) {
			if (defaultOptions.hasOwnProperty(i)) {
				options[i] = opts && typeof(opts[i]) !== 'undefined' ? opts[i] : defaultOptions[i];
				if (typeof(options[i]) === 'function') {
					options[i] = options[i].bind(this);
				}
			}
		}

		// check for jQuery easing
		if (typeof(options.easing) === 'string' && typeof(jQuery) !== 'undefined' && jQuery.isFunction(jQuery.easing[options.easing])) {
			options.easing = jQuery.easing[options.easing];
		} else {
			options.easing = defaultOptions.easing;
		}

		// process earlier animate option to avoid bc breaks
		if (typeof(options.animate) === 'number') {
			options.animate = {
				duration: options.animate,
				enabled: true
			};
		}

		if (typeof(options.animate) === 'boolean' && !options.animate) {
			options.animate = {
				duration: 1000,
				enabled: options.animate
			};
		}

		// create renderer
		this.renderer = new options.renderer(el, options);

		// initial draw
		this.renderer.draw(currentValue);

		// initial update
		if (el.dataset && el.dataset.percent) {
			this.update(parseFloat(el.dataset.percent));
		} else if (el.getAttribute && el.getAttribute('data-percent')) {
			this.update(parseFloat(el.getAttribute('data-percent')));
		}
	}.bind(this);

	/**
	 * Update the value of the chart
	 * @param  {number} newValue Number between 0 and 100
	 * @return {object}          Instance of the plugin for method chaining
	 */
	this.update = function(newValue) {
		newValue = parseFloat(newValue);
		if (options.animate.enabled) {
			this.renderer.animate(currentValue, newValue);
		} else {
			this.renderer.draw(newValue);
		}
		currentValue = newValue;
		return this;
	}.bind(this);

	/**
	 * Disable animation
	 * @return {object} Instance of the plugin for method chaining
	 */
	this.disableAnimation = function() {
		options.animate.enabled = false;
		return this;
	};

	/**
	 * Enable animation
	 * @return {object} Instance of the plugin for method chaining
	 */
	this.enableAnimation = function() {
		options.animate.enabled = true;
		return this;
	};

	init();
};

$.fn.easyPieChart = function(options) {
	return this.each(function() {
		var instanceOptions;

		if (!$.data(this, 'easyPieChart')) {
			instanceOptions = $.extend({}, options, $(this).data());
			$.data(this, 'easyPieChart', new EasyPieChart(this, instanceOptions));
		}
	});
};


}));
;(function( window, $, undefined ) {

	/*
	* smartresize: debounced resize event for jQuery
	*
	* latest version and complete README available on Github:
	* https://github.com/louisremi/jquery.smartresize.js
	*
	* Copyright 2011 @louis_remi
	* Licensed under the MIT license.
	*/

	var $event = $.event, resizeTimeout;

	$event.special.smartresize 	= {
		setup: function() {
			$(this).bind( "resize", $event.special.smartresize.handler );
		},
		teardown: function() {
			$(this).unbind( "resize", $event.special.smartresize.handler );
		},
		handler: function( event, execAsap ) {
			// Save the context
			var context = this,
				args 	= arguments;

			// set correct event type
			event.type = "smartresize";

			if ( resizeTimeout ) { clearTimeout( resizeTimeout ); }
			resizeTimeout = setTimeout(function() {
				jQuery.event.handle.apply( context, args );
			}, execAsap === "execAsap"? 0 : 100 );
		}
	};

	$.fn.smartresize 			= function( fn ) {
		return fn ? this.bind( "smartresize", fn ) : this.trigger( "smartresize", ["execAsap"] );
	};

	$.Slideshow 				= function( options, element ) {

		this.$el			= $( element );

		/***** images ****/

		// list of image items
		this.$list			= this.$el.find('ul.ei-slider-large');
		// image items
		this.$imgItems		= this.$list.children('li');
		// total number of items
		this.itemsCount		= this.$imgItems.length;
		// images
		this.$images		= this.$imgItems.find('img:first');

		/***** thumbs ****/

		// thumbs wrapper
		this.$sliderthumbs	= this.$el.find('ul.ei-slider-thumbs').hide();
		// slider elements
		this.$sliderElems	= this.$sliderthumbs.children('li');
		// sliding div
		this.$sliderElem	= this.$sliderthumbs.children('li.ei-slider-element');
		// thumbs
		this.$thumbs		= this.$sliderElems.not('.ei-slider-element');

		// initialize slideshow
		this._init( options );

	};

	$.Slideshow.defaults 		= {
		// animation types:
		// "sides" : new slides will slide in from left / right
		// "center": new slides will appear in the center
		animation			: 'sides', // sides || center
		// if true the slider will automatically slide, and it will only stop if the user clicks on a thumb
		autoplay			: false,
		// interval for the slideshow
		slideshow_interval	: 3000,
		// speed for the sliding animation
		speed			: 800,
		// easing for the sliding animation
		easing			: '',
		// percentage of speed for the titles animation. Speed will be speed * titlesFactor
		titlesFactor		: 0.60,
		// titles animation speed
		titlespeed			: 800,
		// titles animation easing
		titleeasing			: '',
		// maximum width for the thumbs in pixels
		thumbMaxWidth		: 150
	};

	$.Slideshow.prototype 		= {
		_init 				: function( options ) {

			this.options 		= $.extend( true, {}, $.Slideshow.defaults, options );

			// set the opacity of the title elements and the image items
			this.$imgItems.css( 'opacity', 0 );
			this.$imgItems.find('div.ei-title > *').css( 'opacity', 0 );

			// index of current visible slider
			this.current		= 0;

			var _self			= this;

			// preload images
			// add loading status
			this.$loading		= $('<div class="ei-slider-loading">Loading</div>').prependTo( _self.$el );

			$.when( this._preloadImages() ).done( function() {

				// hide loading status
				_self.$loading.hide();

				// calculate size and position for each image
				_self._setImagesSize();

				// configure thumbs container
				_self._initThumbs();

				// show first
				_self.$imgItems.eq( _self.current ).css({
					'opacity' 	: 1,
					'z-index'	: 10
				}).show().find('div.ei-title > *').css( 'opacity', 1 );

				// if autoplay is true
				if( _self.options.autoplay ) {

					_self._startSlideshow();

				}

				// initialize the events
				_self._initEvents();

			});

		},
		_preloadImages		: function() {

			// preloads all the large images

			var _self	= this,
				loaded	= 0;

			return $.Deferred(

				function(dfd) {

					_self.$images.each( function( i ) {

						$('<img/>').load( function() {

							if( ++loaded === _self.itemsCount ) {

								dfd.resolve();

							}

						}).attr( 'src', $(this).attr('src') );

					});

				}

			).promise();

		},
		_setImagesSize		: function() {

			// save ei-slider's width
			this.elWidth	= this.$el.width();

			var _self	= this;

			this.$images.each( function( i ) {

				var $img	= $(this);
					imgDim	= _self._getImageDim( $img.attr('src') );

				$img.css({
					width		: imgDim.width,
					height		: imgDim.height,
					marginLeft	: imgDim.left,
					marginTop	: imgDim.top
				});

			});

		},
		_getImageDim		: function( src ) {

			var $img	= new Image();

			$img.src	= src;

			var c_w		= this.elWidth,
				c_h		= this.$el.height(),
				r_w		= c_h / c_w,

				i_w		= $img.width,
				i_h		= $img.height,
				r_i		= i_h / i_w,
				new_w, new_h, new_left, new_top;

			if( r_w > r_i ) {

				new_h	= c_h;
				new_w	= c_h / r_i;

			}
			else {

				new_h	= c_w * r_i;
				new_w	= c_w;

			}

			return {
				width	: new_w,
				height	: new_h,
				left	: ( c_w - new_w ) / 2,
				top		: ( c_h - new_h ) / 2
			};

		},
		_initThumbs			: function() {

			// set the max-width of the slider elements to the one set in the plugin's options
			// also, the width of each slider element will be 100% / total number of elements
			this.$sliderElems.css({
				'max-width' : this.options.thumbMaxWidth + 'px',
				'width'		: 100 / this.itemsCount + '%'
			});

			// set the max-width of the slider and show it
			this.$sliderthumbs.css( 'max-width', this.options.thumbMaxWidth * this.itemsCount + 'px' ).show();

		},
		_startSlideshow		: function() {

			var _self	= this;

			this.slideshow	= setTimeout( function() {

				var pos;

				( _self.current === _self.itemsCount - 1 ) ? pos = 0 : pos = _self.current + 1;

				_self._slideTo( pos );

				if( _self.options.autoplay ) {

					_self._startSlideshow();

				}

			}, this.options.slideshow_interval);

		},
		// shows the clicked thumb's slide
		_slideTo			: function( pos ) {

			// return if clicking the same element or if currently animating
			if( pos === this.current || this.isAnimating )
				return false;

			this.isAnimating	= true;

			var $currentSlide	= this.$imgItems.eq( this.current ),
				$nextSlide		= this.$imgItems.eq( pos ),
				_self			= this,

				preCSS			= {zIndex	: 10},
				animCSS			= {opacity	: 1};

			// new slide will slide in from left or right side
			if( this.options.animation === 'sides' ) {

				preCSS.left		= ( pos > this.current ) ? -1 * this.elWidth : this.elWidth;
				animCSS.left	= 0;

			}

			// titles animation
			$nextSlide.find('div.ei-title > h2')
					  .css( 'margin-right', 50 + 'px' )
					  .stop()
					  .delay( this.options.speed * this.options.titlesFactor )
					  .animate({ marginRight : 0 + 'px', opacity : 1 }, this.options.titlespeed, this.options.titleeasing )
					  .end()
					  .find('div.ei-title > h3')
					  .css( 'margin-right', -50 + 'px' )
					  .stop()
					  .delay( this.options.speed * this.options.titlesFactor )
					  .animate({ marginRight : 0 + 'px', opacity : 1 }, this.options.titlespeed, this.options.titleeasing );

			$.when(

				// fade out current titles
				$currentSlide.css( 'z-index' , 1 ).find('div.ei-title > *').stop().fadeOut( this.options.speed / 2, function() {
					// reset style
					$(this).show().css( 'opacity', 0 );
				}),

				// animate next slide in
				$nextSlide.css( preCSS ).stop().animate( animCSS, this.options.speed, this.options.easing ),

				// "sliding div" moves to new position
				this.$sliderElem.stop().animate({
					left	: this.$thumbs.eq( pos ).position().left
				}, this.options.speed )

			).done( function() {

				// reset values
				$currentSlide.css( 'opacity' , 0 ).find('div.ei-title > *').css( 'opacity', 0 );
					_self.current	= pos;
					_self.isAnimating		= false;

				});

		},
		_initEvents			: function() {

			var _self	= this;

			// window resize
			$(window).on( 'smartresize.eislideshow', function( event ) {

				// resize the images
				_self._setImagesSize();

				// reset position of thumbs sliding div
				_self.$sliderElem.css( 'left', _self.$thumbs.eq( _self.current ).position().left );

			});

			// click the thumbs
			this.$thumbs.on( 'click.eislideshow', function( event ) {

				if( _self.options.autoplay ) {

					clearTimeout( _self.slideshow );
					_self.options.autoplay	= false;

				}

				var $thumb	= $(this),
					idx		= $thumb.index() - 1; // exclude sliding div

				_self._slideTo( idx );

				return false;

			});

		}
	};

	var logError 				= function( message ) {

		if ( this.console ) {

			console.error( message );

		}

	};

	$.fn.eislideshow			= function( options ) {

		if ( typeof options === 'string' ) {

			var args = Array.prototype.slice.call( arguments, 1 );

			this.each(function() {

				var instance = $.data( this, 'eislideshow' );

				if ( !instance ) {
					logError( "cannot call methods on eislideshow prior to initialization; " +
					"attempted to call method '" + options + "'" );
					return;
				}

				if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
					logError( "no such method '" + options + "' for eislideshow instance" );
					return;
				}

				instance[ options ].apply( instance, args );

			});

		}
		else {

			this.each(function() {

				var instance = $.data( this, 'eislideshow' );
				if ( !instance ) {
					$.data( this, 'eislideshow', new $.Slideshow( options, this ) );
				}

			});

		}

		return this;

	};

})( window, jQuery );;/*jshint browser:true */
/*!
* FitVids 1.1
*
* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
* Released under the WTFPL license - http://sam.zoy.org/wtfpl/
*
*/

;(function( $ ){

  'use strict';

  $.fn.fitVids = function( options ) {
    var settings = {
      customSelector: null,
      ignore: null
    };

    if(!document.getElementById('fit-vids-style')) {
      // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js
      var head = document.head || document.getElementsByTagName('head')[0];
      var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';
      var div = document.createElement("div");
      div.innerHTML = '<p>x</p><style id="fit-vids-style">' + css + '</style>';
      head.appendChild(div.childNodes[1]);
    }

    if ( options ) {
      $.extend( settings, options );
    }

    return this.each(function(){
      var selectors = [
        'iframe[src*="player.vimeo.com"]',
        'iframe[src*="youtube.com"]',
        'iframe[src*="youtube-nocookie.com"]',
        'iframe[src*="kickstarter.com"][src*="video.html"]',
        'object',
        'embed'
      ];

      if (settings.customSelector) {
        selectors.push(settings.customSelector);
      }

      var ignoreList = '.fitvidsignore';

      if(settings.ignore) {
        ignoreList = ignoreList + ', ' + settings.ignore;
      }

      var $allVideos = $(this).find(selectors.join(','));
      $allVideos = $allVideos.not('object object'); // SwfObj conflict patch
      $allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.

      $allVideos.each(function(){
        var $this = $(this);
        if($this.parents(ignoreList).length > 0) {
          return; // Disable FitVids on this video.
        }
        if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
        if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width'))))
        {
          $this.attr('height', 9);
          $this.attr('width', 16);
        }
        var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
            width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
            aspectRatio = height / width;
        if(!$this.attr('name')){
          var videoName = 'fitvid' + $.fn.fitVids._count;
          $this.attr('name', videoName);
          $.fn.fitVids._count++;
        }
        $this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%');
        $this.removeAttr('height').removeAttr('width');
      });
    });
  };
  
  // Internal counter for unique video names.
  $.fn.fitVids._count = 0;
  
// Works with either jQuery or Zepto
})( window.jQuery || window.Zepto );;/* jquery.nicescroll
-- version 3.5.0 BETA5
-- copyright 2011-12-13 InuYaksa*2013
-- licensed under the MIT
--
-- http://areaaperta.com/nicescroll
-- https://github.com/inuyaksa/jquery.nicescroll
--
*/

(function(jQuery){

  // globals
  var domfocus = false;
  var mousefocus = false;
  var zoomactive = false;
  var tabindexcounter = 5000;
  var ascrailcounter = 2000;
  var globalmaxzindex = 0;
  
  var $ = jQuery;  // sandbox
 
  // http://stackoverflow.com/questions/2161159/get-script-path
  function getScriptPath() {
    var scripts=document.getElementsByTagName('script');
    var path=scripts[scripts.length-1].src.split('?')[0];
    return (path.split('/').length>0) ? path.split('/').slice(0,-1).join('/')+'/' : '';
  }
  var scriptpath = getScriptPath();
  
  var vendors = ['ms','moz','webkit','o'];
  
  var setAnimationFrame = window.requestAnimationFrame||false;
  var clearAnimationFrame = window.cancelAnimationFrame||false;

  if (!setAnimationFrame) {
    for(var vx in vendors) {
      var v = vendors[vx];
      if (!setAnimationFrame) setAnimationFrame = window[v+'RequestAnimationFrame'];
      if (!clearAnimationFrame) clearAnimationFrame = window[v+'CancelAnimationFrame']||window[v+'CancelRequestAnimationFrame'];
    }
  }
  
  var clsMutationObserver = window.MutationObserver || window.WebKitMutationObserver || false;
  
  var _globaloptions = {
      zindex:"auto",
      cursoropacitymin:0,
      cursoropacitymax:1,
      cursorcolor:"#424242",
      cursorwidth:"5px",
      cursorborder:"1px solid #fff",
      cursorborderradius:"5px",
      scrollspeed:60,
      mousescrollstep:8*3,
      touchbehavior:false,
      hwacceleration:true,
      usetransition:true,
      boxzoom:false,
      dblclickzoom:true,
      gesturezoom:true,
      grabcursorenabled:true,
      autohidemode:true,
      background:"",
      iframeautoresize:true,
      cursorminheight:32,
      preservenativescrolling:true,
      railoffset:false,
      bouncescroll:true,
      spacebarenabled:true,
      railpadding:{top:0,right:0,left:0,bottom:0},
      disableoutline:true,
      horizrailenabled:true,
      railalign:"right",
      railvalign:"bottom",
      enabletranslate3d:true,
      enablemousewheel:true,
      enablekeyboard:true,
      smoothscroll:true,
      sensitiverail:true,
      enablemouselockapi:true,
//      cursormaxheight:false,
      cursorfixedheight:false,      
      directionlockdeadzone:6,
      hidecursordelay:400,
      nativeparentscrolling:true,
      enablescrollonselection:true,
      overflowx:true,
      overflowy:true,
      cursordragspeed:0.3,
      rtlmode:false,
      cursordragontouch:false,
      oneaxismousemode:"auto"
  };
  
  var browserdetected = false;
  
  var getBrowserDetection = function() {
  
    if (browserdetected) return browserdetected;
  
    var domtest = document.createElement('DIV');

    var d = {};
    
		d.haspointerlock = "pointerLockElement" in document || "mozPointerLockElement" in document || "webkitPointerLockElement" in document;
		
    d.isopera = ("opera" in window);
    d.isopera12 = (d.isopera&&("getUserMedia" in navigator));
    d.isoperamini = (Object.prototype.toString.call(window.operamini) === "[object OperaMini]");
    
    d.isie = (("all" in document) && ("attachEvent" in domtest) && !d.isopera);
    d.isieold = (d.isie && !("msInterpolationMode" in domtest.style));  // IE6 and older
    d.isie7 = d.isie&&!d.isieold&&(!("documentMode" in document)||(document.documentMode==7));
    d.isie8 = d.isie&&("documentMode" in document)&&(document.documentMode==8);
    d.isie9 = d.isie&&("performance" in window)&&(document.documentMode>=9);
    d.isie10 = d.isie&&("performance" in window)&&(document.documentMode>=10);
    
    d.isie9mobile = /iemobile.9/i.test(navigator.userAgent);  //wp 7.1 mango
    if (d.isie9mobile) d.isie9 = false;
    d.isie7mobile = (!d.isie9mobile&&d.isie7) && /iemobile/i.test(navigator.userAgent);  //wp 7.0
    
    d.ismozilla = ("MozAppearance" in domtest.style);
		
    d.iswebkit = ("WebkitAppearance" in domtest.style);
    
    d.ischrome = ("chrome" in window);
		d.ischrome22 = (d.ischrome&&d.haspointerlock);
    d.ischrome26 = (d.ischrome&&("transition" in domtest.style));  // issue with transform detection (maintain prefix)
    
    d.cantouch = ("ontouchstart" in document.documentElement)||("ontouchstart" in window);  // detection for Chrome Touch Emulation
    d.hasmstouch = (window.navigator.msPointerEnabled||false);  // IE10+ pointer events
		
    d.ismac = /^mac$/i.test(navigator.platform);
    
    d.isios = (d.cantouch && /iphone|ipad|ipod/i.test(navigator.platform));
    d.isios4 = ((d.isios)&&!("seal" in Object));
    
    d.isandroid = (/android/i.test(navigator.userAgent));
    
    d.trstyle = false;
    d.hastransform = false;
    d.hastranslate3d = false;
    d.transitionstyle = false;
    d.hastransition = false;
    d.transitionend = false;
    
    var check = ['transform','msTransform','webkitTransform','MozTransform','OTransform'];
    for(var a=0;a<check.length;a++){
      if (typeof domtest.style[check[a]] != "undefined") {
        d.trstyle = check[a];
        break;
      }
    }
    d.hastransform = (d.trstyle != false);
    if (d.hastransform) {
      domtest.style[d.trstyle] = "translate3d(1px,2px,3px)";
      d.hastranslate3d = /translate3d/.test(domtest.style[d.trstyle]);
    }
    
    d.transitionstyle = false;
    d.prefixstyle = '';
    d.transitionend = false;
    var check = ['transition','webkitTransition','MozTransition','OTransition','OTransition','msTransition','KhtmlTransition'];
    var prefix = ['','-webkit-','-moz-','-o-','-o','-ms-','-khtml-'];
    var evs = ['transitionend','webkitTransitionEnd','transitionend','otransitionend','oTransitionEnd','msTransitionEnd','KhtmlTransitionEnd'];
    for(var a=0;a<check.length;a++) {
      if (check[a] in domtest.style) {
        d.transitionstyle = check[a];
        d.prefixstyle = prefix[a];
        d.transitionend = evs[a];
        break;
      }
    }
    if (d.ischrome26) {  // use always prefix
      d.prefixstyle = prefix[1];
    }
    
    d.hastransition = (d.transitionstyle);
    
    function detectCursorGrab() {      
      var lst = ['-moz-grab','-webkit-grab','grab'];
      if ((d.ischrome&&!d.ischrome22)||d.isie) lst=[];  // force setting for IE returns false positive and chrome cursor bug
      for(var a=0;a<lst.length;a++) {
        var p = lst[a];
        domtest.style['cursor']=p;
        if (domtest.style['cursor']==p) return p;
      }
      return 'url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur),n-resize';  // thank you google for custom cursor!
    }
    d.cursorgrabvalue = detectCursorGrab();

    d.hasmousecapture = ("setCapture" in domtest);
    
    d.hasMutationObserver = (clsMutationObserver !== false);
    
    domtest = null;  //memory released

    browserdetected = d;
    
    return d;  
  };
  
  var NiceScrollClass = function(myopt,me) {

    var self = this;

    this.version = '3.5.0 BETA5';
    this.name = 'nicescroll';
    
    this.me = me;
    
    this.opt = {
      doc:$("body"),
      win:false
    };
    
    $.extend(this.opt,_globaloptions);
    
// Options for internal use
    this.opt.snapbackspeed = 80;
    
    if (myopt||false) {
      for(var a in self.opt) {
        if (typeof myopt[a] != "undefined") self.opt[a] = myopt[a];
      }
    }
    
    this.doc = self.opt.doc;
    this.iddoc = (this.doc&&this.doc[0])?this.doc[0].id||'':'';    
    this.ispage = /BODY|HTML/.test((self.opt.win)?self.opt.win[0].nodeName:this.doc[0].nodeName);
    this.haswrapper = (self.opt.win!==false);
    this.win = self.opt.win||(this.ispage?$(window):this.doc);
    this.docscroll = (this.ispage&&!this.haswrapper)?$(window):this.win;
    this.body = $("body");
    this.viewport = false;
    
    this.isfixed = false;
    
    this.iframe = false;
    this.isiframe = ((this.doc[0].nodeName == 'IFRAME') && (this.win[0].nodeName == 'IFRAME'));
    
    this.istextarea = (this.win[0].nodeName == 'TEXTAREA');
    
    this.forcescreen = false; //force to use screen position on events

    this.canshowonmouseevent = (self.opt.autohidemode!="scroll");
    
// Events jump table    
    this.onmousedown = false;
    this.onmouseup = false;
    this.onmousemove = false;
    this.onmousewheel = false;
    this.onkeypress = false;
    this.ongesturezoom = false;
    this.onclick = false;
    
// Nicescroll custom events
    this.onscrollstart = false;
    this.onscrollend = false;
    this.onscrollcancel = false;    
    
    this.onzoomin = false;
    this.onzoomout = false;
    
// Let's start!  
    this.view = false;
    this.page = false;
    
    this.scroll = {x:0,y:0};
    this.scrollratio = {x:0,y:0};    
    this.cursorheight = 20;
    this.scrollvaluemax = 0;
    
    this.checkrtlmode = false;
    
    this.scrollrunning = false;
    
    this.scrollmom = false;
    
    this.observer = false;
    this.observerremover = false;  // observer on parent for remove detection
    
    do {
      this.id = "ascrail"+(ascrailcounter++);
    } while (document.getElementById(this.id));
    
    this.rail = false;
    this.cursor = false;
    this.cursorfreezed = false;  
    this.selectiondrag = false;
    
    this.zoom = false;
    this.zoomactive = false;
    
    this.hasfocus = false;
    this.hasmousefocus = false;
    
    this.visibility = true;
    this.locked = false;
    this.hidden = false; // rails always hidden
    this.cursoractive = true; // user can interact with cursors
    
    this.overflowx = self.opt.overflowx;
    this.overflowy = self.opt.overflowy;
    
    this.nativescrollingarea = false;
    this.checkarea = 0;
    
    this.events = [];  // event list for unbind
    
    this.saved = {};
    
    this.delaylist = {};
    this.synclist = {};
    
    this.lastdeltax = 0;
    this.lastdeltay = 0;
    
    this.detected = getBrowserDetection(); 
    
    var cap = $.extend({},this.detected);
 
    this.canhwscroll = (cap.hastransform&&self.opt.hwacceleration);
    this.ishwscroll = (this.canhwscroll&&self.haswrapper);
    
    this.istouchcapable = false;  // desktop devices with touch screen support
    
//## Check Chrome desktop with touch support
    if (cap.cantouch&&cap.ischrome&&!cap.isios&&!cap.isandroid) {
      this.istouchcapable = true;
      cap.cantouch = false;  // parse normal desktop events
    }    

//## Firefox 18 nightly build (desktop) false positive (or desktop with touch support)
    if (cap.cantouch&&cap.ismozilla&&!cap.isios&&!cap.isandroid) {
      this.istouchcapable = true;
      cap.cantouch = false;  // parse normal desktop events
    }    
    
//## disable MouseLock API on user request

    if (!self.opt.enablemouselockapi) {
      cap.hasmousecapture = false;
      cap.haspointerlock = false;
    }
    
    this.delayed = function(name,fn,tm,lazy) {
      var dd = self.delaylist[name];
      var nw = (new Date()).getTime();
      if (!lazy&&dd&&dd.tt) return false;
      if (dd&&dd.tt) clearTimeout(dd.tt);
      if (dd&&dd.last+tm>nw&&!dd.tt) {      
        self.delaylist[name] = {
          last:nw+tm,
          tt:setTimeout(function(){self.delaylist[name].tt=0;fn.call();},tm)
        }
      }
      else if (!dd||!dd.tt) {
        self.delaylist[name] = {
          last:nw,
          tt:0
        };
        setTimeout(function(){fn.call();},0);
      };
    };
    
    this.debounced = function(name,fn,tm) {
      var dd = self.delaylist[name];
      var nw = (new Date()).getTime();      
      self.delaylist[name] = fn;
      if (!dd) {        
        setTimeout(function(){var fn=self.delaylist[name];self.delaylist[name]=false;fn.call();},tm);
      }
    };
    
    this.synched = function(name,fn) {
    
      function requestSync() {
        if (self.onsync) return;
        setAnimationFrame(function(){
          self.onsync = false;
          for(name in self.synclist){
            var fn = self.synclist[name];
            if (fn) fn.call(self);
            self.synclist[name] = false;
          }
        });
        self.onsync = true;
      };    
    
      self.synclist[name] = fn;
      requestSync();
      return name;
    };
    
    this.unsynched = function(name) {
      if (self.synclist[name]) self.synclist[name] = false;
    };
    
    this.css = function(el,pars) {  // save & set
      for(var n in pars) {
        self.saved.css.push([el,n,el.css(n)]);
        el.css(n,pars[n]);
      }
    };
    
    this.scrollTop = function(val) {
      return (typeof val == "undefined") ? self.getScrollTop() : self.setScrollTop(val);
    };

    this.scrollLeft = function(val) {
      return (typeof val == "undefined") ? self.getScrollLeft() : self.setScrollLeft(val);
    };
    
// derived by by Dan Pupius www.pupius.net
    BezierClass = function(st,ed,spd,p1,p2,p3,p4) {
      this.st = st;
      this.ed = ed;
      this.spd = spd;
      
      this.p1 = p1||0;
      this.p2 = p2||1;
      this.p3 = p3||0;
      this.p4 = p4||1;
      
      this.ts = (new Date()).getTime();
      this.df = this.ed-this.st;
    };
    BezierClass.prototype = {
      B2:function(t){ return 3*t*t*(1-t) },
      B3:function(t){ return 3*t*(1-t)*(1-t) },
      B4:function(t){ return (1-t)*(1-t)*(1-t) },
      getNow:function(){
        var nw = (new Date()).getTime();
        var pc = 1-((nw-this.ts)/this.spd);
        var bz = this.B2(pc) + this.B3(pc) + this.B4(pc);
        return (pc<0) ? this.ed : this.st+Math.round(this.df*bz);
      },
      update:function(ed,spd){
        this.st = this.getNow();
        this.ed = ed;
        this.spd = spd;
        this.ts = (new Date()).getTime();
        this.df = this.ed-this.st;
        return this;
      }
    };
    
    if (this.ishwscroll) {  
    // hw accelerated scroll
      this.doc.translate = {x:0,y:0,tx:"0px",ty:"0px"};
      
      //this one can help to enable hw accel on ios6 http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/
      if (cap.hastranslate3d&&cap.isios) this.doc.css("-webkit-backface-visibility","hidden");  // prevent flickering http://stackoverflow.com/questions/3461441/      
      
      //derived from http://stackoverflow.com/questions/11236090/
      function getMatrixValues() {
        var tr = self.doc.css(cap.trstyle);
        if (tr&&(tr.substr(0,6)=="matrix")) {
          return tr.replace(/^.*\((.*)\)$/g, "$1").replace(/px/g,'').split(/, +/);
        }
        return false;
      }
      
      this.getScrollTop = function(last) {
        if (!last) {
          var mtx = getMatrixValues();
          if (mtx) return (mtx.length==16) ? -mtx[13] : -mtx[5];  //matrix3d 16 on IE10
          if (self.timerscroll&&self.timerscroll.bz) return self.timerscroll.bz.getNow();
        }
        return self.doc.translate.y;
      };

      this.getScrollLeft = function(last) {
        if (!last) {
          var mtx = getMatrixValues();          
          if (mtx) return (mtx.length==16) ? -mtx[12] : -mtx[4];  //matrix3d 16 on IE10
          if (self.timerscroll&&self.timerscroll.bh) return self.timerscroll.bh.getNow();
        }
        return self.doc.translate.x;
      };
      
      if (document.createEvent) {
        this.notifyScrollEvent = function(el) {
          var e = document.createEvent("UIEvents");
          e.initUIEvent("scroll", false, true, window, 1);
          el.dispatchEvent(e);
        };
      }
      else if (document.fireEvent) {
        this.notifyScrollEvent = function(el) {
          var e = document.createEventObject();
          el.fireEvent("onscroll");
          e.cancelBubble = true; 
        };
      }
      else {
        this.notifyScrollEvent = function(el,add) {}; //NOPE
      }
      
      if (cap.hastranslate3d&&self.opt.enabletranslate3d) {
        this.setScrollTop = function(val,silent) {
          self.doc.translate.y = val;
          self.doc.translate.ty = (val*-1)+"px";
          self.doc.css(cap.trstyle,"translate3d("+self.doc.translate.tx+","+self.doc.translate.ty+",0px)");          
          if (!silent) self.notifyScrollEvent(self.win[0]);
        };
        this.setScrollLeft = function(val,silent) {          
          self.doc.translate.x = val;
          self.doc.translate.tx = (val*-1)+"px";
          self.doc.css(cap.trstyle,"translate3d("+self.doc.translate.tx+","+self.doc.translate.ty+",0px)");          
          if (!silent) self.notifyScrollEvent(self.win[0]);
        };
      } else {
        this.setScrollTop = function(val,silent) {
          self.doc.translate.y = val;
          self.doc.translate.ty = (val*-1)+"px";
          self.doc.css(cap.trstyle,"translate("+self.doc.translate.tx+","+self.doc.translate.ty+")");
          if (!silent) self.notifyScrollEvent(self.win[0]);          
        };
        this.setScrollLeft = function(val,silent) {        
          self.doc.translate.x = val;
          self.doc.translate.tx = (val*-1)+"px";
          self.doc.css(cap.trstyle,"translate("+self.doc.translate.tx+","+self.doc.translate.ty+")");
          if (!silent) self.notifyScrollEvent(self.win[0]);
        };
      }
    } else {
    // native scroll
      this.getScrollTop = function() {
        return self.docscroll.scrollTop();
      };
      this.setScrollTop = function(val) {        
        return self.docscroll.scrollTop(val);
      };
      this.getScrollLeft = function() {
        return self.docscroll.scrollLeft();
      };
      this.setScrollLeft = function(val) {
        return self.docscroll.scrollLeft(val);
      };
    }
    
    this.getTarget = function(e) {
      if (!e) return false;
      if (e.target) return e.target;
      if (e.srcElement) return e.srcElement;
      return false;
    };
    
    this.hasParent = function(e,id) {
      if (!e) return false;
      var el = e.target||e.srcElement||e||false;
      while (el && el.id != id) {
        el = el.parentNode||false;
      }
      return (el!==false);
    };
    
    function getZIndex() {
      var dom = self.win;
      if ("zIndex" in dom) return dom.zIndex();  // use jQuery UI method when available
      while (dom.length>0) {        
        if (dom[0].nodeType==9) return false;
        var zi = dom.css('zIndex');        
        if (!isNaN(zi)&&zi!=0) return parseInt(zi);
        dom = dom.parent();
      }
      return false;
    };
    
//inspired by http://forum.jquery.com/topic/width-includes-border-width-when-set-to-thin-medium-thick-in-ie
    var _convertBorderWidth = {"thin":1,"medium":3,"thick":5};
    function getWidthToPixel(dom,prop,chkheight) {
      var wd = dom.css(prop);
      var px = parseFloat(wd);
      if (isNaN(px)) {
        px = _convertBorderWidth[wd]||0;
        var brd = (px==3) ? ((chkheight)?(self.win.outerHeight() - self.win.innerHeight()):(self.win.outerWidth() - self.win.innerWidth())) : 1; //DON'T TRUST CSS
        if (self.isie8&&px) px+=1;
        return (brd) ? px : 0; 
      }
      return px;
    };
    
    this.getOffset = function() {
      if (self.isfixed) return {top:parseFloat(self.win.css('top')),left:parseFloat(self.win.css('left'))};
      if (!self.viewport) return self.win.offset();
      var ww = self.win.offset();
      var vp = self.viewport.offset();
      return {top:ww.top-vp.top+self.viewport.scrollTop(),left:ww.left-vp.left+self.viewport.scrollLeft()};
    };
    
    this.updateScrollBar = function(len) {
      if (self.ishwscroll) {
        self.rail.css({height:self.win.innerHeight()});
        if (self.railh) self.railh.css({width:self.win.innerWidth()});
      } else {
        var wpos = self.getOffset();
        var pos = {top:wpos.top,left:wpos.left};
        pos.top+= getWidthToPixel(self.win,'border-top-width',true);
        var brd = (self.win.outerWidth() - self.win.innerWidth())/2;
        pos.left+= (self.rail.align) ? self.win.outerWidth() - getWidthToPixel(self.win,'border-right-width') - self.rail.width : getWidthToPixel(self.win,'border-left-width');
        
        var off = self.opt.railoffset;
        if (off) {
          if (off.top) pos.top+=off.top;
          if (self.rail.align&&off.left) pos.left+=off.left;
        }
        
				if (!self.locked) self.rail.css({top:pos.top,left:pos.left,height:(len)?len.h:self.win.innerHeight()});
				
				if (self.zoom) {				  
				  self.zoom.css({top:pos.top+1,left:(self.rail.align==1) ? pos.left-20 : pos.left+self.rail.width+4});
			  }
				
				if (self.railh&&!self.locked) {
					var pos = {top:wpos.top,left:wpos.left};
					var y = (self.railh.align) ? pos.top + getWidthToPixel(self.win,'border-top-width',true) + self.win.innerHeight() - self.railh.height : pos.top + getWidthToPixel(self.win,'border-top-width',true);
					var x = pos.left + getWidthToPixel(self.win,'border-left-width');
					self.railh.css({top:y,left:x,width:self.railh.width});
				}
		
				
      }
    };
    
    this.doRailClick = function(e,dbl,hr) {

      var fn,pg,cur,pos;
      
//      if (self.rail.drag&&self.rail.drag.pt!=1) return;
      if (self.locked) return;
//      if (self.rail.drag) return;

//      self.cancelScroll();       
      
      self.cancelEvent(e);
      
      if (dbl) {
        fn = (hr) ? self.doScrollLeft : self.doScrollTop;
        cur = (hr) ? ((e.pageX - self.railh.offset().left - (self.cursorwidth/2)) * self.scrollratio.x) : ((e.pageY - self.rail.offset().top - (self.cursorheight/2)) * self.scrollratio.y);
        fn(cur);
      } else {
//        console.log(e.pageY);
        fn = (hr) ? self.doScrollLeftBy : self.doScrollBy;
        cur = (hr) ? self.scroll.x : self.scroll.y;
        pos = (hr) ? e.pageX - self.railh.offset().left : e.pageY - self.rail.offset().top;
        pg = (hr) ? self.view.w : self.view.h;        
        (cur>=pos) ? fn(pg) : fn(-pg);
      }
    
    };
    
    self.hasanimationframe = (setAnimationFrame);
    self.hascancelanimationframe = (clearAnimationFrame);
    
    if (!self.hasanimationframe) {
      setAnimationFrame=function(fn){return setTimeout(fn,15-Math.floor((+new Date)/1000)%16)}; // 1000/60)};
      clearAnimationFrame=clearInterval;
    } 
    else if (!self.hascancelanimationframe) clearAnimationFrame=function(){self.cancelAnimationFrame=true};
    
    this.init = function() {

      self.saved.css = [];
      
      if (cap.isie7mobile) return true; // SORRY, DO NOT WORK!
      if (cap.isoperamini) return true; // SORRY, DO NOT WORK!
      
      if (cap.hasmstouch) self.css((self.ispage)?$("html"):self.win,{'-ms-touch-action':'none'});
      
      self.zindex = "auto";
      if (!self.ispage&&self.opt.zindex=="auto") {
        self.zindex = getZIndex()||"auto";
      } else {
        self.zindex = self.opt.zindex;
      }
      
      if (!self.ispage&&self.zindex!="auto") {
        if (self.zindex>globalmaxzindex) globalmaxzindex=self.zindex;
      }
      
      if (self.isie&&self.zindex==0&&self.opt.zindex=="auto") {  // fix IE auto == 0
        self.zindex="auto";
      }
      
/*      
      self.ispage = true;
      self.haswrapper = true;
//      self.win = $(window);
      self.docscroll = $("body");
//      self.doc = $("body");
*/
      
      if (!self.ispage || (!cap.cantouch && !cap.isieold && !cap.isie9mobile)) {
      
        var cont = self.docscroll;
        if (self.ispage) cont = (self.haswrapper)?self.win:self.doc;
        
        if (!cap.isie9mobile) self.css(cont,{'overflow-y':'hidden'});      
        
        if (self.ispage&&cap.isie7) {
          if (self.doc[0].nodeName=='BODY') self.css($("html"),{'overflow-y':'hidden'});  //IE7 double scrollbar issue
          else if (self.doc[0].nodeName=='HTML') self.css($("body"),{'overflow-y':'hidden'});  //IE7 double scrollbar issue
        }
        
        if (cap.isios&&!self.ispage&&!self.haswrapper) self.css($("body"),{"-webkit-overflow-scrolling":"touch"});  //force hw acceleration
        
        var cursor = $(document.createElement('div'));
        cursor.css({
          position:"relative",top:0,"float":"right",width:self.opt.cursorwidth,height:"0px",
          'background-color':self.opt.cursorcolor,
          border:self.opt.cursorborder,
          'background-clip':'padding-box',
          '-webkit-border-radius':self.opt.cursorborderradius,
          '-moz-border-radius':self.opt.cursorborderradius,
          'border-radius':self.opt.cursorborderradius
        });   
        
        cursor.hborder = parseFloat(cursor.outerHeight() - cursor.innerHeight());        
        self.cursor = cursor;        
        
        var rail = $(document.createElement('div'));
        rail.attr('id',self.id);
        rail.addClass('nicescroll-rails');
        
        var v,a,kp = ["left","right"];  //"top","bottom"
        for(var n in kp) {
          a=kp[n];
          v = self.opt.railpadding[a];
          (v) ? rail.css("padding-"+a,v+"px") : self.opt.railpadding[a] = 0;
        }
        
        rail.append(cursor);
        
        rail.width = Math.max(parseFloat(self.opt.cursorwidth),cursor.outerWidth()) + self.opt.railpadding['left'] + self.opt.railpadding['right'];
        rail.css({width:rail.width+"px",'zIndex':self.zindex,"background":self.opt.background,cursor:"default"});        
        
        rail.visibility = true;
        rail.scrollable = true;
        
        rail.align = (self.opt.railalign=="left") ? 0 : 1;
        
        self.rail = rail;
        
        self.rail.drag = false;
        
        var zoom = false;
        if (self.opt.boxzoom&&!self.ispage&&!cap.isieold) {
          zoom = document.createElement('div');          
          self.bind(zoom,"click",self.doZoom);
          self.zoom = $(zoom);
          self.zoom.css({"cursor":"pointer",'z-index':self.zindex,'backgroundImage':'url('+scriptpath+'zoomico.png)','height':18,'width':18,'backgroundPosition':'0px 0px'});
          if (self.opt.dblclickzoom) self.bind(self.win,"dblclick",self.doZoom);
          if (cap.cantouch&&self.opt.gesturezoom) {
            self.ongesturezoom = function(e) {
              if (e.scale>1.5) self.doZoomIn(e);
              if (e.scale<0.8) self.doZoomOut(e);
              return self.cancelEvent(e);
            };
            self.bind(self.win,"gestureend",self.ongesturezoom);             
          }
        }
        
// init HORIZ

        self.railh = false;

        if (self.opt.horizrailenabled) {

          self.css(cont,{'overflow-x':'hidden'});

          var cursor = $(document.createElement('div'));
          cursor.css({
            position:"relative",top:0,height:self.opt.cursorwidth,width:"0px",
            'background-color':self.opt.cursorcolor,
            border:self.opt.cursorborder,
            'background-clip':'padding-box',
            '-webkit-border-radius':self.opt.cursorborderradius,
            '-moz-border-radius':self.opt.cursorborderradius,
            'border-radius':self.opt.cursorborderradius
          });   
          
          cursor.wborder = parseFloat(cursor.outerWidth() - cursor.innerWidth());
          self.cursorh = cursor;
          
          var railh = $(document.createElement('div'));
          railh.attr('id',self.id+'-hr');
          railh.addClass('nicescroll-rails');
          railh.height = Math.max(parseFloat(self.opt.cursorwidth),cursor.outerHeight());
          railh.css({height:railh.height+"px",'zIndex':self.zindex,"background":self.opt.background});
          
          railh.append(cursor);
          
          railh.visibility = true;
          railh.scrollable = true;
          
          railh.align = (self.opt.railvalign=="top") ? 0 : 1;
          
          self.railh = railh;
          
          self.railh.drag = false;
          
        }
        
//        
        
        if (self.ispage) {
          rail.css({position:"fixed",top:"0px",height:"100%"});
          (rail.align) ? rail.css({right:"0px"}) : rail.css({left:"0px"});
          self.body.append(rail);
          if (self.railh) {
            railh.css({position:"fixed",left:"0px",width:"100%"});
            (railh.align) ? railh.css({bottom:"0px"}) : railh.css({top:"0px"});
            self.body.append(railh);
          }
        } else {          
          if (self.ishwscroll) {
            if (self.win.css('position')=='static') self.css(self.win,{'position':'relative'});
            var bd = (self.win[0].nodeName == 'HTML') ? self.body : self.win;
            if (self.zoom) {
              self.zoom.css({position:"absolute",top:1,right:0,"margin-right":rail.width+4});
              bd.append(self.zoom);
            }
            rail.css({position:"absolute",top:0});
            (rail.align) ? rail.css({right:0}) : rail.css({left:0});
            bd.append(rail);
            if (railh) {
              railh.css({position:"absolute",left:0,bottom:0});
              (railh.align) ? railh.css({bottom:0}) : railh.css({top:0});
              bd.append(railh);
            }
          } else {
            self.isfixed = (self.win.css("position")=="fixed");
            var rlpos = (self.isfixed) ? "fixed" : "absolute";
            
            if (!self.isfixed) self.viewport = self.getViewport(self.win[0]);
            if (self.viewport) {
              self.body = self.viewport;              
              if ((/relative|absolute/.test(self.viewport.css("position")))==false) self.css(self.viewport,{"position":"relative"});
            }            
            
            rail.css({position:rlpos});
            if (self.zoom) self.zoom.css({position:rlpos});
            self.updateScrollBar();
            self.body.append(rail);
            if (self.zoom) self.body.append(self.zoom);
            if (self.railh) {
              railh.css({position:rlpos});
              self.body.append(railh);           
            }
          }
          
          if (cap.isios) self.css(self.win,{'-webkit-tap-highlight-color':'rgba(0,0,0,0)','-webkit-touch-callout':'none'});  // prevent grey layer on click
          
					if (cap.isie&&self.opt.disableoutline) self.win.attr("hideFocus","true");  // IE, prevent dotted rectangle on focused div
					if (cap.iswebkit&&self.opt.disableoutline) self.win.css({"outline":"none"});
//          if (cap.isopera&&self.opt.disableoutline) self.win.css({"outline":"0"});  // Opera to test [TODO]
          
        }
        
        if (self.opt.autohidemode===false) {
          self.autohidedom = false;
          self.rail.css({opacity:self.opt.cursoropacitymax});          
          if (self.railh) self.railh.css({opacity:self.opt.cursoropacitymax});
        }
        else if (self.opt.autohidemode===true) {
          self.autohidedom = $().add(self.rail);          
          if (cap.isie8) self.autohidedom=self.autohidedom.add(self.cursor);
          if (self.railh) self.autohidedom=self.autohidedom.add(self.railh);
          if (self.railh&&cap.isie8) self.autohidedom=self.autohidedom.add(self.cursorh);
        }
        else if (self.opt.autohidemode=="scroll") {
          self.autohidedom = $().add(self.rail);
          if (self.railh) self.autohidedom=self.autohidedom.add(self.railh);
        }
        else if (self.opt.autohidemode=="cursor") {
          self.autohidedom = $().add(self.cursor);
          if (self.railh) self.autohidedom=self.autohidedom.add(self.cursorh);
        }
        else if (self.opt.autohidemode=="hidden") {
          self.autohidedom = false;
          self.hide();
          self.locked = false;
        }
        
        if (cap.isie9mobile) {

          self.scrollmom = new ScrollMomentumClass2D(self);        

          /*
          var trace = function(msg) {
            var db = $("#debug");
            if (isNaN(msg)&&(typeof msg != "string")) {
              var x = [];
              for(var a in msg) {
                x.push(a+":"+msg[a]);
              }
              msg ="{"+x.join(",")+"}";
            }
            if (db.children().length>0) {
              db.children().eq(0).before("<div>"+msg+"</div>");
            } else {
              db.append("<div>"+msg+"</div>");
            }
          }
          window.onerror = function(msg,url,ln) {
            trace("ERR: "+msg+" at "+ln);
          }
*/          
  
          self.onmangotouch = function(e) {
            var py = self.getScrollTop();
            var px = self.getScrollLeft();
            
            if ((py == self.scrollmom.lastscrolly)&&(px == self.scrollmom.lastscrollx)) return true;
//            $("#debug").html('DRAG:'+py);

            var dfy = py-self.mangotouch.sy;
            var dfx = px-self.mangotouch.sx;            
            var df = Math.round(Math.sqrt(Math.pow(dfx,2)+Math.pow(dfy,2)));            
            if (df==0) return;
            
            var dry = (dfy<0)?-1:1;
            var drx = (dfx<0)?-1:1;
            
            var tm = +new Date();
            if (self.mangotouch.lazy) clearTimeout(self.mangotouch.lazy);
            
            if (((tm-self.mangotouch.tm)>80)||(self.mangotouch.dry!=dry)||(self.mangotouch.drx!=drx)) {
//              trace('RESET+'+(tm-self.mangotouch.tm));
              self.scrollmom.stop();
              self.scrollmom.reset(px,py);
              self.mangotouch.sy = py;
              self.mangotouch.ly = py;
              self.mangotouch.sx = px;
              self.mangotouch.lx = px;
              self.mangotouch.dry = dry;
              self.mangotouch.drx = drx;
              self.mangotouch.tm = tm;
            } else {
              
              self.scrollmom.stop();
              self.scrollmom.update(self.mangotouch.sx-dfx,self.mangotouch.sy-dfy);
              var gap = tm - self.mangotouch.tm;              
              self.mangotouch.tm = tm;
              
//              trace('MOVE:'+df+" - "+gap);
              
              var ds = Math.max(Math.abs(self.mangotouch.ly-py),Math.abs(self.mangotouch.lx-px));
              self.mangotouch.ly = py;
              self.mangotouch.lx = px;
              
              if (ds>2) {
                self.mangotouch.lazy = setTimeout(function(){
//                  trace('END:'+ds+'+'+gap);                  
                  self.mangotouch.lazy = false;
                  self.mangotouch.dry = 0;
                  self.mangotouch.drx = 0;
                  self.mangotouch.tm = 0;                  
                  self.scrollmom.doMomentum(30);
                },100);
              }
            }
          };
          
          var top = self.getScrollTop();
          var lef = self.getScrollLeft();
          self.mangotouch = {sy:top,ly:top,dry:0,sx:lef,lx:lef,drx:0,lazy:false,tm:0};
          
          self.bind(self.docscroll,"scroll",self.onmangotouch);
        
        } else {
        
          if (cap.cantouch||self.istouchcapable||self.opt.touchbehavior||cap.hasmstouch) {
          
            self.scrollmom = new ScrollMomentumClass2D(self);
          
            self.ontouchstart = function(e) {
              if (e.pointerType&&e.pointerType!=2) return false;
              
              if (!self.locked) {
              
                if (cap.hasmstouch) {
                  var tg = (e.target) ? e.target : false;
                  while (tg) {
                    var nc = $(tg).getNiceScroll();
                    if ((nc.length>0)&&(nc[0].me == self.me)) break;
                    if (nc.length>0) return false;
                    if ((tg.nodeName=='DIV')&&(tg.id==self.id)) break;
                    tg = (tg.parentNode) ? tg.parentNode : false;
                  }
                }
              
                self.cancelScroll();
                
                var tg = self.getTarget(e);
                
                if (tg) {
                  var skp = (/INPUT/i.test(tg.nodeName))&&(/range/i.test(tg.type));
                  if (skp) return self.stopPropagation(e);
                }
                
                if (!("clientX" in e) && ("changedTouches" in e)) {
                  e.clientX = e.changedTouches[0].clientX;
                  e.clientY = e.changedTouches[0].clientY;
                }
                
                if (self.forcescreen) {
                  var le = e;
                  var e = {"original":(e.original)?e.original:e};
                  e.clientX = le.screenX;
                  e.clientY = le.screenY;    
                }
                
                self.rail.drag = {x:e.clientX,y:e.clientY,sx:self.scroll.x,sy:self.scroll.y,st:self.getScrollTop(),sl:self.getScrollLeft(),pt:2,dl:false};
                
                if (self.ispage||!self.opt.directionlockdeadzone) {
                  self.rail.drag.dl = "f";
                } else {
                
                  var view = {
                    w:$(window).width(),
                    h:$(window).height()
                  };
                  
                  var page = {
                    w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),
                    h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)
                  };
                  
                  var maxh = Math.max(0,page.h - view.h);
                  var maxw = Math.max(0,page.w - view.w);                
                
                  if (!self.rail.scrollable&&self.railh.scrollable) self.rail.drag.ck = (maxh>0) ? "v" : false;
                  else if (self.rail.scrollable&&!self.railh.scrollable) self.rail.drag.ck = (maxw>0) ? "h" : false;
                  else self.rail.drag.ck = false;
                  if (!self.rail.drag.ck) self.rail.drag.dl = "f";
                };
                
                if (self.opt.touchbehavior&&self.isiframe&&cap.isie) {
                  var wp = self.win.position();
                  self.rail.drag.x+=wp.left;
                  self.rail.drag.y+=wp.top;
                };
                
                self.hasmoving = false;
                self.lastmouseup = false;
                self.scrollmom.reset(e.clientX,e.clientY);
                if (!cap.cantouch&&!this.istouchcapable&&!cap.hasmstouch) {
                  
                  var ip = (tg)?/INPUT|SELECT|TEXTAREA/i.test(tg.nodeName):false;
                  if (!ip) {
                    if (!self.ispage&&cap.hasmousecapture) tg.setCapture();                   
//                  return self.cancelEvent(e);
                    return (self.opt.touchbehavior) ? self.cancelEvent(e) : self.stopPropagation(e);
                  }
                  if (/SUBMIT|CANCEL|BUTTON/i.test($(tg).attr('type'))) {
                    pc = {"tg":tg,"click":false};
                    self.preventclick = pc;
                  }
                  
                }
              }
              
            };
            
            self.ontouchend = function(e) {
              if (e.pointerType&&e.pointerType!=2) return false;
              if (self.rail.drag&&(self.rail.drag.pt==2)) {
                self.scrollmom.doMomentum();
                self.rail.drag = false;
                if (self.hasmoving) {
                  self.hasmoving = false;
                  self.lastmouseup = true;
                  self.hideCursor();
                  if (cap.hasmousecapture) document.releaseCapture();
                  if (!cap.cantouch) return self.cancelEvent(e);
                }                            
              }                        
              
            };
            
            var moveneedoffset = (self.opt.touchbehavior&&self.isiframe&&!cap.hasmousecapture);
            
            self.ontouchmove = function(e,byiframe) {
              
              if (e.pointerType&&e.pointerType!=2) return false;
    
              if (self.rail.drag&&(self.rail.drag.pt==2)) {
                if (cap.cantouch&&(typeof e.original == "undefined")) return true;  // prevent ios "ghost" events by clickable elements
              
                self.hasmoving = true;

                if (self.preventclick&&!self.preventclick.click) {
                  self.preventclick.click = self.preventclick.tg.onclick||false;                
                  self.preventclick.tg.onclick = self.onpreventclick;
                }

                var ev = $.extend({"original":e},e);
                e = ev;
                
                if (("changedTouches" in e)) {
                  e.clientX = e.changedTouches[0].clientX;
                  e.clientY = e.changedTouches[0].clientY;
                }                
                
                if (self.forcescreen) {
                  var le = e;
                  var e = {"original":(e.original)?e.original:e};
                  e.clientX = le.screenX;
                  e.clientY = le.screenY;      
                }
                
                var ofx = ofy = 0;
                
                if (moveneedoffset&&!byiframe) {
                  var wp = self.win.position();
                  ofx=-wp.left;
                  ofy=-wp.top;
                }                
                
                var fy = e.clientY + ofy;
                var my = (fy-self.rail.drag.y);
                var fx = e.clientX + ofx;
                var mx = (fx-self.rail.drag.x);
                
                var ny = self.rail.drag.st-my;
                
                if (self.ishwscroll&&self.opt.bouncescroll) {
                  if (ny<0) {
                    ny = Math.round(ny/2);
//                    fy = 0;
                  }
                  else if (ny>self.page.maxh) {
                    ny = self.page.maxh+Math.round((ny-self.page.maxh)/2);
//                    fy = 0;
                  }
                } else {
                  if (ny<0) {ny=0;fy=0}
                  if (ny>self.page.maxh) {ny=self.page.maxh;fy=0}
                }
                  
                if (self.railh&&self.railh.scrollable) {
                  var nx = self.rail.drag.sl-mx;
                  
                  if (self.ishwscroll&&self.opt.bouncescroll) {                  
                    if (nx<0) {
                      nx = Math.round(nx/2);
//                      fx = 0;
                    }
                    else if (nx>self.page.maxw) {
                      nx = self.page.maxw+Math.round((nx-self.page.maxw)/2);
//                      fx = 0;
                    }
                  } else {
                    if (nx<0) {nx=0;fx=0}
                    if (nx>self.page.maxw) {nx=self.page.maxw;fx=0}
                  }
                
                }
                
                var grabbed = false;
                if (self.rail.drag.dl) {
                  grabbed = true;
                  if (self.rail.drag.dl=="v") nx = self.rail.drag.sl;
                  else if (self.rail.drag.dl=="h") ny = self.rail.drag.st;                  
                } else {
                  var ay = Math.abs(my);
                  var ax = Math.abs(mx);
                  var dz = self.opt.directionlockdeadzone;
                  if (self.rail.drag.ck=="v") {    
                    if (ay>dz&&(ax<=(ay*0.3))) {
                      self.rail.drag = false;                      
                      return true;
                    }
                    else if (ax>dz) {
                      self.rail.drag.dl="f";                      
                      $("body").scrollTop($("body").scrollTop());  // stop iOS native scrolling (when active javascript has blocked)
                    }
                  }
                  else if (self.rail.drag.ck=="h") {
                    if (ax>dz&&(ay<=(ax*0.3))) {
                      self.rail.drag = false;                      
                      return true;
                    }
                    else if (ay>dz) {                      
                      self.rail.drag.dl="f";
                      $("body").scrollLeft($("body").scrollLeft());  // stop iOS native scrolling (when active javascript has blocked)
                    }
                  }  
                }
                
                self.synched("touchmove",function(){
                  if (self.rail.drag&&(self.rail.drag.pt==2)) {
                    if (self.prepareTransition) self.prepareTransition(0);
                    if (self.rail.scrollable) self.setScrollTop(ny);
                    self.scrollmom.update(fx,fy);
                    if (self.railh&&self.railh.scrollable) {
                      self.setScrollLeft(nx);
                      self.showCursor(ny,nx);
                    } else {
                      self.showCursor(ny);
                    }
                    if (cap.isie10) document.selection.clear();
                  }
                });
                
                if (cap.ischrome&&self.istouchcapable) grabbed=false;  //chrome touch emulation doesn't like!
                if (grabbed) return self.cancelEvent(e);
              }
              
            };
          
          }
          
          self.onmousedown = function(e,hronly) {    
            if (self.rail.drag&&self.rail.drag.pt!=1) return;
            if (self.locked) return self.cancelEvent(e);            
            self.cancelScroll();              
            self.rail.drag = {x:e.clientX,y:e.clientY,sx:self.scroll.x,sy:self.scroll.y,pt:1,hr:(!!hronly)};
            var tg = self.getTarget(e);
            if (!self.ispage&&cap.hasmousecapture) tg.setCapture();
            if (self.isiframe&&!cap.hasmousecapture) {
              self.saved["csspointerevents"] = self.doc.css("pointer-events");
              self.css(self.doc,{"pointer-events":"none"});
            }
            return self.cancelEvent(e);
          };
          
          self.onmouseup = function(e) {
            if (self.rail.drag) {
              if (cap.hasmousecapture) document.releaseCapture();
              if (self.isiframe&&!cap.hasmousecapture) self.doc.css("pointer-events",self.saved["csspointerevents"]);
              if(self.rail.drag.pt!=1)return;
              self.rail.drag = false;
              //if (!self.rail.active) self.hideCursor();
              return self.cancelEvent(e);
            }
          };        
          
          self.onmousemove = function(e) {
            if (self.rail.drag) {
              if(self.rail.drag.pt!=1)return;
              
              if (cap.ischrome&&e.which==0) return self.onmouseup(e);
              
              self.cursorfreezed = true;
                  
              if (self.rail.drag.hr) {
                self.scroll.x = self.rail.drag.sx + (e.clientX-self.rail.drag.x);
                if (self.scroll.x<0) self.scroll.x=0;
                var mw = self.scrollvaluemaxw;
                if (self.scroll.x>mw) self.scroll.x=mw;
              } else {                
                self.scroll.y = self.rail.drag.sy + (e.clientY-self.rail.drag.y);
                if (self.scroll.y<0) self.scroll.y=0;
                var my = self.scrollvaluemax;
                if (self.scroll.y>my) self.scroll.y=my;
              }
              
              self.synched('mousemove',function(){
                if (self.rail.drag&&(self.rail.drag.pt==1)) {
                  self.showCursor();
                  if (self.rail.drag.hr) self.doScrollLeft(Math.round(self.scroll.x*self.scrollratio.x),self.opt.cursordragspeed);
                  else self.doScrollTop(Math.round(self.scroll.y*self.scrollratio.y),self.opt.cursordragspeed);
                }
              });
              
              return self.cancelEvent(e);
            } 
/*              
            else {
              self.checkarea = true;
            }
*/              
          };          
         
          if (cap.cantouch||self.opt.touchbehavior) {
          
            self.onpreventclick = function(e) {
              if (self.preventclick) {
                self.preventclick.tg.onclick = self.preventclick.click;
                self.preventclick = false;            
                return self.cancelEvent(e);
              }
            };
          
//            self.onmousedown = self.ontouchstart;            
//            self.onmouseup = self.ontouchend;
//            self.onmousemove = self.ontouchmove;

            self.bind(self.win,"mousedown",self.ontouchstart);  // control content dragging

            self.onclick = (cap.isios) ? false : function(e) { 
              if (self.lastmouseup) {
                self.lastmouseup = false;
                return self.cancelEvent(e);
              } else {
                return true;
              }
            }; 
            
            if (self.opt.grabcursorenabled&&cap.cursorgrabvalue) {
              self.css((self.ispage)?self.doc:self.win,{'cursor':cap.cursorgrabvalue});            
              self.css(self.rail,{'cursor':cap.cursorgrabvalue});
            }
            
          } else {

            function checkSelectionScroll(e) {
              if (!self.selectiondrag) return;
              
              if (e) {
                var ww = self.win.outerHeight();
                var df = (e.pageY - self.selectiondrag.top);
                if (df>0&&df<ww) df=0;
                if (df>=ww) df-=ww;
                self.selectiondrag.df = df;                
              }
              if (self.selectiondrag.df==0) return;
              
              var rt = -Math.floor(self.selectiondrag.df/6)*2;              
//              self.doScrollTop(self.getScrollTop(true)+rt);
              self.doScrollBy(rt);
              
              self.debounced("doselectionscroll",function(){checkSelectionScroll()},50);
            }
            
            if ("getSelection" in document) {  // A grade - Major browsers
              self.hasTextSelected = function() {  
                return (document.getSelection().rangeCount>0);
              }
            } 
            else if ("selection" in document) {  //IE9-
              self.hasTextSelected = function() {
                return (document.selection.type != "None");
              }
            } 
            else {
              self.hasTextSelected = function() {  // no support
                return false;
              }
            }            
            
            self.onselectionstart = function(e) {
              if (self.ispage) return;
              self.selectiondrag = self.win.offset();
            };
            self.onselectionend = function(e) {
              self.selectiondrag = false;
            };
            self.onselectiondrag = function(e) {              
              if (!self.selectiondrag) return;
              if (self.hasTextSelected()) self.debounced("selectionscroll",function(){checkSelectionScroll(e)},250);
            };
            
            
          }
          
          if (cap.hasmstouch) {
            self.css(self.rail,{'-ms-touch-action':'none'});
            self.css(self.cursor,{'-ms-touch-action':'none'});
            
            self.bind(self.win,"MSPointerDown",self.ontouchstart);
            self.bind(document,"MSPointerUp",self.ontouchend);
            self.bind(document,"MSPointerMove",self.ontouchmove);
            self.bind(self.cursor,"MSGestureHold",function(e){e.preventDefault()});
            self.bind(self.cursor,"contextmenu",function(e){e.preventDefault()});
          };

          if (this.istouchcapable) {  //desktop with screen touch enabled
            self.bind(self.win,"touchstart",self.ontouchstart);
            self.bind(document,"touchend",self.ontouchend);
            self.bind(document,"touchcancel",self.ontouchend);
            self.bind(document,"touchmove",self.ontouchmove);            
          };
          
          self.bind(self.cursor,"mousedown",self.onmousedown);
          self.bind(self.cursor,"mouseup",self.onmouseup);

          if (self.railh) {
            self.bind(self.cursorh,"mousedown",function(e){self.onmousedown(e,true)});
            self.bind(self.cursorh,"mouseup",function(e){
              if (self.rail.drag&&self.rail.drag.pt==2) return;
              self.rail.drag = false;
              self.hasmoving = false;
              self.hideCursor();
              if (cap.hasmousecapture) document.releaseCapture();
              return self.cancelEvent(e);
            });
          };
		
          if (self.opt.cursordragontouch||!cap.cantouch&&!self.opt.touchbehavior) {

            self.rail.css({"cursor":"default"});
            self.railh&&self.railh.css({"cursor":"default"});          
          
            self.jqbind(self.rail,"mouseenter",function() {
              if (self.canshowonmouseevent) self.showCursor();
              self.rail.active = true;
            });
            self.jqbind(self.rail,"mouseleave",function() { 
              self.rail.active = false;
              if (!self.rail.drag) self.hideCursor();
            });
            
            if (self.opt.sensitiverail) {
              self.bind(self.rail,"click",function(e){self.doRailClick(e,false,false)});
              self.bind(self.rail,"dblclick",function(e){self.doRailClick(e,true,false)});
              self.bind(self.cursor,"click",function(e){self.cancelEvent(e)});
              self.bind(self.cursor,"dblclick",function(e){self.cancelEvent(e)});
            };

            if (self.railh) {
              self.jqbind(self.railh,"mouseenter",function() {
                if (self.canshowonmouseevent) self.showCursor();
                self.rail.active = true;
              });          
              self.jqbind(self.railh,"mouseleave",function() { 
                self.rail.active = false;
                if (!self.rail.drag) self.hideCursor();
              });
              
              if (self.opt.sensitiverail) {
                self.bind(self.railh, "click", function(e){self.doRailClick(e,false,true)});
                self.bind(self.railh, "dblclick", function(e){self.doRailClick(e, true, true) });
                self.bind(self.cursorh, "click", function (e) { self.cancelEvent(e) });
                self.bind(self.cursorh, "dblclick", function (e) { self.cancelEvent(e) });
              };
              
            }
          
          };
    
          if (!cap.cantouch&&!self.opt.touchbehavior) {

            self.bind((cap.hasmousecapture)?self.win:document,"mouseup",self.onmouseup);            
            self.bind(document,"mousemove",self.onmousemove);
            if (self.onclick) self.bind(document,"click",self.onclick);
            
            if (!self.ispage&&self.opt.enablescrollonselection) {
              self.bind(self.win[0],"mousedown",self.onselectionstart);
              self.bind(document,"mouseup",self.onselectionend);
              self.bind(self.cursor,"mouseup",self.onselectionend);
              if (self.cursorh) self.bind(self.cursorh,"mouseup",self.onselectionend);
              self.bind(document,"mousemove",self.onselectiondrag);
            }

						if (self.zoom) {
							self.jqbind(self.zoom,"mouseenter",function() {
								if (self.canshowonmouseevent) self.showCursor();
								self.rail.active = true;
							});          
							self.jqbind(self.zoom,"mouseleave",function() { 
								self.rail.active = false;
								if (!self.rail.drag) self.hideCursor();
							});
						}

          } else {
            
            self.bind((cap.hasmousecapture)?self.win:document,"mouseup",self.ontouchend);
            self.bind(document,"mousemove",self.ontouchmove);
            if (self.onclick) self.bind(document,"click",self.onclick);
            
            if (self.opt.cursordragontouch) {
              self.bind(self.cursor,"mousedown",self.onmousedown);
              self.bind(self.cursor,"mousemove",self.onmousemove);
              self.cursorh&&self.bind(self.cursorh,"mousedown",self.onmousedown);
              self.cursorh&&self.bind(self.cursorh,"mousemove",self.onmousemove);
            }
          
          }
						
					if (self.opt.enablemousewheel) {
						if (!self.isiframe) self.bind((cap.isie&&self.ispage) ? document : self.win /*self.docscroll*/ ,"mousewheel",self.onmousewheel);
						self.bind(self.rail,"mousewheel",self.onmousewheel);
						if (self.railh) self.bind(self.railh,"mousewheel",self.onmousewheelhr);
					}						
						
          if (!self.ispage&&!cap.cantouch&&!(/HTML|BODY/.test(self.win[0].nodeName))) {
            if (!self.win.attr("tabindex")) self.win.attr({"tabindex":tabindexcounter++});
            
            self.jqbind(self.win,"focus",function(e) {
              domfocus = (self.getTarget(e)).id||true;
              self.hasfocus = true;
              if (self.canshowonmouseevent) self.noticeCursor();
            });
            self.jqbind(self.win,"blur",function(e) {
              domfocus = false;
              self.hasfocus = false;
            });
            
            self.jqbind(self.win,"mouseenter",function(e) {
              mousefocus = (self.getTarget(e)).id||true;
              self.hasmousefocus = true;
              if (self.canshowonmouseevent) self.noticeCursor();
            });
            self.jqbind(self.win,"mouseleave",function() {
              mousefocus = false;
              self.hasmousefocus = false;
            });
            
          };
          
        }  // !ie9mobile
        
        //Thanks to http://www.quirksmode.org !!
        self.onkeypress = function(e) {
          if (self.locked&&self.page.maxh==0) return true;
          
          e = (e) ? e : window.e;
          var tg = self.getTarget(e);
          if (tg&&/INPUT|TEXTAREA|SELECT|OPTION/.test(tg.nodeName)) {
            var tp = tg.getAttribute('type')||tg.type||false;            
            if ((!tp)||!(/submit|button|cancel/i.tp)) return true;
          }
          
          if (self.hasfocus||(self.hasmousefocus&&!domfocus)||(self.ispage&&!domfocus&&!mousefocus)) {
            var key = e.keyCode;
            
            if (self.locked&&key!=27) return self.cancelEvent(e);

            var ctrl = e.ctrlKey||false;
            var shift = e.shiftKey || false;
            
            var ret = false;
            switch (key) {
              case 38:
              case 63233: //safari
                self.doScrollBy(24*3);
                ret = true;
                break;
              case 40:
              case 63235: //safari
                self.doScrollBy(-24*3);
                ret = true;
                break;
              case 37:
              case 63232: //safari
                if (self.railh) {
                  (ctrl) ? self.doScrollLeft(0) : self.doScrollLeftBy(24*3);
                  ret = true;
                }
                break;
              case 39:
              case 63234: //safari
                if (self.railh) {
                  (ctrl) ? self.doScrollLeft(self.page.maxw) : self.doScrollLeftBy(-24*3);
                  ret = true;
                }
                break;
              case 33:
              case 63276: // safari
                self.doScrollBy(self.view.h);
                ret = true;
                break;
              case 34:
              case 63277: // safari
                self.doScrollBy(-self.view.h);
                ret = true;
                break;
              case 36:
              case 63273: // safari                
                (self.railh&&ctrl) ? self.doScrollPos(0,0) : self.doScrollTo(0);
                ret = true;
                break;
              case 35:
              case 63275: // safari
                (self.railh&&ctrl) ? self.doScrollPos(self.page.maxw,self.page.maxh) : self.doScrollTo(self.page.maxh);
                ret = true;
                break;
              case 32:
                if (self.opt.spacebarenabled) {
                  (shift) ? self.doScrollBy(self.view.h) : self.doScrollBy(-self.view.h);
                  ret = true;
                }
                break;
              case 27: // ESC
                if (self.zoomactive) {
                  self.doZoom();
                  ret = true;
                }
                break;
            }
            if (ret) return self.cancelEvent(e);
          }
        };
        
        if (self.opt.enablekeyboard) self.bind(document,(cap.isopera&&!cap.isopera12)?"keypress":"keydown",self.onkeypress);
        
        self.bind(window,'resize',self.lazyResize);
        self.bind(window,'orientationchange',self.lazyResize);
        
        self.bind(window,"load",self.lazyResize);
		
        if (cap.ischrome&&!self.ispage&&!self.haswrapper) { //chrome void scrollbar bug - it persists in version 26
          var tmp=self.win.attr("style");
					var ww = parseFloat(self.win.css("width"))+1;
          self.win.css('width',ww);
          self.synched("chromefix",function(){self.win.attr("style",tmp)});
        };
        
        
// Trying a cross-browser implementation - good luck!

        self.onAttributeChange = function(e) {
          self.lazyResize(250);
        };
        
        if (!self.ispage&&!self.haswrapper) {
          // redesigned MutationObserver for Chrome18+/Firefox14+/iOS6+ with support for: remove div, add/remove content
          if (clsMutationObserver !== false) {
            self.observer = new clsMutationObserver(function(mutations) {            
              mutations.forEach(self.onAttributeChange);
            });
            self.observer.observe(self.win[0],{childList: true, characterData: false, attributes: true, subtree: false});
            
            self.observerremover = new clsMutationObserver(function(mutations) {
               mutations.forEach(function(mo){
                 if (mo.removedNodes.length>0) {
                   for (var dd in mo.removedNodes) {
                     if (mo.removedNodes[dd]==self.win[0]) return self.remove();
                   }
                 }
               });
            });
            self.observerremover.observe(self.win[0].parentNode,{childList: true, characterData: false, attributes: false, subtree: false});
            
          } else {        
            self.bind(self.win,(cap.isie&&!cap.isie9)?"propertychange":"DOMAttrModified",self.onAttributeChange);            
            if (cap.isie9) self.win[0].attachEvent("onpropertychange",self.onAttributeChange); //IE9 DOMAttrModified bug
            self.bind(self.win,"DOMNodeRemoved",function(e){
              if (e.target==self.win[0]) self.remove();
            });
          }
        };
        
//

        if (!self.ispage&&self.opt.boxzoom) self.bind(window,"resize",self.resizeZoom);
        if (self.istextarea) self.bind(self.win,"mouseup",self.lazyResize);
        
        self.checkrtlmode = true;
        self.lazyResize(30);
        
      };
      
      if (this.doc[0].nodeName == 'IFRAME') {
        function oniframeload(e) {
          self.iframexd = false;
          try {
            var doc = 'contentDocument' in this ? this.contentDocument : this.contentWindow.document;
            var a = doc.domain;            
          } catch(e){self.iframexd = true;doc=false};
          
          if (self.iframexd) {
            if ("console" in window) console.log('NiceScroll error: policy restriced iframe');
            return true;  //cross-domain - I can't manage this        
          }
          
          self.forcescreen = true;
          
          if (self.isiframe) {            
            self.iframe = {
              "doc":$(doc),
              "html":self.doc.contents().find('html')[0],
              "body":self.doc.contents().find('body')[0]
            };
            self.getContentSize = function(){
              return {
                w:Math.max(self.iframe.html.scrollWidth,self.iframe.body.scrollWidth),
                h:Math.max(self.iframe.html.scrollHeight,self.iframe.body.scrollHeight)
              };
            };

            self.docscroll = $(self.iframe.body);//$(this.contentWindow);
          };
          
          if (!cap.isios&&self.opt.iframeautoresize&&!self.isiframe) {
            self.win.scrollTop(0); // reset position
            self.doc.height("");  //reset height to fix browser bug
            var hh=Math.max(doc.getElementsByTagName('html')[0].scrollHeight,doc.body.scrollHeight);
            self.doc.height(hh);          
          };

          self.lazyResize(30);
          
          if (cap.isie7) self.css($(self.iframe.html),{'overflow-y':'hidden'});
          //self.css($(doc.body),{'overflow-y':'hidden'});
          self.css($(self.iframe.body),{'overflow-y':'hidden'});
          
          if (cap.isios&&self.haswrapper) {
            self.css($(doc.body),{'-webkit-transform':'translate3d(0,0,0)'});  // avoid iFrame content clipping - thanks to http://blog.derraab.com/2012/04/02/avoid-iframe-content-clipping-with-css-transform-on-ios/
            
            console.log(1);
            
          }
          
          if ('contentWindow' in this) {
            self.bind(this.contentWindow,"scroll",self.onscroll);  //IE8 & minor
          } else {          
            self.bind(doc,"scroll",self.onscroll);
          }                    
          
          if (self.opt.enablemousewheel) {
            self.bind(doc,"mousewheel",self.onmousewheel);
          }
          
          if (self.opt.enablekeyboard) self.bind(doc,(cap.isopera)?"keypress":"keydown",self.onkeypress);
          
          if (cap.cantouch||self.opt.touchbehavior) {
            self.bind(doc,"mousedown",self.ontouchstart);
            self.bind(doc,"mousemove",function(e){self.ontouchmove(e,true)});
            if (self.opt.grabcursorenabled&&cap.cursorgrabvalue) self.css($(doc.body),{'cursor':cap.cursorgrabvalue});
          }
          
          self.bind(doc,"mouseup",self.ontouchend);
          
          if (self.zoom) {
            if (self.opt.dblclickzoom) self.bind(doc,'dblclick',self.doZoom);
            if (self.ongesturezoom) self.bind(doc,"gestureend",self.ongesturezoom);             
          }
        };
        
        if (this.doc[0].readyState&&this.doc[0].readyState=="complete"){
          setTimeout(function(){oniframeload.call(self.doc[0],false)},500);
        }
        self.bind(this.doc,"load",oniframeload);
        
      }
      
    };
    
    this.showCursor = function(py,px) {
      if (self.cursortimeout) {
        clearTimeout(self.cursortimeout);
        self.cursortimeout = 0;
      }
      if (!self.rail) return;
      if (self.autohidedom) {
        self.autohidedom.stop().css({opacity:self.opt.cursoropacitymax});
        self.cursoractive = true;
      }
      
      if (!self.rail.drag||self.rail.drag.pt!=1) {      
        if ((typeof py != "undefined")&&(py!==false)) {
          self.scroll.y = Math.round(py * 1/self.scrollratio.y);
        }
        if (typeof px != "undefined") {
          self.scroll.x = Math.round(px * 1/self.scrollratio.x);
        }
      }
      
      self.cursor.css({height:self.cursorheight,top:self.scroll.y}); 
      if (self.cursorh) {
        (!self.rail.align&&self.rail.visibility) ? self.cursorh.css({width:self.cursorwidth,left:self.scroll.x+self.rail.width}) : self.cursorh.css({width:self.cursorwidth,left:self.scroll.x});
        self.cursoractive = true;
      }
      
      if (self.zoom) self.zoom.stop().css({opacity:self.opt.cursoropacitymax});      
    };
    
    this.hideCursor = function(tm) {
      if (self.cursortimeout) return;
      if (!self.rail) return;
      if (!self.autohidedom) return;
      self.cursortimeout = setTimeout(function() {
         if (!self.rail.active||!self.showonmouseevent) {
           self.autohidedom.stop().animate({opacity:self.opt.cursoropacitymin});
           if (self.zoom) self.zoom.stop().animate({opacity:self.opt.cursoropacitymin});
           self.cursoractive = false;
         }
         self.cursortimeout = 0;
      },tm||self.opt.hidecursordelay);
    };
    
    this.noticeCursor = function(tm,py,px) {
      self.showCursor(py,px);
      if (!self.rail.active) self.hideCursor(tm);
    };
        
    this.getContentSize = 
      (self.ispage) ?
        function(){
          return {
            w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),
            h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)
          }
        }
      : (self.haswrapper) ?
        function(){
          return {
            w:self.doc.outerWidth()+parseInt(self.win.css('paddingLeft'))+parseInt(self.win.css('paddingRight')),
            h:self.doc.outerHeight()+parseInt(self.win.css('paddingTop'))+parseInt(self.win.css('paddingBottom'))
          }
        }
      : function() {        
        return {
          w:self.docscroll[0].scrollWidth,
          h:self.docscroll[0].scrollHeight
        };
      };
  
    this.onResize = function(e,page) {
    
	  if (!self.win) return false;
	
      if (!self.haswrapper&&!self.ispage) {
        if (self.win.css('display')=='none') {
          if (self.visibility) self.hideRail().hideRailHr();
          return false;
        } else {          
          if (!self.hidden&&!self.visibility) self.showRail().showRailHr();
        }        
      }
    
      var premaxh = self.page.maxh;
      var premaxw = self.page.maxw;

      var preview = {h:self.view.h,w:self.view.w};   
      
      self.view = {
        w:(self.ispage) ? self.win.width() : parseInt(self.win[0].clientWidth),
        h:(self.ispage) ? self.win.height() : parseInt(self.win[0].clientHeight)
      };
      
      self.page = (page) ? page : self.getContentSize();
      
      self.page.maxh = Math.max(0,self.page.h - self.view.h);
      self.page.maxw = Math.max(0,self.page.w - self.view.w);
      
      if ((self.page.maxh==premaxh)&&(self.page.maxw==premaxw)&&(self.view.w==preview.w)) {
        // test position        
        if (!self.ispage) {
          var pos = self.win.offset();
          if (self.lastposition) {
            var lst = self.lastposition;
            if ((lst.top==pos.top)&&(lst.left==pos.left)) return self; //nothing to do            
          }
          self.lastposition = pos;
        } else {
          return self; //nothing to do
        }
      }
      
      if (self.page.maxh==0) {
        self.hideRail();        
        self.scrollvaluemax = 0;
        self.scroll.y = 0;
        self.scrollratio.y = 0;
        self.cursorheight = 0;
        self.setScrollTop(0);
        self.rail.scrollable = false;
      } else {       
        self.rail.scrollable = true;
      }
      
      if (self.page.maxw==0) {
        self.hideRailHr();
        self.scrollvaluemaxw = 0;
        self.scroll.x = 0;
        self.scrollratio.x = 0;
        self.cursorwidth = 0;
        self.setScrollLeft(0);
        self.railh.scrollable = false;
      } else {        
        self.railh.scrollable = true;
      }
  
      self.locked = (self.page.maxh==0)&&(self.page.maxw==0);
      if (self.locked) {
				if (!self.ispage) self.updateScrollBar(self.view);
			  return false;
		  }

      if (!self.hidden&&!self.visibility) {
        self.showRail().showRailHr();
      }      
      else if (!self.hidden&&!self.railh.visibility) self.showRailHr();
      
      if (self.istextarea&&self.win.css('resize')&&self.win.css('resize')!='none') self.view.h-=20;      

      self.cursorheight = Math.min(self.view.h,Math.round(self.view.h * (self.view.h / self.page.h)));
      self.cursorheight = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight,self.cursorheight);

      self.cursorwidth = Math.min(self.view.w,Math.round(self.view.w * (self.view.w / self.page.w)));
      self.cursorwidth = (self.opt.cursorfixedheight) ? self.opt.cursorfixedheight : Math.max(self.opt.cursorminheight,self.cursorwidth);
      
      self.scrollvaluemax = self.view.h-self.cursorheight-self.cursor.hborder;
      
      if (self.railh) {
        self.railh.width = (self.page.maxh>0) ? (self.view.w-self.rail.width) : self.view.w;
        self.scrollvaluemaxw = self.railh.width-self.cursorwidth-self.cursorh.wborder;
      }
      
      if (self.checkrtlmode&&self.railh) {
        self.checkrtlmode = false;
        if (self.opt.rtlmode&&self.scroll.x==0) self.setScrollLeft(self.page.maxw);
      }
      
      if (!self.ispage) self.updateScrollBar(self.view);
      
      self.scrollratio = {
        x:(self.page.maxw/self.scrollvaluemaxw),
        y:(self.page.maxh/self.scrollvaluemax)
      };
     
      var sy = self.getScrollTop();
      if (sy>self.page.maxh) {
        self.doScrollTop(self.page.maxh);
      } else {     
        self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));
        self.scroll.x = Math.round(self.getScrollLeft() * (1/self.scrollratio.x));
        if (self.cursoractive) self.noticeCursor();     
      }      
      
      if (self.scroll.y&&(self.getScrollTop()==0)) self.doScrollTo(Math.floor(self.scroll.y*self.scrollratio.y));
      
      return self;
    };
    
    this.resize = self.onResize;
    
    this.lazyResize = function(tm) {   // event debounce
      tm = (isNaN(tm)) ? 30 : tm;
      self.delayed('resize',self.resize,tm);
      return self;
    };
   
// modified by MDN https://developer.mozilla.org/en-US/docs/DOM/Mozilla_event_reference/wheel
    function _modernWheelEvent(dom,name,fn,bubble) {      
      self._bind(dom,name,function(e){
        var  e = (e) ? e : window.event;
        var event = {
          original: e,
          target: e.target || e.srcElement,
          type: "wheel",
          deltaMode: e.type == "MozMousePixelScroll" ? 0 : 1,
          deltaX: 0,
          deltaZ: 0,
          preventDefault: function() {
            e.preventDefault ? e.preventDefault() : e.returnValue = false;
            return false;
          },
          stopImmediatePropagation: function() {
            (e.stopImmediatePropagation) ? e.stopImmediatePropagation() : e.cancelBubble = true;
          }
        };
            
        if (name=="mousewheel") {
          event.deltaY = - 1/40 * e.wheelDelta;
          e.wheelDeltaX && (event.deltaX = - 1/40 * e.wheelDeltaX);
        } else {
          event.deltaY = e.detail;
        }

        return fn.call(dom,event);      
      },bubble);
    };     
   
    this._bind = function(el,name,fn,bubble) {  // primitive bind
      self.events.push({e:el,n:name,f:fn,b:bubble,q:false});
      if (el.addEventListener) {
        el.addEventListener(name,fn,bubble||false);
      }
      else if (el.attachEvent) {
        el.attachEvent("on"+name,fn);
      }
      else {
        el["on"+name] = fn;        
      }        
    };
   
    this.jqbind = function(dom,name,fn) {  // use jquery bind for non-native events (mouseenter/mouseleave)
      self.events.push({e:dom,n:name,f:fn,q:true});
      $(dom).bind(name,fn);
    };
   
    this.bind = function(dom,name,fn,bubble) {  // touch-oriented & fixing jquery bind
      var el = ("jquery" in dom) ? dom[0] : dom;
      if (el == undefined) {
        el = dom;
      }

      if (name=='mousewheel') {
        if ("onwheel" in self.win) {            
          self._bind(el,"wheel",fn,bubble||false);
        } else {            
          var wname = (typeof document.onmousewheel != "undefined") ? "mousewheel" : "DOMMouseScroll";  // older IE/Firefox
          _modernWheelEvent(el,wname,fn,bubble||false);
          if (wname=="DOMMouseScroll") _modernWheelEvent(el,"MozMousePixelScroll",fn,bubble||false);  // Firefox legacy
        }
      } 
      else if (el.addEventListener) {
        if (cap.cantouch && /mouseup|mousedown|mousemove/.test(name)) {  // touch device support
          var tt=(name=='mousedown')?'touchstart':(name=='mouseup')?'touchend':'touchmove';
          self._bind(el,tt,function(e){
            if (e.touches) {
              if (e.touches.length<2) {var ev=(e.touches.length)?e.touches[0]:e;ev.original=e;fn.call(this,ev);}
            } 
            else if (e.changedTouches) {var ev=e.changedTouches[0];ev.original=e;fn.call(this,ev);}  //blackberry
          },bubble||false);
        }
        self._bind(el,name,fn,bubble||false);
        if (cap.cantouch && name=="mouseup") self._bind(el,"touchcancel",fn,bubble||false);
      }
      else {
        self._bind(el,name,function(e) {
          e = e||window.event||false;
          if (e) {
            if (e.srcElement) e.target=e.srcElement;
          }
          if (!("pageY" in e)) {
            e.pageX = e.clientX + document.documentElement.scrollLeft;
            e.pageY = e.clientY + document.documentElement.scrollTop; 
          }
          return ((fn.call(el,e)===false)||bubble===false) ? self.cancelEvent(e) : true;
        });
      } 
    };
    
    this._unbind = function(el,name,fn,bub) {  // primitive unbind
      if (el.removeEventListener) {
        el.removeEventListener(name,fn,bub);
      }
      else if (el.detachEvent) {
        el.detachEvent('on'+name,fn);
      } else {
        el['on'+name] = false;
      }
    };
    
    this.unbindAll = function() {
      for(var a=0;a<self.events.length;a++) {
        var r = self.events[a];        
        (r.q) ? r.e.unbind(r.n,r.f) : self._unbind(r.e,r.n,r.f,r.b);
      }
    };
    
    // Thanks to http://www.switchonthecode.com !!
    this.cancelEvent = function(e) {
      var e = (e.original) ? e.original : (e) ? e : window.event||false;
      if (!e) return false;      
      if(e.preventDefault) e.preventDefault();
      if(e.stopPropagation) e.stopPropagation();
      if(e.preventManipulation) e.preventManipulation();  //IE10
      e.cancelBubble = true;
      e.cancel = true;
      e.returnValue = false;
      return false;
    };

    this.stopPropagation = function(e) {
      var e = (e.original) ? e.original : (e) ? e : window.event||false;
      if (!e) return false;
      if (e.stopPropagation) return e.stopPropagation();
      if (e.cancelBubble) e.cancelBubble=true;
      return false;
    };
    
    this.showRail = function() {
      if ((self.page.maxh!=0)&&(self.ispage||self.win.css('display')!='none')) {
        self.visibility = true;
        self.rail.visibility = true;
        self.rail.css('display','block');
      }
      return self;
    };

    this.showRailHr = function() {
      if (!self.railh) return self;
      if ((self.page.maxw!=0)&&(self.ispage||self.win.css('display')!='none')) {
        self.railh.visibility = true;
        self.railh.css('display','block');
      };

      return self;
    };
    
    this.hideRail = function() {
      self.visibility = false;
      self.rail.visibility = false;
      self.rail.css('display','none');
      return self;
    };

    this.hideRailHr = function() {
      if (!self.railh) return self;
      self.railh.visibility = false;
      self.railh.css('display','none');
      return self;
    };
    
    this.show = function() {
      self.hidden = false;
      self.locked = false;
      return self.showRail().showRailHr();
    };

    this.hide = function() {
      self.hidden = true;
      self.locked = true;
      return self.hideRail().hideRailHr();
    };
    
    this.toggle = function() {
      return (self.hidden) ? self.show() : self.hide();
    };
    
    this.remove = function() {
      self.stop();
      if (self.cursortimeout) clearTimeout(self.cursortimeout);
      self.doZoomOut();
      self.unbindAll();     

      if (cap.isie9) self.win[0].detachEvent("onpropertychange",self.onAttributeChange); //IE9 DOMAttrModified bug
      
      if (self.observer !== false) self.observer.disconnect();
      if (self.observerremover !== false) self.observerremover.disconnect();      
      
      self.events = null;
      
      if (self.cursor) {
        self.cursor.remove();
      }
      if (self.cursorh) {
        self.cursorh.remove();
      }
      if (self.rail) {
        self.rail.remove();
      }
      if (self.railh) {
        self.railh.remove();
      }
      if (self.zoom) {
        self.zoom.remove();
      }
      for(var a=0;a<self.saved.css.length;a++) {
        var d=self.saved.css[a];
        d[0].css(d[1],(typeof d[2]=="undefined") ? '' : d[2]);
      }
      self.saved = false;      
      self.me.data('__nicescroll',''); //erase all traces
      
      // memory leak fixed by GianlucaGuarini - thanks a lot!
      // remove the current nicescroll from the $.nicescroll array & normalize array
      var lst = $.nicescroll;
      lst.each(function(i){
        if (!this) return;
        if(this.id === self.id) {
          delete lst[i];          
          for(var b=++i;b<lst.length;b++,i++) lst[i]=lst[b];
          lst.length--;
          if (lst.length) delete lst[lst.length];
        }
      });      
      
      for (var i in self) {
        self[i] = null;
        delete self[i];
      }
      
      self = null;
      
    };
    
    this.scrollstart = function(fn) {
      this.onscrollstart = fn;
      return self;
    };
    this.scrollend = function(fn) {
      this.onscrollend = fn;
      return self;
    };
    this.scrollcancel = function(fn) {
      this.onscrollcancel = fn;
      return self;
    };
    
    this.zoomin = function(fn) {
      this.onzoomin = fn;
      return self;
    };
    this.zoomout = function(fn) {
      this.onzoomout = fn;
      return self;
    };
    
    this.isScrollable = function(e) {      
      var dom = (e.target) ? e.target : e;
      if (dom.nodeName == 'OPTION') return true;
      while (dom&&(dom.nodeType==1)&&!(/BODY|HTML/.test(dom.nodeName))) {
        var dd = $(dom);
        var ov = dd.css('overflowY')||dd.css('overflowX')||dd.css('overflow')||'';
        if (/scroll|auto/.test(ov)) return (dom.clientHeight!=dom.scrollHeight);
        dom = (dom.parentNode) ? dom.parentNode : false;        
      }
      return false;
    };

    this.getViewport = function(me) {      
      var dom = (me&&me.parentNode) ? me.parentNode : false;
      while (dom&&(dom.nodeType==1)&&!(/BODY|HTML/.test(dom.nodeName))) {
        var dd = $(dom);
        var ov = dd.css('overflowY')||dd.css('overflowX')||dd.css('overflow')||'';
        if ((/scroll|auto/.test(ov))&&(dom.clientHeight!=dom.scrollHeight)) return dd;
        if (dd.getNiceScroll().length>0) return dd;
        dom = (dom.parentNode) ? dom.parentNode : false;
      }
      return false;
    };
    
    function execScrollWheel(e,hr,chkscroll) {
      var px,py;
      var rt = 1;
      
      if (e.deltaMode==0) {  // PIXEL
        px = -Math.floor(e.deltaX*(self.opt.mousescrollstep/(18*3)));
        py = -Math.floor(e.deltaY*(self.opt.mousescrollstep/(18*3)));
      }
      else if (e.deltaMode==1) {  // LINE
        px = -Math.floor(e.deltaX*self.opt.mousescrollstep);
        py = -Math.floor(e.deltaY*self.opt.mousescrollstep);
      }
      
      if (hr&&self.opt.oneaxismousemode&&(px==0)&&py) {  // classic vertical-only mousewheel + browser with x/y support 
        px = py;
        py = 0;
      }

      if (px) {
        if (self.scrollmom) {self.scrollmom.stop()}
        self.lastdeltax+=px;
        self.debounced("mousewheelx",function(){var dt=self.lastdeltax;self.lastdeltax=0;if(!self.rail.drag){self.doScrollLeftBy(dt)}},120);
      }
      if (py) {
        if (self.opt.nativeparentscrolling&&chkscroll&&!self.ispage&&!self.zoomactive) {
          if (py<0) {
            if (self.getScrollTop()>=self.page.maxh) return true;
          } else {
            if (self.getScrollTop()<=0) return true;
          }
        }
        if (self.scrollmom) {self.scrollmom.stop()}
        self.lastdeltay+=py;
        self.debounced("mousewheely",function(){var dt=self.lastdeltay;self.lastdeltay=0;if(!self.rail.drag){self.doScrollBy(dt)}},120);
      }
      
      e.stopImmediatePropagation();
      return e.preventDefault();
//      return self.cancelEvent(e);
    };
    
    this.onmousewheel = function(e) {          
      if (self.locked) {
        self.debounced("checkunlock",self.resize,250);
        return true;
      }
      if (self.rail.drag) return self.cancelEvent(e);
      
      if (self.opt.oneaxismousemode=="auto"&&e.deltaX!=0) self.opt.oneaxismousemode = false;  // check two-axis mouse support (not very elegant)
      
      if (self.opt.oneaxismousemode&&e.deltaX==0) {
        if (!self.rail.scrollable) {
          if (self.railh&&self.railh.scrollable) {
            return self.onmousewheelhr(e);
          } else {          
            return true;
          }
        }
      }
      
      var nw = +(new Date());
      var chk = false;
      if (self.opt.preservenativescrolling&&((self.checkarea+600)<nw)) {
//        self.checkarea = false;
        self.nativescrollingarea = self.isScrollable(e);
        chk = true;
      }
      self.checkarea = nw;
      if (self.nativescrollingarea) return true; // this isn't my business
//      if (self.locked) return self.cancelEvent(e);
      var ret = execScrollWheel(e,false,chk);
      if (ret) self.checkarea = 0;
      return ret;
    };

    this.onmousewheelhr = function(e) {
      if (self.locked||!self.railh.scrollable) return true;
      if (self.rail.drag) return self.cancelEvent(e);
      
      var nw = +(new Date());
      var chk = false;
      if (self.opt.preservenativescrolling&&((self.checkarea+600)<nw)) {
//        self.checkarea = false;
        self.nativescrollingarea = self.isScrollable(e); 
        chk = true;
      }
      self.checkarea = nw;
      if (self.nativescrollingarea) return true; // this isn't my business
      if (self.locked) return self.cancelEvent(e);

      return execScrollWheel(e,true,chk);
    };
    
    this.stop = function() {
      self.cancelScroll();
      if (self.scrollmon) self.scrollmon.stop();
      self.cursorfreezed = false;
      self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));      
      self.noticeCursor();
      return self;
    };
    
    this.getTransitionSpeed = function(dif) {
      var sp = Math.round(self.opt.scrollspeed*10);
      var ex = Math.min(sp,Math.round((dif / 20) * self.opt.scrollspeed));
      return (ex>20) ? ex : 0;
    };
    
    if (!self.opt.smoothscroll) {
      this.doScrollLeft = function(x,spd) {  //direct
        var y = self.getScrollTop();
        self.doScrollPos(x,y,spd);
      };
      this.doScrollTop = function(y,spd) {   //direct
        var x = self.getScrollLeft();
        self.doScrollPos(x,y,spd);
      };
      this.doScrollPos = function(x,y,spd) {  //direct
        var nx = (x>self.page.maxw) ? self.page.maxw : x;
        if (nx<0) nx=0;
        var ny = (y>self.page.maxh) ? self.page.maxh : y;
        if (ny<0) ny=0;
        self.synched('scroll',function(){
          self.setScrollTop(ny);
          self.setScrollLeft(nx);
        });
      };

      this.cancelScroll = function() {}; // direct
    } 
    else if (self.ishwscroll&&cap.hastransition&&self.opt.usetransition) {
      this.prepareTransition = function(dif,istime) {
        var ex = (istime) ? ((dif>20)?dif:0) : self.getTransitionSpeed(dif);        
        var trans = (ex) ? cap.prefixstyle+'transform '+ex+'ms ease-out' : '';
        if (!self.lasttransitionstyle||self.lasttransitionstyle!=trans) {
          self.lasttransitionstyle = trans;
          self.doc.css(cap.transitionstyle,trans);
        }
        return ex;
      };
      
      this.doScrollLeft = function(x,spd) {  //trans
        var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop();
        self.doScrollPos(x,y,spd);
      }; 
      
      this.doScrollTop = function(y,spd) {   //trans
        var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft();
        self.doScrollPos(x,y,spd);
      };
      
      this.doScrollPos = function(x,y,spd) {  //trans
   
        var py = self.getScrollTop();
        var px = self.getScrollLeft();        
      
        if (((self.newscrolly-py)*(y-py)<0)||((self.newscrollx-px)*(x-px)<0)) self.cancelScroll();  //inverted movement detection      
        
        if (self.opt.bouncescroll==false) {
          if (y<0) y=0;
          else if (y>self.page.maxh) y=self.page.maxh;
          if (x<0) x=0;
          else if (x>self.page.maxw) x=self.page.maxw;
        }
        
        if (self.scrollrunning&&x==self.newscrollx&&y==self.newscrolly) return false;
        
        self.newscrolly = y;
        self.newscrollx = x;
        
        self.newscrollspeed = spd||false;
        
        if (self.timer) return false;
        
        self.timer = setTimeout(function(){
        
          var top = self.getScrollTop();
          var lft = self.getScrollLeft();
          
          var dst = {};
          dst.x = x-lft;
          dst.y = y-top;
          dst.px = lft;
          dst.py = top;
          
          var dd = Math.round(Math.sqrt(Math.pow(dst.x,2)+Math.pow(dst.y,2)));          
          
//          var df = (self.newscrollspeed) ? self.newscrollspeed : dd;
          
          var ms = (self.newscrollspeed && self.newscrollspeed>1) ? self.newscrollspeed : self.getTransitionSpeed(dd);
          if (self.newscrollspeed&&self.newscrollspeed<=1) ms*=self.newscrollspeed;
          
          self.prepareTransition(ms,true);
          
          if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);    
          
          if (ms>0) {
          
            if (!self.scrollrunning&&self.onscrollstart) {
              var info = {"type":"scrollstart","current":{"x":lft,"y":top},"request":{"x":x,"y":y},"end":{"x":self.newscrollx,"y":self.newscrolly},"speed":ms};
              self.onscrollstart.call(self,info);
            }
            
            if (cap.transitionend) {
              if (!self.scrollendtrapped) {
                self.scrollendtrapped = true;
                self.bind(self.doc,cap.transitionend,self.onScrollEnd,false); //I have got to do something usefull!!
              }
            } else {              
              if (self.scrollendtrapped) clearTimeout(self.scrollendtrapped);
              self.scrollendtrapped = setTimeout(self.onScrollEnd,ms);  // simulate transitionend event
            }
            
            var py = top;
            var px = lft;
            self.timerscroll = {
              bz: new BezierClass(py,self.newscrolly,ms,0,0,0.58,1),
              bh: new BezierClass(px,self.newscrollx,ms,0,0,0.58,1)
            };            
            if (!self.cursorfreezed) self.timerscroll.tm=setInterval(function(){self.showCursor(self.getScrollTop(),self.getScrollLeft())},60);
            
          }
          
          self.synched("doScroll-set",function(){
            self.timer = 0;
            if (self.scrollendtrapped) self.scrollrunning = true;
            self.setScrollTop(self.newscrolly);
            self.setScrollLeft(self.newscrollx);
            if (!self.scrollendtrapped) self.onScrollEnd();
          });
          
          
        },50);
        
      };
      
      this.cancelScroll = function() {
        if (!self.scrollendtrapped) return true;        
        var py = self.getScrollTop();
        var px = self.getScrollLeft();
        self.scrollrunning = false;
        if (!cap.transitionend) clearTimeout(cap.transitionend);
        self.scrollendtrapped = false;
        self._unbind(self.doc,cap.transitionend,self.onScrollEnd);        
        self.prepareTransition(0);
        self.setScrollTop(py); // fire event onscroll
        if (self.railh) self.setScrollLeft(px);
        if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);
        self.timerscroll = false;
        
        self.cursorfreezed = false;

        //self.noticeCursor(false,py,px);
        self.showCursor(py,px);
        return self;
      };
      this.onScrollEnd = function() {                
        if (self.scrollendtrapped) self._unbind(self.doc,cap.transitionend,self.onScrollEnd);
        self.scrollendtrapped = false;        
        self.prepareTransition(0);
        if (self.timerscroll&&self.timerscroll.tm) clearInterval(self.timerscroll.tm);
        self.timerscroll = false;        
        var py = self.getScrollTop();
        var px = self.getScrollLeft();
        self.setScrollTop(py);  // fire event onscroll        
        if (self.railh) self.setScrollLeft(px);  // fire event onscroll left
        
        self.noticeCursor(false,py,px);     
        
        self.cursorfreezed = false;
        
        if (py<0) py=0;
        else if (py>self.page.maxh) py=self.page.maxh;
        if (px<0) px=0;
        else if (px>self.page.maxw) px=self.page.maxw;
        if((py!=self.newscrolly)||(px!=self.newscrollx)) return self.doScrollPos(px,py,self.opt.snapbackspeed);
        
        if (self.onscrollend&&self.scrollrunning) {
          var info = {"type":"scrollend","current":{"x":px,"y":py},"end":{"x":self.newscrollx,"y":self.newscrolly}};
          self.onscrollend.call(self,info);
        };

        self.scrollrunning = false;
        
      };

    } else {

      this.doScrollLeft = function(x,spd) {  //no-trans
        var y = (self.scrollrunning) ? self.newscrolly : self.getScrollTop();
        self.doScrollPos(x,y,spd);
      };

      this.doScrollTop = function(y,spd) {  //no-trans
        var x = (self.scrollrunning) ? self.newscrollx : self.getScrollLeft();
        self.doScrollPos(x,y,spd);
      };

      this.doScrollPos = function(x,y,spd) {  //no-trans
        var y = ((typeof y == "undefined")||(y===false)) ? self.getScrollTop(true) : y;
      
        if  ((self.timer)&&(self.newscrolly==y)&&(self.newscrollx==x)) return true;
      
        if (self.timer) clearAnimationFrame(self.timer);
        self.timer = 0;      

        var py = self.getScrollTop();
        var px = self.getScrollLeft();
        
        if (((self.newscrolly-py)*(y-py)<0)||((self.newscrollx-px)*(x-px)<0)) self.cancelScroll();  //inverted movement detection
        
        self.newscrolly = y;
        self.newscrollx = x;
        
        if (!self.bouncescroll||!self.rail.visibility) {
          if (self.newscrolly<0) {
            self.newscrolly = 0;
          }
          else if (self.newscrolly>self.page.maxh) {
            self.newscrolly = self.page.maxh;
          }
        }
        if (!self.bouncescroll||!self.railh.visibility) {
          if (self.newscrollx<0) {
            self.newscrollx = 0;
          }
          else if (self.newscrollx>self.page.maxw) {
            self.newscrollx = self.page.maxw;
          }
        }

        self.dst = {};
        self.dst.x = x-px;
        self.dst.y = y-py;
        self.dst.px = px;
        self.dst.py = py;
        
        var dst = Math.round(Math.sqrt(Math.pow(self.dst.x,2)+Math.pow(self.dst.y,2)));
        
        self.dst.ax = self.dst.x / dst;
        self.dst.ay = self.dst.y / dst;
        
        var pa = 0;
        var pe = dst;
        
        if (self.dst.x==0) {
          pa = py;
          pe = y;
          self.dst.ay = 1;
          self.dst.py = 0;
        } else if (self.dst.y==0) {
          pa = px;
          pe = x;
          self.dst.ax = 1;
          self.dst.px = 0;
        }

        var ms = self.getTransitionSpeed(dst);
        if (spd&&spd<=1) ms*=spd;
        if (ms>0) {
          self.bzscroll = (self.bzscroll) ? self.bzscroll.update(pe,ms) : new BezierClass(pa,pe,ms,0,1,0,1);
        } else {
          self.bzscroll = false;
        }
        
        if (self.timer) return;
        
        if ((py==self.page.maxh&&y>=self.page.maxh)||(px==self.page.maxw&&x>=self.page.maxw)) self.checkContentSize();
        
        var sync = 1;
        
        function scrolling() {          
          if (self.cancelAnimationFrame) return true;
          
          self.scrollrunning = true;
          
          sync = 1-sync;
          if (sync) return (self.timer = setAnimationFrame(scrolling)||1);

          var done = 0;
          
          var sc = sy = self.getScrollTop();
          if (self.dst.ay) {            
            sc = (self.bzscroll) ? self.dst.py + (self.bzscroll.getNow()*self.dst.ay) : self.newscrolly;
            var dr=sc-sy;          
            if ((dr<0&&sc<self.newscrolly)||(dr>0&&sc>self.newscrolly)) sc = self.newscrolly;
            self.setScrollTop(sc);
            if (sc == self.newscrolly) done=1;
          } else {
            done=1;
          }
          
          var scx = sx = self.getScrollLeft();
          if (self.dst.ax) {            
            scx = (self.bzscroll) ? self.dst.px + (self.bzscroll.getNow()*self.dst.ax) : self.newscrollx;            
            var dr=scx-sx;
            if ((dr<0&&scx<self.newscrollx)||(dr>0&&scx>self.newscrollx)) scx = self.newscrollx;
            self.setScrollLeft(scx);
            if (scx == self.newscrollx) done+=1;
          } else {
            done+=1;
          }
          
          if (done==2) {
            self.timer = 0;
            self.cursorfreezed = false;
            self.bzscroll = false;
            self.scrollrunning = false;
            if (sc<0) sc=0;
            else if (sc>self.page.maxh) sc=self.page.maxh;
            if (scx<0) scx=0;
            else if (scx>self.page.maxw) scx=self.page.maxw;
            if ((scx!=self.newscrollx)||(sc!=self.newscrolly)) self.doScrollPos(scx,sc);
            else {
              if (self.onscrollend) {
                var info = {"type":"scrollend","current":{"x":sx,"y":sy},"end":{"x":self.newscrollx,"y":self.newscrolly}};
                self.onscrollend.call(self,info);
              }             
            } 
          } else {
            self.timer = setAnimationFrame(scrolling)||1;
          }
        };
        self.cancelAnimationFrame=false;
        self.timer = 1;

        if (self.onscrollstart&&!self.scrollrunning) {
          var info = {"type":"scrollstart","current":{"x":px,"y":py},"request":{"x":x,"y":y},"end":{"x":self.newscrollx,"y":self.newscrolly},"speed":ms};
          self.onscrollstart.call(self,info);
        }        

        scrolling();
        
        if ((py==self.page.maxh&&y>=py)||(px==self.page.maxw&&x>=px)) self.checkContentSize();
        
        self.noticeCursor();
      };
  
      this.cancelScroll = function() {        
        if (self.timer) clearAnimationFrame(self.timer);
        self.timer = 0;
        self.bzscroll = false;
        self.scrollrunning = false;
        return self;
      };
      
    };
    
    this.doScrollBy = function(stp,relative) {
      var ny = 0;
      if (relative) {
        ny = Math.floor((self.scroll.y-stp)*self.scrollratio.y)
      } else {        
        var sy = (self.timer) ? self.newscrolly : self.getScrollTop(true);
        ny = sy-stp;
      }
      if (self.bouncescroll) {
        var haf = Math.round(self.view.h/2);
        if (ny<-haf) ny=-haf;
        else if (ny>(self.page.maxh+haf)) ny = (self.page.maxh+haf);
      }
      self.cursorfreezed = false;      

      py = self.getScrollTop(true);
      if (ny<0&&py<=0) return self.noticeCursor();      
      else if (ny>self.page.maxh&&py>=self.page.maxh) {
        self.checkContentSize();
        return self.noticeCursor();
      }
      
      self.doScrollTop(ny);
    };

    this.doScrollLeftBy = function(stp,relative) {
      var nx = 0;
      if (relative) {
        nx = Math.floor((self.scroll.x-stp)*self.scrollratio.x)
      } else {
        var sx = (self.timer) ? self.newscrollx : self.getScrollLeft(true);
        nx = sx-stp;
      }
      if (self.bouncescroll) {
        var haf = Math.round(self.view.w/2);
        if (nx<-haf) nx=-haf;
        else if (nx>(self.page.maxw+haf)) nx = (self.page.maxw+haf);
      }
      self.cursorfreezed = false;    

      px = self.getScrollLeft(true);
      if (nx<0&&px<=0) return self.noticeCursor();      
      else if (nx>self.page.maxw&&px>=self.page.maxw) return self.noticeCursor();
      
      self.doScrollLeft(nx);
    };
    
    this.doScrollTo = function(pos,relative) {
      var ny = (relative) ? Math.round(pos*self.scrollratio.y) : pos;
      if (ny<0) ny=0;
      else if (ny>self.page.maxh) ny = self.page.maxh;
      self.cursorfreezed = false;
      self.doScrollTop(pos);
    };
    
    this.checkContentSize = function() {      
      var pg = self.getContentSize();
      if ((pg.h!=self.page.h)||(pg.w!=self.page.w)) self.resize(false,pg);
    };
    
    self.onscroll = function(e) {    
      if (self.rail.drag) return;
      if (!self.cursorfreezed) {
        self.synched('scroll',function(){
          self.scroll.y = Math.round(self.getScrollTop() * (1/self.scrollratio.y));
          if (self.railh) self.scroll.x = Math.round(self.getScrollLeft() * (1/self.scrollratio.x));
          self.noticeCursor();
        });
      }
    };
    
    self.bind(self.docscroll,"scroll",self.onscroll);
    
    this.doZoomIn = function(e) {
      if (self.zoomactive) return;
      self.zoomactive = true;
      
      self.zoomrestore = {
        style:{}
      };
      var lst = ['position','top','left','zIndex','backgroundColor','marginTop','marginBottom','marginLeft','marginRight'];
      var win = self.win[0].style;
      for(var a in lst) {
        var pp = lst[a];
        self.zoomrestore.style[pp] = (typeof win[pp] != "undefined") ? win[pp] : '';        
      }
      
      self.zoomrestore.style.width = self.win.css('width');
      self.zoomrestore.style.height = self.win.css('height');
      
      self.zoomrestore.padding = {
        w:self.win.outerWidth()-self.win.width(),
        h:self.win.outerHeight()-self.win.height()
      };
      
      if (cap.isios4) {
        self.zoomrestore.scrollTop = $(window).scrollTop();
        $(window).scrollTop(0);
      }
      
      self.win.css({
        "position":(cap.isios4)?"absolute":"fixed",
        "top":0,
        "left":0,
        "z-index":globalmaxzindex+100,
        "margin":"0px"
      });
      var bkg = self.win.css("backgroundColor");      
      if (bkg==""||/transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(bkg)) self.win.css("backgroundColor","#fff");
      self.rail.css({"z-index":globalmaxzindex+101});
      self.zoom.css({"z-index":globalmaxzindex+102});      
      self.zoom.css('backgroundPosition','0px -18px');
      self.resizeZoom();
      
      if (self.onzoomin) self.onzoomin.call(self);
      
      return self.cancelEvent(e);
    };

    this.doZoomOut = function(e) {
      if (!self.zoomactive) return;
      self.zoomactive = false;
      
      self.win.css("margin","");
      self.win.css(self.zoomrestore.style);
      
      if (cap.isios4) {
        $(window).scrollTop(self.zoomrestore.scrollTop);
      }
      
      self.rail.css({"z-index":self.zindex});
      self.zoom.css({"z-index":self.zindex});
      self.zoomrestore = false;
      self.zoom.css('backgroundPosition','0px 0px');
      self.onResize();
      
      if (self.onzoomout) self.onzoomout.call(self);
      
      return self.cancelEvent(e);
    };
    
    this.doZoom = function(e) {
      return (self.zoomactive) ? self.doZoomOut(e) : self.doZoomIn(e);
    };
    
    this.resizeZoom = function() {
      if (!self.zoomactive) return;

      var py = self.getScrollTop(); //preserve scrolling position
      self.win.css({
        width:$(window).width()-self.zoomrestore.padding.w+"px",
        height:$(window).height()-self.zoomrestore.padding.h+"px"
      });
      self.onResize();
      
      self.setScrollTop(Math.min(self.page.maxh,py));
    };
   
    this.init();
    
    $.nicescroll.push(this);

  };
  
// Inspired by the work of Kin Blas
// http://webpro.host.adobe.com/people/jblas/momentum/includes/jquery.momentum.0.7.js  
  
  
  var ScrollMomentumClass2D = function(nc) {
    var self = this;
    this.nc = nc;
    
    this.lastx = 0;
    this.lasty = 0;
    this.speedx = 0;
    this.speedy = 0;
    this.lasttime = 0;
    this.steptime = 0;
    this.snapx = false;
    this.snapy = false;
    this.demulx = 0;
    this.demuly = 0;
    
    this.lastscrollx = -1;
    this.lastscrolly = -1;
    
    this.chkx = 0;
    this.chky = 0;
    
    this.timer = 0;
    
    this.time = function() {
      return +new Date();//beautifull hack
    };
    
    this.reset = function(px,py) {
      self.stop();
      var now = self.time();
      self.steptime = 0;
      self.lasttime = now;
      self.speedx = 0;
      self.speedy = 0;
      self.lastx = px;
      self.lasty = py;
      self.lastscrollx = -1;
      self.lastscrolly = -1;
    };
    
    this.update = function(px,py) {
      var now = self.time();
      self.steptime = now - self.lasttime;
      self.lasttime = now;      
      var dy = py - self.lasty;
      var dx = px - self.lastx;
      var sy = self.nc.getScrollTop();
      var sx = self.nc.getScrollLeft();
      var newy = sy + dy;
      var newx = sx + dx;
      self.snapx = (newx<0)||(newx>self.nc.page.maxw);
      self.snapy = (newy<0)||(newy>self.nc.page.maxh);
      self.speedx = dx;
      self.speedy = dy;
      self.lastx = px;
      self.lasty = py;
    };
    
    this.stop = function() {
      self.nc.unsynched("domomentum2d");
      if (self.timer) clearTimeout(self.timer);
      self.timer = 0;
      self.lastscrollx = -1;
      self.lastscrolly = -1;
    };
    
    this.doSnapy = function(nx,ny) {
      var snap = false;
      
      if (ny<0) {
        ny=0;
        snap=true;        
      } 
      else if (ny>self.nc.page.maxh) {
        ny=self.nc.page.maxh;
        snap=true;
      }

      if (nx<0) {
        nx=0;
        snap=true;        
      } 
      else if (nx>self.nc.page.maxw) {
        nx=self.nc.page.maxw;
        snap=true;
      }
      
      if (snap) self.nc.doScrollPos(nx,ny,self.nc.opt.snapbackspeed);
    };
    
    this.doMomentum = function(gp) {
      var t = self.time();
      var l = (gp) ? t+gp : self.lasttime;

      var sl = self.nc.getScrollLeft();
      var st = self.nc.getScrollTop();
      
      var pageh = self.nc.page.maxh;
      var pagew = self.nc.page.maxw;
      
      self.speedx = (pagew>0) ? Math.min(60,self.speedx) : 0;
      self.speedy = (pageh>0) ? Math.min(60,self.speedy) : 0;
      
      var chk = l && (t - l) <= 60;
      
      if ((st<0)||(st>pageh)||(sl<0)||(sl>pagew)) chk = false;
      
      var sy = (self.speedy && chk) ? self.speedy : false;
      var sx = (self.speedx && chk) ? self.speedx : false;
      
      if (sy||sx) {
        var tm = Math.max(16,self.steptime); //timeout granularity
        
        if (tm>50) {  // do smooth
          var xm = tm/50;
          self.speedx*=xm;
          self.speedy*=xm;
          tm = 50;
        }
        
        self.demulxy = 0;

        self.lastscrollx = self.nc.getScrollLeft();
        self.chkx = self.lastscrollx;
        self.lastscrolly = self.nc.getScrollTop();
        self.chky = self.lastscrolly;
        
        var nx = self.lastscrollx;
        var ny = self.lastscrolly;
        
        var onscroll = function(){
          var df = ((self.time()-t)>600) ? 0.04 : 0.02;
        
          if (self.speedx) {
            nx = Math.floor(self.lastscrollx - (self.speedx*(1-self.demulxy)));
            self.lastscrollx = nx;
            if ((nx<0)||(nx>pagew)) df=0.10;
          }

          if (self.speedy) {
            ny = Math.floor(self.lastscrolly - (self.speedy*(1-self.demulxy)));
            self.lastscrolly = ny;
            if ((ny<0)||(ny>pageh)) df=0.10;
          }
          
          self.demulxy = Math.min(1,self.demulxy+df);
          
          self.nc.synched("domomentum2d",function(){

            if (self.speedx) {
              var scx = self.nc.getScrollLeft();
              if (scx!=self.chkx) self.stop();
              self.chkx=nx;
              self.nc.setScrollLeft(nx);
            }
          
            if (self.speedy) {
              var scy = self.nc.getScrollTop();
              if (scy!=self.chky) self.stop();          
              self.chky=ny;
              self.nc.setScrollTop(ny);
            }
            
            if(!self.timer) {
              self.nc.hideCursor();
              self.doSnapy(nx,ny);
            }
            
          });
          
          if (self.demulxy<1) {            
            self.timer = setTimeout(onscroll,tm);
          } else {
            self.stop();
            self.nc.hideCursor();
            self.doSnapy(nx,ny);
          }
        };
        
        onscroll();
        
      } else {
        self.doSnapy(self.nc.getScrollLeft(),self.nc.getScrollTop());
      }      
      
    }
    
  };

  
// override jQuery scrollTop
 
  var _scrollTop = jQuery.fn.scrollTop; // preserve original function
   
  jQuery.cssHooks["pageYOffset"] = {
    get: function(elem,computed,extra) {      
      var nice = $.data(elem,'__nicescroll')||false;
      return (nice&&nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(elem);
    },
    set: function(elem,value) {
      var nice = $.data(elem,'__nicescroll')||false;    
      (nice&&nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call(elem,value);
      return this;
    }
  };
  
/*  
  $.fx.step["scrollTop"] = function(fx){    
    $.cssHooks["scrollTop"].set( fx.elem, fx.now + fx.unit );
  };
*/  
  
  jQuery.fn.scrollTop = function(value) {    
    if (typeof value == "undefined") {
      var nice = (this[0]) ? $.data(this[0],'__nicescroll')||false : false;
      return (nice&&nice.ishwscroll) ? nice.getScrollTop() : _scrollTop.call(this);
    } else {      
      return this.each(function() {
        var nice = $.data(this,'__nicescroll')||false;
        (nice&&nice.ishwscroll) ? nice.setScrollTop(parseInt(value)) : _scrollTop.call($(this),value);
      });
    }
  };

// override jQuery scrollLeft
 
  var _scrollLeft = jQuery.fn.scrollLeft; // preserve original function
   
  $.cssHooks.pageXOffset = {
    get: function(elem,computed,extra) {
      var nice = $.data(elem,'__nicescroll')||false;
      return (nice&&nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(elem);
    },
    set: function(elem,value) {
      var nice = $.data(elem,'__nicescroll')||false;    
      (nice&&nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call(elem,value);
      return this;
    }
  };
  
/*  
  $.fx.step["scrollLeft"] = function(fx){
    $.cssHooks["scrollLeft"].set( fx.elem, fx.now + fx.unit );
  };  
*/  
 
  jQuery.fn.scrollLeft = function(value) {    
    if (typeof value == "undefined") {
      var nice = (this[0]) ? $.data(this[0],'__nicescroll')||false : false;
      return (nice&&nice.ishwscroll) ? nice.getScrollLeft() : _scrollLeft.call(this);
    } else {
      return this.each(function() {     
        var nice = $.data(this,'__nicescroll')||false;
        (nice&&nice.ishwscroll) ? nice.setScrollLeft(parseInt(value)) : _scrollLeft.call($(this),value);
      });
    }
  };
  
  var NiceScrollArray = function(doms) {
    var self = this;
    this.length = 0;
    this.name = "nicescrollarray";
  
    this.each = function(fn) {
      for(var a=0,i=0;a<self.length;a++) fn.call(self[a],i++);
      return self;
    };
    
    this.push = function(nice) {
      self[self.length]=nice;
      self.length++;
    };
    
    this.eq = function(idx) {
      return self[idx];
    };
    
    if (doms) {
      for(a=0;a<doms.length;a++) {
        var nice = $.data(doms[a],'__nicescroll')||false;
        if (nice) {
          this[this.length]=nice;
          this.length++;
        }
      };
    }
    
    return this;
  };
  
  function mplex(el,lst,fn) {
    for(var a=0;a<lst.length;a++) fn(el,lst[a]);
  };  
  mplex(
    NiceScrollArray.prototype,
    ['show','hide','toggle','onResize','resize','remove','stop','doScrollPos'],
    function(e,n) {
      e[n] = function(){
        var args = arguments;
        return this.each(function(){          
          this[n].apply(this,args);
        });
      };
    }
  );  
  
  jQuery.fn.getNiceScroll = function(index) {
    if (typeof index == "undefined") {
      return new NiceScrollArray(this);
    } else {      
      var nice = this[index]&&$.data(this[index],'__nicescroll')||false;
      return nice;
    }
  };
  
  jQuery.extend(jQuery.expr[':'], {
    nicescroll: function(a) {
      return ($.data(a,'__nicescroll'))?true:false;
    }
  });  
  
  $.fn.niceScroll = function(wrapper,opt) {        
    if (typeof opt=="undefined") {
      if ((typeof wrapper=="object")&&!("jquery" in wrapper)) {
        opt = wrapper;
        wrapper = false;        
      }
    }
    var ret = new NiceScrollArray();
    if (typeof opt=="undefined") opt = {};
    
    if (wrapper||false) {      
      opt.doc = $(wrapper);
      opt.win = $(this);
    }    
    var docundef = !("doc" in opt);   
    if (!docundef&&!("win" in opt)) opt.win = $(this);    
    
    this.each(function() {
      var nice = $(this).data('__nicescroll')||false;
      if (!nice) {
        opt.doc = (docundef) ? $(this) : opt.doc;
        nice = new NiceScrollClass(opt,$(this));        
        $(this).data('__nicescroll',nice);
      }
      ret.push(nice);
    });
    return (ret.length==1) ? ret[0] : ret;
  };
  
  window.NiceScroll = {
    getjQuery:function(){return jQuery}
  };
  
  if (!$.nicescroll) {
   $.nicescroll = new NiceScrollArray();
   $.nicescroll.options = _globaloptions;
  }
  
})( jQuery );
  ;/*
 * jQuery FlexSlider v2.2.2
 * Copyright 2012 WooThemes
 * Contributing Author: Tyler Smith
 */
;
(function ($) {

  //FlexSlider: Object Instance
  $.flexslider = function(el, options) {
	var slider = $(el);

	// making variables public
	slider.vars = $.extend({}, $.flexslider.defaults, options);

	var namespace = slider.vars.namespace,
		msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
		touch = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch,
		// depricating this idea, as devices are being released with both of these events
		//eventType = (touch) ? "touchend" : "click",
		eventType = "click touchend MSPointerUp",
		watchedEvent = "",
		watchedEventClearTimer,
		vertical = slider.vars.direction === "vertical",
		reverse = slider.vars.reverse,
		carousel = (slider.vars.itemWidth > 0),
		fade = slider.vars.animation === "fade",
		asNav = slider.vars.asNavFor !== "",
		methods = {},
		focused = true;

	// Store a reference to the slider object
	$.data(el, "flexslider", slider);

	// Private slider methods
	methods = {
	  init: function() {
		slider.animating = false;
		// Get current slide and make sure it is a number
		slider.currentSlide = parseInt( ( slider.vars.startAt ? slider.vars.startAt : 0), 10 );
		if ( isNaN( slider.currentSlide ) ) slider.currentSlide = 0;
		slider.animatingTo = slider.currentSlide;
		slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last);
		slider.containerSelector = slider.vars.selector.substr(0,slider.vars.selector.search(' '));
		slider.slides = $(slider.vars.selector, slider);
		slider.container = $(slider.containerSelector, slider);
		slider.count = slider.slides.length;
		// SYNC:
		slider.syncExists = $(slider.vars.sync).length > 0;
		// SLIDE:
		if (slider.vars.animation === "slide") slider.vars.animation = "swing";
		slider.prop = (vertical) ? "top" : "marginLeft";
		slider.args = {};
		// SLIDESHOW:
		slider.manualPause = false;
		slider.stopped = false;
		//PAUSE WHEN INVISIBLE
		slider.started = false;
		slider.startTimeout = null;
		// TOUCH/USECSS:
		slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS && (function() {
		  var obj = document.createElement('div'),
			  props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
		  for (var i in props) {
			if ( obj.style[ props[i] ] !== undefined ) {
			  slider.pfx = props[i].replace('Perspective','').toLowerCase();
			  slider.prop = "-" + slider.pfx + "-transform";
			  return true;
			}
		  }
		  return false;
		}());
		slider.ensureAnimationEnd = '';
		// CONTROLSCONTAINER:
		if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer);
		// MANUAL:
		if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls);

		// RANDOMIZE:
		if (slider.vars.randomize) {
		  slider.slides.sort(function() { return (Math.round(Math.random())-0.5); });
		  slider.container.empty().append(slider.slides);
		}

		slider.doMath();

		// INIT
		slider.setup("init");

		// CONTROLNAV:
		if (slider.vars.controlNav) methods.controlNav.setup();

		// DIRECTIONNAV:
		if (slider.vars.directionNav) methods.directionNav.setup();

		// KEYBOARD:
		if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) {
		  $(document).bind('keyup', function(event) {
			var keycode = event.keyCode;
			if (!slider.animating && (keycode === 39 || keycode === 37)) {
			  var target = (keycode === 39) ? slider.getTarget('next') :
						   (keycode === 37) ? slider.getTarget('prev') : false;
			  slider.flexAnimate(target, slider.vars.pauseOnAction);
			}
		  });
		}
		// MOUSEWHEEL:
		if (slider.vars.mousewheel) {
		  slider.bind('mousewheel', function(event, delta, deltaX, deltaY) {
			event.preventDefault();
			var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev');
			slider.flexAnimate(target, slider.vars.pauseOnAction);
		  });
		}

		// PAUSEPLAY
		if (slider.vars.pausePlay) methods.pausePlay.setup();

		//PAUSE WHEN INVISIBLE
		if (slider.vars.slideshow && slider.vars.pauseInvisible) methods.pauseInvisible.init();

		// SLIDSESHOW
		if (slider.vars.slideshow) {
		  if (slider.vars.pauseOnHover) {
			slider.hover(function() {
			  if (!slider.manualPlay && !slider.manualPause) slider.pause();
			}, function() {
			  if (!slider.manualPause && !slider.manualPlay && !slider.stopped) slider.play();
			});
		  }
		  // initialize animation
		  //If we're visible, or we don't use PageVisibility API
		  if(!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) {
			(slider.vars.initDelay > 0) ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play();
		  }
		}

		// ASNAV:
		if (asNav) methods.asNav.setup();

		// TOUCH
		if (touch && slider.vars.touch) methods.touch();

		// FADE&&SMOOTHHEIGHT || SLIDE:
		if (!fade || (fade && slider.vars.smoothHeight)) $(window).bind("resize orientationchange focus", methods.resize);

		slider.find("img").attr("draggable", "false");

		// API: start() Callback
		setTimeout(function(){
		  slider.vars.start(slider);
		}, 200);
	  },
	  asNav: {
		setup: function() {
		  slider.asNav = true;
		  slider.animatingTo = Math.floor(slider.currentSlide/slider.move);
		  slider.currentItem = slider.currentSlide;
		  slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide");
		  if(!msGesture){
			  slider.slides.on(eventType, function(e){
				e.preventDefault();
				var $slide = $(this),
					target = $slide.index();
				var posFromLeft = $slide.offset().left - $(slider).scrollLeft(); // Find position of slide relative to left of slider container
				if( posFromLeft <= 0 && $slide.hasClass( namespace + 'active-slide' ) ) {
				  slider.flexAnimate(slider.getTarget("prev"), true);
				} else if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass(namespace + "active-slide")) {
				  slider.direction = (slider.currentItem < target) ? "next" : "prev";
				  slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true);
				}
			  });
		  }else{
			  el._slider = slider;
			  slider.slides.each(function (){
				  var that = this;
				  that._gesture = new MSGesture();
				  that._gesture.target = that;
				  that.addEventListener("MSPointerDown", function (e){
					  e.preventDefault();
					  if(e.currentTarget._gesture)
						  e.currentTarget._gesture.addPointer(e.pointerId);
				  }, false);
				  that.addEventListener("MSGestureTap", function (e){
					  e.preventDefault();
					  var $slide = $(this),
						  target = $slide.index();
					  if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) {
						  slider.direction = (slider.currentItem < target) ? "next" : "prev";
						  slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true);
					  }
				  });
			  });
		  }
		}
	  },
	  controlNav: {
		setup: function() {
		  if (!slider.manualControls) {
			methods.controlNav.setupPaging();
		  } else { // MANUALCONTROLS:
			methods.controlNav.setupManual();
		  }
		},
		setupPaging: function() {
		  var type = (slider.vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging',
			  j = 1,
			  item,
			  slide;

		  slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>');

		  if (slider.pagingCount > 1) {
			for (var i = 0; i < slider.pagingCount; i++) {
			  slide = slider.slides.eq(i);
			  item = (slider.vars.controlNav === "thumbnails") ? '<img src="' + slide.attr( 'data-thumb' ) + '"/>' : '<a>' + j + '</a>';
			  if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) {
				var captn = slide.attr( 'data-thumbcaption' );
				if ( '' != captn && undefined != captn ) item += '<span class="' + namespace + 'caption">' + captn + '</span>';
			  }
			  slider.controlNavScaffold.append('<li>' + item + '</li>');
			  j++;
			}
		  }

		  // CONTROLSCONTAINER:
		  (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold);
		  methods.controlNav.set();

		  methods.controlNav.active();

		  slider.controlNavScaffold.delegate('a, img', eventType, function(event) {
			event.preventDefault();

			if (watchedEvent === "" || watchedEvent === event.type) {
			  var $this = $(this),
				  target = slider.controlNav.index($this);

			  if (!$this.hasClass(namespace + 'active')) {
				slider.direction = (target > slider.currentSlide) ? "next" : "prev";
				slider.flexAnimate(target, slider.vars.pauseOnAction);
			  }
			}

			// setup flags to prevent event duplication
			if (watchedEvent === "") {
			  watchedEvent = event.type;
			}
			methods.setToClearWatchedEvent();

		  });
		},
		setupManual: function() {
		  slider.controlNav = slider.manualControls;
		  methods.controlNav.active();

		  slider.controlNav.bind(eventType, function(event) {
			event.preventDefault();

			if (watchedEvent === "" || watchedEvent === event.type) {
			  var $this = $(this),
				  target = slider.controlNav.index($this);

			  if (!$this.hasClass(namespace + 'active')) {
				(target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev";
				slider.flexAnimate(target, slider.vars.pauseOnAction);
			  }
			}

			// setup flags to prevent event duplication
			if (watchedEvent === "") {
			  watchedEvent = event.type;
			}
			methods.setToClearWatchedEvent();
		  });
		},
		set: function() {
		  var selector = (slider.vars.controlNav === "thumbnails") ? 'img' : 'a';
		  slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider);
		},
		active: function() {
		  slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active");
		},
		update: function(action, pos) {
		  if (slider.pagingCount > 1 && action === "add") {
			slider.controlNavScaffold.append($('<li><a>' + slider.count + '</a></li>'));
		  } else if (slider.pagingCount === 1) {
			slider.controlNavScaffold.find('li').remove();
		  } else {
			slider.controlNav.eq(pos).closest('li').remove();
		  }
		  methods.controlNav.set();
		  (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active();
		}
	  },
	  directionNav: {
		setup: function() {
		  var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">' + slider.vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + '</a></li></ul>');

		  // CONTROLSCONTAINER:
		  if (slider.controlsContainer) {
			$(slider.controlsContainer).append(directionNavScaffold);
			slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer);
		  } else {
			slider.append(directionNavScaffold);
			slider.directionNav = $('.' + namespace + 'direction-nav li a', slider);
		  }

		  methods.directionNav.update();

		  slider.directionNav.bind(eventType, function(event) {
			event.preventDefault();
			var target;

			if (watchedEvent === "" || watchedEvent === event.type) {
			  target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev');
			  slider.flexAnimate(target, slider.vars.pauseOnAction);
			}

			// setup flags to prevent event duplication
			if (watchedEvent === "") {
			  watchedEvent = event.type;
			}
			methods.setToClearWatchedEvent();
		  });
		},
		update: function() {
		  var disabledClass = namespace + 'disabled';
		  if (slider.pagingCount === 1) {
			slider.directionNav.addClass(disabledClass).attr('tabindex', '-1');
		  } else if (!slider.vars.animationLoop) {
			if (slider.animatingTo === 0) {
			  slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass).attr('tabindex', '-1');
			} else if (slider.animatingTo === slider.last) {
			  slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass).attr('tabindex', '-1');
			} else {
			  slider.directionNav.removeClass(disabledClass).removeAttr('tabindex');
			}
		  } else {
			slider.directionNav.removeClass(disabledClass).removeAttr('tabindex');
		  }
		}
	  },
	  pausePlay: {
		setup: function() {
		  var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>');

		  // CONTROLSCONTAINER:
		  if (slider.controlsContainer) {
			slider.controlsContainer.append(pausePlayScaffold);
			slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer);
		  } else {
			slider.append(pausePlayScaffold);
			slider.pausePlay = $('.' + namespace + 'pauseplay a', slider);
		  }

		  methods.pausePlay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play');

		  slider.pausePlay.bind(eventType, function(event) {
			event.preventDefault();

			if (watchedEvent === "" || watchedEvent === event.type) {
			  if ($(this).hasClass(namespace + 'pause')) {
				slider.manualPause = true;
				slider.manualPlay = false;
				slider.pause();
			  } else {
				slider.manualPause = false;
				slider.manualPlay = true;
				slider.play();
			  }
			}

			// setup flags to prevent event duplication
			if (watchedEvent === "") {
			  watchedEvent = event.type;
			}
			methods.setToClearWatchedEvent();
		  });
		},
		update: function(state) {
		  (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').html(slider.vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').html(slider.vars.pauseText);
		}
	  },
	  touch: function() {
		var startX,
		  startY,
		  offset,
		  cwidth,
		  dx,
		  startT,
		  scrolling = false,
		  localX = 0,
		  localY = 0,
		  accDx = 0;

		if(!msGesture){
			function onTouchStart(e) {
			  if (slider.animating) {
				e.preventDefault();
			  } else if ( ( window.navigator.msPointerEnabled ) || e.touches.length === 1 ) {
				slider.pause();
				// CAROUSEL:
				cwidth = (vertical) ? slider.h : slider. w;
				startT = Number(new Date());
				// CAROUSEL:

				// Local vars for X and Y points.
				localX = e.touches[0].pageX;
				localY = e.touches[0].pageY;

				offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
						 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
						 (carousel && slider.currentSlide === slider.last) ? slider.limit :
						 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide :
						 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
				startX = (vertical) ? localY : localX;
				startY = (vertical) ? localX : localY;

				el.addEventListener('touchmove', onTouchMove, false);
				el.addEventListener('touchend', onTouchEnd, false);
			  }
			}

			function onTouchMove(e) {
			  // Local vars for X and Y points.

			  localX = e.touches[0].pageX;
			  localY = e.touches[0].pageY;

			  dx = (vertical) ? startX - localY : startX - localX;
			  scrolling = (vertical) ? (Math.abs(dx) < Math.abs(localX - startY)) : (Math.abs(dx) < Math.abs(localY - startY));

			  var fxms = 500;

			  if ( ! scrolling || Number( new Date() ) - startT > fxms ) {
				e.preventDefault();
				if (!fade && slider.transitions) {
				  if (!slider.vars.animationLoop) {
					dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1);
				  }
				  slider.setProps(offset + dx, "setTouch");
				}
			  }
			}

			function onTouchEnd(e) {
			  // finish the touch by undoing the touch session
			  el.removeEventListener('touchmove', onTouchMove, false);

			  if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
				var updateDx = (reverse) ? -dx : dx,
					target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');

				if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
				  slider.flexAnimate(target, slider.vars.pauseOnAction);
				} else {
				  if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true);
				}
			  }
			  el.removeEventListener('touchend', onTouchEnd, false);

			  startX = null;
			  startY = null;
			  dx = null;
			  offset = null;
			}

			el.addEventListener('touchstart', onTouchStart, false);
		}else{
			function onMSPointerDown(e){
				e.stopPropagation();
				if (slider.animating) {
					e.preventDefault();
				}else{
					slider.pause();
					el._gesture.addPointer(e.pointerId);
					accDx = 0;
					cwidth = (vertical) ? slider.h : slider. w;
					startT = Number(new Date());
					// CAROUSEL:

					offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
						(carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
							(carousel && slider.currentSlide === slider.last) ? slider.limit :
								(carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide :
									(reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
				}
			}

			function onMSGestureChange(e) {
				e.stopPropagation();
				var slider = e.target._slider;
				if(!slider){
					return;
				}
				var transX = -e.translationX,
					transY = -e.translationY;

				//Accumulate translations.
				accDx = accDx + ((vertical) ? transY : transX);
				dx = accDx;
				scrolling = (vertical) ? (Math.abs(accDx) < Math.abs(-transX)) : (Math.abs(accDx) < Math.abs(-transY));

				if(e.detail === e.MSGESTURE_FLAG_INERTIA){
					setImmediate(function (){
						el._gesture.stop();
					});

					return;
				}

				if (!scrolling || Number(new Date()) - startT > 500) {
					e.preventDefault();
					if (!fade && slider.transitions) {
						if (!slider.vars.animationLoop) {
							dx = accDx / ((slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0) ? (Math.abs(accDx) / cwidth + 2) : 1);
						}
						slider.setProps(offset + dx, "setTouch");
					}
				}
			}

			function onMSGestureEnd(e) {
				e.stopPropagation();
				var slider = e.target._slider;
				if(!slider){
					return;
				}
				if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
					var updateDx = (reverse) ? -dx : dx,
						target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');

					if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
						slider.flexAnimate(target, slider.vars.pauseOnAction);
					} else {
						if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true);
					}
				}

				startX = null;
				startY = null;
				dx = null;
				offset = null;
				accDx = 0;
			}

			el.style.msTouchAction = "pan-y";
			el._gesture = new MSGesture();
			el._gesture.target = el;
			el.addEventListener("MSPointerDown", onMSPointerDown, false);
			el._slider = slider;
			el.addEventListener("MSGestureChange", onMSGestureChange, false);
			el.addEventListener("MSGestureEnd", onMSGestureEnd, false);

		}
	  },
	  resize: function() {
		if (!slider.animating && slider.is(':visible')) {
		  if (!carousel) slider.doMath();

		  if (fade) {
			// SMOOTH HEIGHT:
			methods.smoothHeight();
		  } else if (carousel) { //CAROUSEL:
			slider.slides.width(slider.computedW);
			slider.update(slider.pagingCount);
			slider.setProps();
		  }
		  else if (vertical) { //VERTICAL:
			slider.viewport.height(slider.h);
			slider.setProps(slider.h, "setTotal");
		  } else {
			// SMOOTH HEIGHT:
			if (slider.vars.smoothHeight) methods.smoothHeight();
			slider.newSlides.width(slider.computedW);
			slider.setProps(slider.computedW, "setTotal");
		  }
		}
	  },
	  smoothHeight: function(dur) {
		if (!vertical || fade) {
		  var $obj = (fade) ? slider : slider.viewport;
		  (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingTo).height());
		}
	  },
	  sync: function(action) {
		var $obj = $(slider.vars.sync).data("flexslider"),
			target = slider.animatingTo;

		switch (action) {
		  case "animate": $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true); break;
		  case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break;
		  case "pause": $obj.pause(); break;
		}
	  },
	  uniqueID: function($clone) {
		$clone.find( '[id]' ).each(function() {
		  var $this = $(this);
		  $this.attr( 'id', $this.attr( 'id' ) + '_clone' );
		});
		return $clone;
	  },
	  pauseInvisible: {
		visProp: null,
		init: function() {
		  var prefixes = ['webkit','moz','ms','o'];

		  if ('hidden' in document) return 'hidden';
		  for (var i = 0; i < prefixes.length; i++) {
			if ((prefixes[i] + 'Hidden') in document)
			methods.pauseInvisible.visProp = prefixes[i] + 'Hidden';
		  }
		  if (methods.pauseInvisible.visProp) {
			var evtname = methods.pauseInvisible.visProp.replace(/[H|h]idden/,'') + 'visibilitychange';
			document.addEventListener(evtname, function() {
			  if (methods.pauseInvisible.isHidden()) {
				if(slider.startTimeout) clearTimeout(slider.startTimeout); //If clock is ticking, stop timer and prevent from starting while invisible
				else slider.pause(); //Or just pause
			  }
			  else {
				if(slider.started) slider.play(); //Initiated before, just play
				else (slider.vars.initDelay > 0) ? setTimeout(slider.play, slider.vars.initDelay) : slider.play(); //Didn't init before: simply init or wait for it
			  }
			});
		  }
		},
		isHidden: function() {
		  return document[methods.pauseInvisible.visProp] || false;
		}
	  },
	  setToClearWatchedEvent: function() {
		clearTimeout(watchedEventClearTimer);
		watchedEventClearTimer = setTimeout(function() {
		  watchedEvent = "";
		}, 3000);
	  }
	};

	// public methods
	slider.flexAnimate = function(target, pause, override, withSync, fromNav) {
	  if (!slider.vars.animationLoop && target !== slider.currentSlide) {
		slider.direction = (target > slider.currentSlide) ? "next" : "prev";
	  }

	  if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev";

	  if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) {
		if (asNav && withSync) {
		  var master = $(slider.vars.asNavFor).data('flexslider');
		  slider.atEnd = target === 0 || target === slider.count - 1;
		  master.flexAnimate(target, true, false, true, fromNav);
		  slider.direction = (slider.currentItem < target) ? "next" : "prev";
		  master.direction = slider.direction;

		  if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) {
			slider.currentItem = target;
			slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
			target = Math.floor(target/slider.visible);
		  } else {
			slider.currentItem = target;
			slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
			return false;
		  }
		}

		slider.animating = true;
		slider.animatingTo = target;

		// SLIDESHOW:
		if (pause) slider.pause();

		// API: before() animation Callback
		slider.vars.before(slider);

		// SYNC:
		if (slider.syncExists && !fromNav) methods.sync("animate");

		// CONTROLNAV
		if (slider.vars.controlNav) methods.controlNav.active();

		// !CAROUSEL:
		// CANDIDATE: slide active class (for add/remove slide)
		if (!carousel) slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide');

		// INFINITE LOOP:
		// CANDIDATE: atEnd
		slider.atEnd = target === 0 || target === slider.last;

		// DIRECTIONNAV:
		if (slider.vars.directionNav) methods.directionNav.update();

		if (target === slider.last) {
		  // API: end() of cycle Callback
		  slider.vars.end(slider);
		  // SLIDESHOW && !INFINITE LOOP:
		  if (!slider.vars.animationLoop) slider.pause();
		}

		// SLIDE:
		if (!fade) {
		  var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW,
			  margin, slideString, calcNext;

		  // INFINITE LOOP / REVERSE:
		  if (carousel) {
			//margin = (slider.vars.itemWidth > slider.w) ? slider.vars.itemMargin * 2 : slider.vars.itemMargin;
			margin = slider.vars.itemMargin;
			calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo;
			slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext;
		  } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") {
			slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0;
		  } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") {
			slideString = (reverse) ? 0 : (slider.count + 1) * dimension;
		  } else {
			slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension;
		  }
		  slider.setProps(slideString, "", slider.vars.animationSpeed);
		  if (slider.transitions) {
			if (!slider.vars.animationLoop || !slider.atEnd) {
			  slider.animating = false;
			  slider.currentSlide = slider.animatingTo;
			}

			// Unbind previous transitionEnd events and re-bind new transitionEnd event
			slider.container.unbind("webkitTransitionEnd transitionend");
			slider.container.bind("webkitTransitionEnd transitionend", function() {
			  clearTimeout(slider.ensureAnimationEnd);
			  slider.wrapup(dimension);
			});

			// Insurance for the ever-so-fickle transitionEnd event
			clearTimeout(slider.ensureAnimationEnd);
			slider.ensureAnimationEnd = setTimeout(function() {
			  slider.wrapup(dimension);
			}, slider.vars.animationSpeed + 100);

		  } else {
			slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing, function(){
			  slider.wrapup(dimension);
			});
		  }
		} else { // FADE:
		  if (!touch) {
			//slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationSpeed, slider.vars.easing);
			//slider.slides.eq(target).fadeIn(slider.vars.animationSpeed, slider.vars.easing, slider.wrapup);

			slider.slides.eq(slider.currentSlide).css({"zIndex": 1}).animate({"opacity": 0}, slider.vars.animationSpeed, slider.vars.easing);
			slider.slides.eq(target).css({"zIndex": 2}).animate({"opacity": 1}, slider.vars.animationSpeed, slider.vars.easing, slider.wrapup);

		  } else {
			slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 });
			slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 });
			slider.wrapup(dimension);
		  }
		}
		// SMOOTH HEIGHT:
		if (slider.vars.smoothHeight) methods.smoothHeight(slider.vars.animationSpeed);
	  }
	};
	slider.wrapup = function(dimension) {
	  // SLIDE:
	  if (!fade && !carousel) {
		if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) {
		  slider.setProps(dimension, "jumpEnd");
		} else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) {
		  slider.setProps(dimension, "jumpStart");
		}
	  }
	  slider.animating = false;
	  slider.currentSlide = slider.animatingTo;
	  // API: after() animation Callback
	  slider.vars.after(slider);
	};

	// SLIDESHOW:
	slider.animateSlides = function() {
	  if (!slider.animating && focused ) slider.flexAnimate(slider.getTarget("next"));
	};
	// SLIDESHOW:
	slider.pause = function() {
	  clearInterval(slider.animatedSlides);
	  slider.animatedSlides = null;
	  slider.playing = false;
	  // PAUSEPLAY:
	  if (slider.vars.pausePlay) methods.pausePlay.update("play");
	  // SYNC:
	  if (slider.syncExists) methods.sync("pause");
	};
	// SLIDESHOW:
	slider.play = function() {
	  if (slider.playing) clearInterval(slider.animatedSlides);
	  slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed);
	  slider.started = slider.playing = true;
	  // PAUSEPLAY:
	  if (slider.vars.pausePlay) methods.pausePlay.update("pause");
	  // SYNC:
	  if (slider.syncExists) methods.sync("play");
	};
	// STOP:
	slider.stop = function () {
	  slider.pause();
	  slider.stopped = true;
	};
	slider.canAdvance = function(target, fromNav) {
	  // ASNAV:
	  var last = (asNav) ? slider.pagingCount - 1 : slider.last;
	  return (fromNav) ? true :
			 (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true :
			 (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false :
			 (target === slider.currentSlide && !asNav) ? false :
			 (slider.vars.animationLoop) ? true :
			 (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false :
			 (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false :
			 true;
	};
	slider.getTarget = function(dir) {
	  slider.direction = dir;
	  if (dir === "next") {
		return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1;
	  } else {
		return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1;
	  }
	};

	// SLIDE:
	slider.setProps = function(pos, special, dur) {
	  var target = (function() {
		var posCheck = (pos) ? pos : ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo,
			posCalc = (function() {
			  if (carousel) {
				return (special === "setTouch") ? pos :
					   (reverse && slider.animatingTo === slider.last) ? 0 :
					   (reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
					   (slider.animatingTo === slider.last) ? slider.limit : posCheck;
			  } else {
				switch (special) {
				  case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos;
				  case "setTouch": return (reverse) ? pos : pos;
				  case "jumpEnd": return (reverse) ? pos : slider.count * pos;
				  case "jumpStart": return (reverse) ? slider.count * pos : pos;
				  default: return pos;
				}
			  }
			}());

			return (posCalc * -1) + "px";
		  }());

	  if (slider.transitions) {
		target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)";
		dur = (dur !== undefined) ? (dur/1000) + "s" : "0s";
		slider.container.css("-" + slider.pfx + "-transition-duration", dur);
		 slider.container.css("transition-duration", dur);
	  }

	  slider.args[slider.prop] = target;
	  if (slider.transitions || dur === undefined) slider.container.css(slider.args);

	  slider.container.css('transform',target);
	};

	slider.setup = function(type) {
	  // SLIDE:
	  if (!fade) {
		var sliderOffset, arr;

		if (type === "init") {
		  slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container);
		  // INFINITE LOOP:
		  slider.cloneCount = 0;
		  slider.cloneOffset = 0;
		  // REVERSE:
		  if (reverse) {
			arr = $.makeArray(slider.slides).reverse();
			slider.slides = $(arr);
			slider.container.empty().append(slider.slides);
		  }
		}
		// INFINITE LOOP && !CAROUSEL:
		if (slider.vars.animationLoop && !carousel) {
		  slider.cloneCount = 2;
		  slider.cloneOffset = 1;
		  // clear out old clones
		  if (type !== "init") slider.container.find('.clone').remove();
		  // slider.container.append(slider.slides.first().clone().addClass('clone').attr('aria-hidden', 'true')).prepend(slider.slides.last().clone().addClass('clone').attr('aria-hidden', 'true'));
		  methods.uniqueID( slider.slides.first().clone().addClass('clone').attr('aria-hidden', 'true') ).appendTo( slider.container );
		  methods.uniqueID( slider.slides.last().clone().addClass('clone').attr('aria-hidden', 'true') ).prependTo( slider.container );
		}
		slider.newSlides = $(slider.vars.selector, slider);

		sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset;
		// VERTICAL:
		if (vertical && !carousel) {
		  slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%");
		  setTimeout(function(){
			slider.newSlides.css({"display": "block"});
			slider.doMath();
			slider.viewport.height(slider.h);
			slider.setProps(sliderOffset * slider.h, "init");
		  }, (type === "init") ? 100 : 0);
		} else {
		  slider.container.width((slider.count + slider.cloneCount) * 200 + "%");
		  slider.setProps(sliderOffset * slider.computedW, "init");
		  setTimeout(function(){
			slider.doMath();
			slider.newSlides.css({"width": slider.computedW, "float": "left", "display": "block"});
			// SMOOTH HEIGHT:
			if (slider.vars.smoothHeight) methods.smoothHeight();
		  }, (type === "init") ? 100 : 0);
		}
	  } else { // FADE:
		slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"});
		if (type === "init") {
		  if (!touch) {
			//slider.slides.eq(slider.currentSlide).fadeIn(slider.vars.animationSpeed, slider.vars.easing);
			slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).animate({"opacity": 1},slider.vars.animationSpeed,slider.vars.easing);
		  } else {
			slider.slides.css({ "opacity": 0, "display": "block", "webkitTransition": "opacity " + slider.vars.animationSpeed / 1000 + "s ease", "zIndex": 1 }).eq(slider.currentSlide).css({ "opacity": 1, "zIndex": 2});
		  }
		}
		// SMOOTH HEIGHT:
		if (slider.vars.smoothHeight) methods.smoothHeight();
	  }
	  // !CAROUSEL:
	  // CANDIDATE: active slide
	  if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide");

	  //FlexSlider: init() Callback
	  slider.vars.init(slider);
	};

	slider.doMath = function() {
	  var slide = slider.slides.first(),
		  slideMargin = slider.vars.itemMargin,
		  minItems = slider.vars.minItems,
		  maxItems = slider.vars.maxItems;

	  slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width();
	  slider.h = slide.height();
	  slider.boxPadding = slide.outerWidth() - slide.width();

	  // CAROUSEL:
	  if (carousel) {
		slider.itemT = slider.vars.itemWidth + slideMargin;
		slider.minW = (minItems) ? minItems * slider.itemT : slider.w;
		slider.maxW = (maxItems) ? (maxItems * slider.itemT) - slideMargin : slider.w;
		slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * (minItems - 1)))/minItems :
					   (slider.maxW < slider.w) ? (slider.w - (slideMargin * (maxItems - 1)))/maxItems :
					   (slider.vars.itemWidth > slider.w) ? slider.w : slider.vars.itemWidth;

		// ThemeFusion edit for Avada theme: added the item margin for correct calcs
		slider.visible = Math.floor(slider.w/(slider.itemW + slideMargin));
		slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible;
		slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1);
		slider.last =  slider.pagingCount - 1;
		slider.limit = (slider.pagingCount === 1) ? 0 :
					   (slider.vars.itemWidth > slider.w) ? (slider.itemW * (slider.count - 1)) + (slideMargin * (slider.count - 1)) : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin;
	 } else {
		slider.itemW = slider.w;
		slider.pagingCount = slider.count;
		slider.last = slider.count - 1;
	  }
	  slider.computedW = slider.itemW - slider.boxPadding;
	};

	slider.update = function(pos, action) {
	  slider.doMath();

	  // update currentSlide and slider.animatingTo if necessary
	  if (!carousel) {
		if (pos < slider.currentSlide) {
		  slider.currentSlide += 1;
		} else if (pos <= slider.currentSlide && pos !== 0) {
		  slider.currentSlide -= 1;
		}
		slider.animatingTo = slider.currentSlide;
	  }

	  // update controlNav
	  if (slider.vars.controlNav && !slider.manualControls) {
		if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) {
		  methods.controlNav.update("add");
		} else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) {
		  if (carousel && slider.currentSlide > slider.last) {
			slider.currentSlide -= 1;
			slider.animatingTo -= 1;
		  }
		  methods.controlNav.update("remove", slider.last);
		}
	  }
	  // update directionNav
	  if (slider.vars.directionNav) methods.directionNav.update();

	};

	slider.addSlide = function(obj, pos) {
	  var $obj = $(obj);

	  slider.count += 1;
	  slider.last = slider.count - 1;

	  // append new slide
	  if (vertical && reverse) {
		(pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj);
	  } else {
		(pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj);
	  }

	  // update currentSlide, animatingTo, controlNav, and directionNav
	  slider.update(pos, "add");

	  // update slider.slides
	  slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
	  // re-setup the slider to accomdate new slide
	  slider.setup();

	  //FlexSlider: added() Callback
	  slider.vars.added(slider);
	};
	slider.removeSlide = function(obj) {
	  var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj;

	  // update count
	  slider.count -= 1;
	  slider.last = slider.count - 1;

	  // remove slide
	  if (isNaN(obj)) {
		$(obj, slider.slides).remove();
	  } else {
		(vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove();
	  }

	  // update currentSlide, animatingTo, controlNav, and directionNav
	  slider.doMath();
	  slider.update(pos, "remove");

	  // update slider.slides
	  slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
	  // re-setup the slider to accomdate new slide
	  slider.setup();

	  // FlexSlider: removed() Callback
	  slider.vars.removed(slider);
	};

	slider.destroy = function() {
	  var classNamespace = '.' + slider.vars.namespace; // Namespaced class selector
	  if (slider.vars.controlNav) slider.controlNav.closest(classNamespace + 'control-nav').remove(); // Remove control elements if present
	  if (slider.vars.directionNav) slider.directionNav.closest(classNamespace + 'direction-nav').remove(); // Remove direction-nav elements if present
	  if (slider.vars.pausePlay) slider.pausePlay.closest(classNamespace + 'pauseplay').remove(); // Remove pauseplay elements if present
	  slider.find('.clone').remove(); // Remove any flexslider clones
	  slider.unbind(slider.vars.eventNamespace); // Remove events on slider
	  if ( slider.vars.animation != "fade" ) slider.container.unwrap(); // Remove the .flex-viewport div
	  slider.container.removeAttr('style'); // Remove generated CSS (could collide with 3rd parties)
	  slider.container.unbind(slider.vars.eventNamespace); // Remove events on slider
	  slider.slides.removeAttr('style'); // Remove generated CSS (could collide with 3rd parties)
	  slider.slides.filter(classNamespace + 'active-slide').removeClass(slider.vars.namespace + 'active-slide'); // Remove slide active class
	  slider.slides.unbind(slider.vars.eventNamespace); // Remove events on slides
	  $(document).unbind(slider.vars.eventNamespace + "-" + slider.id); // Remove events from document for this instance only
	  $(window).unbind(slider.vars.eventNamespace + "-" + slider.id); // Remove events from window for this instance only
	  slider.stop(); // Stop the interval
	  slider.removeData('flexslider'); // Remove data
	};

	//FlexSlider: Initialize
	methods.init();
  };

  // Ensure the slider isn't focussed if the window loses focus.
  $( window ).blur( function ( e ) {
	focused = false;
  }).focus( function ( e ) {
	focused = true;
  });

  //FlexSlider: Default Settings
  $.flexslider.defaults = {
	namespace: "flex-",			 //{NEW} String: Prefix string attached to the class of every element generated by the plugin
	selector: ".slides > li",	   //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril
	animation: "fade",			  //String: Select your animation type, "fade" or "slide"
	easing: "swing",				//{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported!
	direction: "horizontal",		//String: Select the sliding direction, "horizontal" or "vertical"
	reverse: false,				 //{NEW} Boolean: Reverse the animation direction
	animationLoop: true,			//Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end
	smoothHeight: false,			//{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode
	startAt: 0,					 //Integer: The slide that the slider should start on. Array notation (0 = first slide)
	slideshow: true,				//Boolean: Animate slider automatically
	slideshowSpeed: 7000,		   //Integer: Set the speed of the slideshow cycling, in milliseconds
	animationSpeed: 600,			//Integer: Set the speed of animations, in milliseconds
	initDelay: 0,				   //{NEW} Integer: Set an initialization delay, in milliseconds
	randomize: false,			   //Boolean: Randomize slide order
	thumbCaptions: false,		   //Boolean: Whether or not to put captions on thumbnails when using the "thumbnails" controlNav.

	// Usability features
	pauseOnAction: true,			//Boolean: Pause the slideshow when interacting with control elements, highly recommended.
	pauseOnHover: false,			//Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering
	pauseInvisible: true,	   //{NEW} Boolean: Pause the slideshow when tab is invisible, resume when visible. Provides better UX, lower CPU usage.
	useCSS: true,				   //{NEW} Boolean: Slider will use CSS3 transitions if available
	touch: true,					//{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices
	video: false,				   //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches

	// Primary Controls
	controlNav: true,			   //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage
	directionNav: true,			 //Boolean: Create navigation for previous/next navigation? (true/false)
	prevText: "&#xf104;",		   //String: Set the text for the "previous" directionNav item
	nextText: "&#xf105;",		//String: Set the text for the "next" directionNav item

	// Secondary Navigation
	keyboard: true,				 //Boolean: Allow slider navigating via keyboard left/right keys
	multipleKeyboard: false,		//{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present.
	mousewheel: false,			  //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel
	pausePlay: false,			   //Boolean: Create pause/play dynamic element
	pauseText: "Pause",			 //String: Set the text for the "pause" pausePlay item
	playText: "Play",			   //String: Set the text for the "play" pausePlay item

	// Special properties
	controlsContainer: "",		  //{UPDATED} jQuery Object/Selector: Declare which container the navigation elements should be appended too. Default container is the FlexSlider element. Example use would be $(".flexslider-container"). Property is ignored if given element is not found.
	manualControls: "",			 //{UPDATED} jQuery Object/Selector: Declare custom control navigation. Examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs.
	sync: "",					   //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care.
	asNavFor: "",				   //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider

	// Carousel Options
	itemWidth: 0,				   //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding.
	itemMargin: 0,				  //{NEW} Integer: Margin between carousel items.
	minItems: 1,					//{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this.
	maxItems: 0,					//{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit.
	move: 0,						//{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items.
	allowOneSlide: true,		   //{NEW} Boolean: Whether or not to allow a slider comprised of a single slide

	// Callback API
	start: function(){},			//Callback: function(slider) - Fires when the slider loads the first slide
	before: function(){},		   //Callback: function(slider) - Fires asynchronously with each slider animation
	after: function(){},			//Callback: function(slider) - Fires after each slider animation completes
	end: function(){},			  //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous)
	added: function(){},			//{NEW} Callback: function(slider) - Fires after a slide is added
	removed: function(){},		   //{NEW} Callback: function(slider) - Fires after a slide is removed
	init: function() {}			 //{NEW} Callback: function(slider) - Fires after the slider is initially setup
  };

  //FlexSlider: Plugin Function
  $.fn.flexslider = function(options) {
	if (options === undefined) options = {};

	if (typeof options === "object") {
	  return this.each(function() {
		var $this = $(this),
			selector = (options.selector) ? options.selector : ".slides > li",
			$slides = $this.find(selector);

	  if ( ( $slides.length === 1 && options.allowOneSlide === true ) || $slides.length === 0 ) {
		  $slides.fadeIn(400);
		  if (options.start) options.start($this);
		} else if ($this.data('flexslider') === undefined) {
		  new $.flexslider(this, options);
		}
	  });
	} else {
	  // Helper strings to quickly perform functions on the slider
	  var $slider = $(this).data('flexslider');
	  switch (options) {
		case "play": $slider.play(); break;
		case "pause": $slider.pause(); break;
		case "stop": $slider.stop(); break;
		case "next": $slider.flexAnimate($slider.getTarget("next"), true); break;
		case "prev":
		case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break;
		case "destroy": $slider.destroy(); break;
		default: if (typeof options === "number") $slider.flexAnimate(options, true);
	  }
	}
  };
})(jQuery);;;(function ( $, window, document, undefined ) {

	"use strict";

	var $plugin_name = "fusion_maps",
		$defaults 	 = {
			addresses: 	{},
			address_pin: true,
			animations: true,
			delay: 10, // delay between each address if over_query_limit is reached
			infobox_background_color: false,
			infobox_styling: 'default',
			infobox_text_color: false,
			map_style: 'default',
			map_type: 'roadmap',
			marker_icon: false,
			overlay_color: false,
			overlay_color_hsl: {}, // hue, saturation, lightness object
			pan_control: true,
			show_address: true,
			scale_control: true,
			scrollwheel: true,
			zoom: 9,
			zoom_control: true
		};

	// Plugin Constructor
	function Plugin( $element, $options ) {
		this.element 	= $element;
		this.settings 	= $.extend( {}, $defaults, $options );
		this._defaults 	= $defaults;
		this._name 		= $plugin_name;

		this.geocoder = new google.maps.Geocoder();
		this.next_address = 0;
		this.infowindow = new google.maps.InfoWindow();
		this.markers = [];
		this.query_sent = false;
		this.last_cache_index = 'none';
		this.bounds = new google.maps.LatLngBounds();

		this.init();
	}

	// Avoid Plugin.prototype conflicts
	$.extend(Plugin.prototype, {
		init: function() {
			var $map_options = {
					zoom: this.settings.zoom,
					mapTypeId: this.settings.map_type,
					scrollwheel: this.settings.scrollwheel,
					scaleControl: this.settings.scale_control,
					panControl: this.settings.pan_control,
					zoomControl: this.settings.zoom_control
				},
				$latlng, $styles,
				$isDraggable = $(document).width() > 640 ? true : false,
				$plugin_object = this;


			if( ! this.settings.scrollwheel ) {
				$map_options.draggable = $isDraggable;
			}

			if( ! this.settings.address_pin ) {
				this.settings.addresses = [ this.settings.addresses[0] ];
			}

			jQuery.each( this.settings.addresses, function( $index ) {
				if( this.cache == false ) {
					$plugin_object.last_cache_index = $index;
				}
			});

			if( this.settings.addresses[0].coordinates ) {
				$latlng = new google.maps.LatLng( this.settings.addresses[0].latitude, this.settings.addresses[0].longitude );
				$map_options.center = $latlng;
			}

			this.map = new google.maps.Map( this.element, $map_options );

			if( this.settings.overlay_color && this.settings.map_style == 'custom' ) {
				$styles = [
					{
						stylers: [
							{ hue: this.settings.overlay_color },
							{ lightness: this.settings.overlay_color_hsl.lum * 2 - 100 },
							{ saturation: this.settings.overlay_color_hsl.sat * 2 - 100 }
						]
					},
					{
						featureType: 'road',
						elementType: 'geometry',
						stylers: [
							{ visibility: 'simplified' }
						]
					},
					{
						featureType: 'road',
						elementType: 'labels'
					}
				];

				this.map.setOptions({
					styles: $styles
				});
			}

			// Reset zoom level after adding markers
			var bounds_changed = google.maps.event.addListener( this.map, 'bounds_changed', function() {
				var $latlng = new google.maps.LatLng( $plugin_object.settings.addresses[0].latitude, $plugin_object.settings.addresses[0].longitude );

				$plugin_object.map.setZoom( $plugin_object.settings.zoom );
				$plugin_object.map.setCenter( $latlng );

				google.maps.event.removeListener( bounds_changed );
			});

			this.next_geocode_request();
		},
		/**
		 * Geocoding Addresses
		 * @param  object $search object with address
		 * @return void
		 */
		geocode_address: function( $search, $index ) {
			var $plugin_object = this,
				$lat_lng_object,
				$address_object,
				$latitude,
				$longitude,
				$location,
				$cache = true,
				$query_sent;

			if( typeof( $search ) == 'object' && $search.cache == false ) {
				$cache = false;

				if( $search.coordinates === true ) {
					$lat_lng_object = new google.maps.LatLng( $search.latitude, $search.longitude );
					$address_object = { latLng: $lat_lng_object };
				} else {
					$address_object = { address: $search.address };
				}

				this.geocoder.geocode($address_object, function( $results, $status ) {
					var $latitude, $longitude, $location;

					if( $status == google.maps.GeocoderStatus.OK ) {
						// When coordiantes have been entered, bypass the geocoder results and use specified coordinates
						if ( $search.coordinates === true ) {
							$location = $lat_lng_object; // first location
							$latitude = jQuery.trim( $search.latitude );
							$longitude = jQuery.trim( $search.longitude );
						} else {
							$location = $results[0].geometry.location; // first location
							$latitude = $location.lat();
							$longitude = $location.lng();
						}

						$plugin_object.settings.addresses[ $index ]['latitude'] = $latitude;
						$plugin_object.settings.addresses[ $index ]['longitude'] = $longitude;

						if( $search.coordinates === true && $search.infobox_content === '' ) {
							$search.geocoded_address = $results[0].formatted_address;
						}

						// If first address is not a coordinate, set a center through address
						if( $plugin_object.next_address == 1 && ! $search.coordinates ) {
							$plugin_object.map.setCenter( $location );
						}

						if( $plugin_object.settings.address_pin ) {
							$plugin_object.create_marker( $search, $latitude, $longitude );
						}

						if ( $plugin_object.next_address == 0 ) {
							$plugin_object.map.setCenter( $location );
						}
					} else {
						// if over query limit, go back and try again with a delayed call
						if( $status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT ) {
							$plugin_object.next_address--;
							$plugin_object.settings.delay++;
						}
					}

					if ( $cache == false && $plugin_object.query_sent == false && $plugin_object.last_cache_index == $index ) {
						var $data = {
							action: 'fusion_cache_map',
							addresses: $plugin_object.settings.addresses,
							security: js_local_vars.admin_ajax_nonce
						};

						jQuery.post( js_local_vars.admin_ajax, $data );

						$plugin_object.query_sent = true;
					}

					$plugin_object.next_geocode_request();
				});
			} else if( typeof( $search ) == 'object' && $search.cache == true ) {
				$latitude = jQuery.trim( $search.latitude );
				$longitude = jQuery.trim( $search.longitude );
				$location = new google.maps.LatLng( $latitude, $longitude );

				if( $search.coordinates === true && $search.infobox_content === '' ) {
					$search.geocoded_address = $search.geocoded_address;
				}

				if( $plugin_object.settings.address_pin ) {
					$plugin_object.create_marker( $search, $latitude, $longitude );
				}

				if( $plugin_object.next_address == 0 ) {
					$plugin_object.map.setCenter( $location );
				}

				$plugin_object.next_geocode_request();
			}
		},
		create_marker: function( $address, $latitude, $longitude, $location ) {
			var $content_string,
				$marker_settings = {
					position: new google.maps.LatLng( $latitude, $longitude ),
					map: this.map
				},
				$marker;

			this.bounds.extend( $marker_settings.position );

			if( $address.infobox_content ) {
				$content_string = $address.infobox_content;
			} else {
				$content_string = $address.address;

				// Use google maps suggested address if coordinates were used
				if( $address.coordinates === true && $address.geocoded_address ) {
					$content_string = $address.geocoded_address;
				}
			}

			if( this.settings.animations ) {
				$marker_settings.animation = google.maps.Animation.DROP;
			}

			if( this.settings.map_style == 'custom' && this.settings.marker_icon == 'theme' ) {
				$marker_settings.icon = new google.maps.MarkerImage( $address.marker, null, null, null, new google.maps.Size( 37, 55 ) );
			} else if( this.settings.map_style == 'custom' && $address.marker ) {
				$marker_settings.icon = $address.marker;
			}

			$marker = new google.maps.Marker( $marker_settings );
			this.markers.push( $marker );

			this.create_infowindow( $content_string, $marker );

			if( this.next_address >= this.settings.addresses.length ) {
				this.map.fitBounds( this.bounds );
			}
		},
		create_infowindow: function( $content_string, $marker ) {
			var $info_window, $info_box_div, $info_box_options,
				$plugin_object = this;

			if( this.settings.infobox_styling == 'custom' && this.settings.map_style == 'custom' ) {
				$info_box_div = document.createElement('div');

				$info_box_options = {
					content: $info_box_div,
					disableAutoPan: true,
					maxWidth: 150,
					pixelOffset: new google.maps.Size( -125, 10 ),
					zIndex: null,
					boxStyle: {
						background: 'none',
						opacity: 1,
						width: '250px'
					},
					closeBoxMargin: '2px 2px 2px 2px',
					closeBoxURL: '//www.google.com/intl/en_us/mapfiles/close.gif',
					infoBoxClearance: new google.maps.Size( 1, 1 )
				};

				$info_box_div.className = 'fusion-info-box';
				$info_box_div.style.cssText = 'background-color:' + this.settings.infobox_background_color + ';color:' + this.settings.infobox_text_color  + ';';

				$info_box_div.innerHTML = $content_string;

				$info_window = new InfoBox( $info_box_options );
				$info_window.open( this.map, $marker );

				if( ! this.settings.show_address ) {
					$info_window.close( this.map, $marker );
				}

				google.maps.event.addListener( $marker, 'click', function() {
					var $map = $info_window.getMap();

					if( $map === null || typeof $map === 'undefined' ) {
						$info_window.open( $plugin_object.map, this );
					} else {
						$info_window.close( $plugin_object.map, this );
					}
				});
			} else {
				$info_window = new google.maps.InfoWindow({
					disableAutoPan: true,
					content: $content_string
				});

				if( this.settings.show_address ) {
					$info_window.show = true;
					$info_window.open( this.map, $marker );
				}

				google.maps.event.addListener( $marker, 'click', function() {
					var $map = $info_window.getMap();

					if( $map === null || typeof $map === 'undefined' ) {
						$info_window.open( $plugin_object.map, this );
					} else {
						$info_window.close( $plugin_object.map, this );
					}
				});
			}
		},
		/**
		 * Helps with avoiding OVER_QUERY_LIMIT google maps limit
		 * @return void
		 */
		next_geocode_request: function() {
			var $plugin_object = this;

			if ( $plugin_object.next_address < $plugin_object.settings.addresses.length ) {
				setTimeout( function() {
					$plugin_object.geocode_address( $plugin_object.settings.addresses[$plugin_object.next_address], $plugin_object.next_address );
					$plugin_object.next_address++;
				}, $plugin_object.settings.delay );
			}
		}
	});

	$.fn[ $plugin_name ] = function ( $options ) {
		this.each(function() {
			if ( ! $.data( this, 'plugin_' + $plugin_name ) ) {
				$.data( this, 'plugin_' + $plugin_name, new Plugin( this, $options ) );
			}
		});

		return this;
	};

})( jQuery, window, document );;/*
* hoverFlow - A Solution to Animation Queue Buildup in jQuery
* Version 1.00
*
* Copyright (c) 2009 Ralf Stoltze, http://www.2meter3.de/code/hoverFlow/
* Dual-licensed under the MIT and GPL licenses.
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
(function($) {
	$.fn.hoverFlow = function(type, prop, speed, easing, callback) {
		// only allow hover events
		if ($.inArray(type, ['mouseover', 'mouseenter', 'mouseout', 'mouseleave']) == -1) {
			return this;
		}
	
		// build animation options object from arguments
		// based on internal speed function from jQuery core
		var opt = typeof speed === 'object' ? speed : {
			complete: callback || !callback && easing || $.isFunction(speed) && speed,
			duration: speed,
			easing: callback && easing || easing && !$.isFunction(easing) && easing
		};
		
		// run immediately
		opt.queue = false;
			
		// wrap original callback and add dequeue
		var origCallback = opt.complete;
		opt.complete = function() {
			// execute next function in queue
			$(this).dequeue();
			// execute original callback
			if ($.isFunction(origCallback)) {
				origCallback.call(this);
			}
		};
		
		// keep the chain intact
		return this.each(function() {
			var $this = $(this);
		
			// set flag when mouse is over element
			if (type == 'mouseover' || type == 'mouseenter') {
				$this.data('jQuery.hoverFlow', true);
			} else {
				$this.removeData('jQuery.hoverFlow');
			}
			
			// enqueue function
			$this.queue(function() {				
				// check mouse position at runtime
				var condition = (type == 'mouseover' || type == 'mouseenter') ?
					// read: true if mouse is over element
					$this.data('jQuery.hoverFlow') !== undefined :
					// read: true if mouse is _not_ over element
					$this.data('jQuery.hoverFlow') === undefined;
					
				// only execute animation if condition is met, which is:
				// - only run mouseover animation if mouse _is_ currently over the element
				// - only run mouseout animation if the mouse is currently _not_ over the element
				if(condition) {
					$this.animate(prop, opt);
				// else, clear queue, since there's nothing more to do
				} else {
					$this.queue([]);
				}
			});

		});
	};
})(jQuery);
; /*!
 * hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+
 * http://cherne.net/brian/resources/jquery.hoverIntent.html
 *
 * You may use hoverIntent under the terms of the MIT license. Basically that
 * means you are free to use hoverIntent as long as this header is left intact.
 * Copyright 2007, 2013 Brian Cherne
 */
/* hoverIntent is similar to jQuery's built-in "hover" method except that
 * instead of firing the handlerIn function immediately, hoverIntent checks
 * to see if the user's mouse has slowed down (beneath the sensitivity
 * threshold) before firing the event. The handlerOut function is only
 * called after a matching handlerIn.
 *
 * // basic usage ... just like .hover()
 * .hoverIntent( handlerIn, handlerOut )
 * .hoverIntent( handlerInOut )
 *
 * // basic usage ... with event delegation!
 * .hoverIntent( handlerIn, handlerOut, selector )
 * .hoverIntent( handlerInOut, selector )
 *
 * // using a basic configuration object
 * .hoverIntent( config )
 *
 * @param  handlerIn   function OR configuration object
 * @param  handlerOut  function OR selector for delegation OR undefined
 * @param  selector	selector OR undefined
 * @author Brian Cherne <brian(at)cherne(dot)net>
 */
(function($) {
	$.fn.hoverIntent = function(handlerIn,handlerOut,selector) {

		// default configuration values
		var cfg = {
			interval: 100,
			sensitivity: 7,
			timeout: 0
		};

		if ( typeof handlerIn === "object" ) {
			cfg = $.extend(cfg, handlerIn );
		} else if ($.isFunction(handlerOut)) {
			cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
		} else {
			cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
		}

		// instantiate variables
		// cX, cY = current X and Y position of mouse, updated by mousemove event
		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
		var cX, cY, pX, pY;

		// A private function for getting mouse position
		var track = function(ev) {
			cX = ev.pageX;
			cY = ev.pageY;
		};

		// A private function for comparing current and previous mouse position
		var compare = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			// compare mouse positions to see if they've crossed the threshold
			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
				$(ob).off("mousemove.hoverIntent",track);
				// set hoverIntent state to true (so mouseOut can be called)
				ob.hoverIntent_s = 1;
				return cfg.over.apply(ob,[ev]);
			} else {
				// set previous coordinates for next time
				pX = cX; pY = cY;
				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
			}
		};

		// A private function for delaying the mouseOut function
		var delay = function(ev,ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			ob.hoverIntent_s = 0;
			return cfg.out.apply(ob,[ev]);
		};

		// A private function for handling mouse 'hovering'
		var handleHover = function(e) {
			// copy objects to be passed into t (required for event object to be passed in IE)
			var ev = jQuery.extend({},e);
			var ob = this;

			// cancel hoverIntent timer if it exists
			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }

			// if e.type == "mouseenter"
			if (e.type == "mouseenter") {
				// set "previous" X and Y position based on initial entry point
				pX = ev.pageX; pY = ev.pageY;
				// update "current" X and Y position based on mousemove
				$(ob).on("mousemove.hoverIntent",track);
				// start polling interval (self-calling timeout) to compare mouse coordinates over time
				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}

				// else e.type == "mouseleave"
			} else {
				// unbind expensive mousemove event
				$(ob).off("mousemove.hoverIntent",track);
				// if hoverIntent state is true, then call the mouseOut function after the specified delay
				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
			}
		};

		// listen for mouseenter and mouseleave
		return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
	};
})(jQuery);;/*global jQuery: true */

/*!
   --------------------------------
   Infinite Scroll
   --------------------------------
   + https://github.com/paulirish/infinite-scroll
   + version 2.1.0
   + Copyright 2011/12 Paul Irish & Luke Shumard
   + Licensed under the MIT license

   + Documentation: http://infinite-scroll.com/
*/

// Uses AMD or browser globals to create a jQuery plugin.
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($, undefined) {
    'use strict';

    $.infinitescroll = function infscr(options, callback, element) {
        this.element = $(element);

        // Flag the object in the event of a failed creation
        if (!this._create(options, callback)) {
            this.failed = true;
        }
    };

    $.infinitescroll.defaults = {
        loading: {
            finished: undefined,
            finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>",
            img: 'data:image/gif;base64, ',
            msg: null,
            msgText: '<em>Loading the next set of posts...</em>',
            selector: null,
            speed: 'fast',
            start: undefined
        },
        state: {
            isDuringAjax: false,
            isInvalidPage: false,
            isDestroyed: false,
            isDone: false, // For when it goes all the way through the archive.
            isPaused: false,
            isBeyondMaxPage: false,
            currPage: 1
        },
        debug: false,
        behavior: undefined,
        binder: $(window), // used to cache the selector
        nextSelector: 'div.navigation a:first',
        navSelector: 'div.navigation',
        contentSelector: null, // rename to pageFragment
        extraScrollPx: 150,
        itemSelector: 'div.post',
        animate: false,
        pathParse: undefined,
        dataType: 'html',
        appendCallback: true,
        bufferPx: 40,
        errorCallback: function () { },
        infid: 0, //Instance ID
        pixelsFromNavToBottom: undefined,
        path: undefined, // Either parts of a URL as an array (e.g. ["/page/", "/"] or a function that takes in the page number and returns a URL
        prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted
        maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work)
    };

    $.infinitescroll.prototype = {

        /*
            ----------------------------
            Private methods
            ----------------------------
            */

        // Bind or unbind from scroll
        _binding: function infscr_binding(binding) {

            var instance = this,
            opts = instance.options;

            opts.v = '2.0b2.120520';

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) {
                this['_binding_'+opts.behavior].call(this);
                return;
            }

            if (binding !== 'bind' && binding !== 'unbind') {
                this._debug('Binding value  ' + binding + ' not valid');
                return false;
            }

            if (binding === 'unbind') {
                (this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid);
            } else {
                (this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () {
                    instance.scroll();
                });
            }

            this._debug('Binding', binding);
        },

        // Fundamental aspects of the plugin are initialized
        _create: function infscr_create(options, callback) {

            // Add custom options to defaults
            var opts = $.extend(true, {}, $.infinitescroll.defaults, options);
            this.options = opts;
            var $window = $(window);
            var instance = this;

            // Validate selectors
            if (!instance._validate(options)) {
                return false;
            }

            // Validate page fragment path
            var path = $(opts.nextSelector).attr('href');
            if (!path) {
                this._debug('Navigation selector not found');
                return false;
            }

            // Set the path to be a relative URL from root.
            opts.path = opts.path || this._determinepath(path);

            // contentSelector is 'page fragment' option for .load() / .ajax() calls
            opts.contentSelector = opts.contentSelector || this.element;

            // loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector
            opts.loading.selector = opts.loading.selector || opts.contentSelector;

            // Define loading.msg
            opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>');

            // Preload loading.img
            (new Image()).src = opts.loading.img;

            // distance from nav links to bottom
            // computed as: height of the document + top offset of container - top offset of nav link
            if(opts.pixelsFromNavToBottom === undefined) {
                opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top;
                this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom);
            }

            var self = this;

            // determine loading.start actions
            opts.loading.start = opts.loading.start || function() {
                $(opts.navSelector).hide();
                /**
                 * Customization by ThemeFusion for Avada Theme
                 */
                opts.loading.msg
                .insertAfter(opts.loading.selector)
                .show(opts.loading.speed, $.proxy(function() {
                    this.beginAjax(opts);
                }, self));
            };

            // determine loading.finished actions
            opts.loading.finished = opts.loading.finished || function() {
                if (!opts.state.isBeyondMaxPage)
                    opts.loading.msg.fadeOut(opts.loading.speed);
            };

            // callback loading
            opts.callback = function(instance, data, url) {
                if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) {
                    instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data, url);
                }

                if (callback) {
                    callback.call($(opts.contentSelector)[0], data, opts, url);
                }

                if (opts.prefill) {
                    $window.bind('resize.infinite-scroll', instance._prefill);
                }
            };

            if (options.debug) {
                // Tell IE9 to use its built-in console
                if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') {
                    ['log','info','warn','error','assert','dir','clear','profile','profileEnd']
                        .forEach(function (method) {
                            console[method] = this.call(console[method], console);
                        }, Function.prototype.bind);
                }
            }

            this._setup();

            // Setups the prefill method for use
            if (opts.prefill) {
                this._prefill();
            }

            // Return true to indicate successful creation
            return true;
        },

        _prefill: function infscr_prefill() {
            var instance = this;
            var $window = $(window);

            function needsPrefill() {
                return ( $(instance.options.contentSelector).height() <= $window.height() );
            }

            this._prefill = function() {
                if (needsPrefill()) {
                    instance.scroll();
                }

                $window.bind('resize.infinite-scroll', function() {
                    if (needsPrefill()) {
                        $window.unbind('resize.infinite-scroll');
                        instance.scroll();
                    }
                });
            };

            // Call self after setting up the new function
            this._prefill();
        },

        // Console log wrapper
        _debug: function infscr_debug() {
            if (true !== this.options.debug) {
                return;
            }

            if (typeof console !== 'undefined' && typeof console.log === 'function') {
                // Modern browsers
                // Single argument, which is a string
                if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') {
                    console.log( (Array.prototype.slice.call(arguments)).toString() );
                } else {
                    console.log( Array.prototype.slice.call(arguments) );
                }
            } else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') {
                // IE8
                Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
            }
        },

        // find the number to increment in the path.
        _determinepath: function infscr_determinepath(path) {

            var opts = this.options;

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) {
                return this['_determinepath_'+opts.behavior].call(this,path);
            }

            if (!!opts.pathParse) {

                this._debug('pathParse manual');
                return opts.pathParse(path, this.options.state.currPage+1);

            } else if(path.match(/^(.*2?)\b2\b(.*?$)/)) { // avada edit
                path = path.match(/^(.*2?)\b2\b(.*?$)/).slice(1);
            } else if (path.match(/^(.*?)\b2\b(.*?$)/)) {
                path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);

                // if there is any 2 in the url at all.
            } else if (path.match(/^(.*?)2(.*?$)/)) {

                // page= is used in django:
                // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127
                if (path.match(/^(.*?page=)2(\/.*|$)/)) {
                    path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);
                    return path;
                }

                path = path.match(/^(.*?)2(.*?$)/).slice(1);

            } else {

                // page= is used in drupal too but second page is page=1 not page=2:
                // thx Jerod Fritz, vladikoff
                if (path.match(/^(.*?page=)1(\/.*|$)/)) {
                    path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);
                    return path;
                } else {
                    this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.");
                    // Get rid of isInvalidPage to allow permalink to state
                    opts.state.isInvalidPage = true;  //prevent it from running on this page.
                }
            }
            this._debug('determinePath', path);
            return path;

        },

        // Custom error
        _error: function infscr_error(xhr) {

            var opts = this.options;

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) {
                this['_error_'+opts.behavior].call(this,xhr);
                return;
            }

            if (xhr !== 'destroy' && xhr !== 'end') {
                xhr = 'unknown';
            }

            this._debug('Error', xhr);

            if (xhr === 'end' || opts.state.isBeyondMaxPage) {
                this._showdonemsg();
            }

            opts.state.isDone = true;
            opts.state.currPage = 1; // if you need to go back to this instance
            opts.state.isPaused = false;
            opts.state.isBeyondMaxPage = false;
            this._binding('unbind');

        },

        // Load Callback
        _loadcallback: function infscr_loadcallback(box, data, url) {
            var opts = this.options,
            callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK
            result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append',
            frag;

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) {
                this['_loadcallback_'+opts.behavior].call(this,box,data,url);
                return;
            }

            switch (result) {
                case 'done':
                    this._showdonemsg();
                    return false;

                case 'no-append':
                    if (opts.dataType === 'html') {
                        data = '<div>' + data + '</div>';
                        data = $(data).find(opts.itemSelector);
                    }

                    // if it didn't return anything
                    if (data.length === 0) {
                        return this._error('end');
                    }

                    break;

                case 'append':
                    var children = box.children();
                    // if it didn't return anything
                    if (children.length === 0) {
                        return this._error('end');
                    }

                    // use a documentFragment because it works when content is going into a table or UL
                    frag = document.createDocumentFragment();
                    while (box[0].firstChild) {
                        frag.appendChild(box[0].firstChild);
                    }

                    this._debug('contentSelector', $(opts.contentSelector)[0]);
                    $(opts.contentSelector)[0].appendChild(frag);
                    // previously, we would pass in the new DOM element as context for the callback
                    // however we're now using a documentfragment, which doesn't have parents or children,
                    // so the context is the contentContainer guy, and we pass in an array
                    // of the elements collected as the first argument.

                    data = children.get();
                    break;
            }

            // loadingEnd function
            opts.loading.finished.call($(opts.contentSelector)[0],opts);

            // smooth scroll to ease in the new content
            if (opts.animate) {
                var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px';
                $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; });
            }

            if (!opts.animate) {
                // once the call is done, we can allow it again.
                opts.state.isDuringAjax = false;
            }

            callback(this, data, url);

            if (opts.prefill) {
                this._prefill();
            }
        },

        _nearbottom: function infscr_nearbottom() {

            var opts = this.options,
            pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height();

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) {
                return this['_nearbottom_'+opts.behavior].call(this);
            }

            this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom);

            // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....
            return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom);

        },

        // Pause / temporarily disable plugin from firing
        _pausing: function infscr_pausing(pause) {

            var opts = this.options;

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) {
                this['_pausing_'+opts.behavior].call(this,pause);
                return;
            }

            // If pause is not 'pause' or 'resume', toggle it's value
            if (pause !== 'pause' && pause !== 'resume' && pause !== null) {
                this._debug('Invalid argument. Toggling pause value instead');
            }

            pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle';

            switch (pause) {
                case 'pause':
                    opts.state.isPaused = true;
                break;

                case 'resume':
                    opts.state.isPaused = false;
                break;

                case 'toggle':
                    opts.state.isPaused = !opts.state.isPaused;
                break;
            }

            this._debug('Paused', opts.state.isPaused);
            return false;

        },

        // Behavior is determined
        // If the behavior option is undefined, it will set to default and bind to scroll
        _setup: function infscr_setup() {

            var opts = this.options;

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) {
                this['_setup_'+opts.behavior].call(this);
                return;
            }

            this._binding('bind');

            return false;

        },

        // Show done message
        _showdonemsg: function infscr_showdonemsg() {

            var opts = this.options;

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) {
                this['_showdonemsg_'+opts.behavior].call(this);
                return;
            }

            /**
             * Customized by ThemeFusion for Custom Loading Spinner
             */
            opts.loading.msg
            .find('.fusion-loading-spinner')
            .hide()
            .parent()
            .find('.fusion-loading-msg').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () {
                $(this).parent().fadeOut(opts.loading.speed);
                $( '.fusion-load-more-button' ).fadeOut(opts.loading.speed);
            });

            // user provided callback when done
            opts.errorCallback.call($(opts.contentSelector)[0],'done');
        },

        // grab each selector option and see if any fail
        _validate: function infscr_validate(opts) {
            for (var key in opts) {
                if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) {
                    this._debug('Your ' + key + ' found no elements.');
                    return false;
                }
            }

            return true;
        },

        /*
            ----------------------------
            Public methods
            ----------------------------
            */

        // Bind to scroll
        bind: function infscr_bind() {
            this._binding('bind');
        },

        // Destroy current instance of plugin
        destroy: function infscr_destroy() {
            this.options.state.isDestroyed = true;
            this.options.loading.finished();
            return this._error('destroy');
        },

        // Set pause value to false
        pause: function infscr_pause() {
            this._pausing('pause');
        },

        // Set pause value to false
        resume: function infscr_resume() {
            this._pausing('resume');
        },

        beginAjax: function infscr_ajax(opts) {
            var instance = this,
                path = opts.path,
                box, desturl, method, condition;

            // increment the URL bit. e.g. /page/3/
            opts.state.currPage++;

            // Manually control maximum page
            if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){
                opts.state.isBeyondMaxPage = true;
                this.destroy();
                return;
            }

            // if we're dealing with a table we can't use DIVs
            box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>');

            desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage);
            instance._debug('heading into ajax', desturl);

            method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback';
            if (opts.appendCallback && opts.dataType === 'html') {
                method += '+callback';
            }

            switch (method) {
                case 'html+callback':
                    instance._debug('Using HTML via .load() method');
                    box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) {
                        instance._loadcallback(box, responseText, desturl);
                    });

                    break;

                case 'html':
                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
                    $.ajax({
                        // params
                        url: desturl,
                        dataType: opts.dataType,
                        complete: function infscr_ajax_callback(jqXHR, textStatus) {
                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');
                            if (condition) {
                                instance._loadcallback(box, jqXHR.responseText, desturl);
                            } else {
                                instance._error('end');
                            }
                        }
                    });

                    break;
                case 'json':
                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
                    $.ajax({
                        dataType: 'json',
                        type: 'GET',
                        url: desturl,
                        success: function (data, textStatus, jqXHR) {
                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');
                            if (opts.appendCallback) {
                                // if appendCallback is true, you must defined template in options.
                                // note that data passed into _loadcallback is already an html (after processed in opts.template(data)).
                                if (opts.template !== undefined) {
                                    var theData = opts.template(data);
                                    box.append(theData);
                                    if (condition) {
                                        instance._loadcallback(box, theData);
                                    } else {
                                        instance._error('end');
                                    }
                                } else {
                                    instance._debug('template must be defined.');
                                    instance._error('end');
                                }
                            } else {
                                // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback.
                                if (condition) {
                                    instance._loadcallback(box, data, desturl);
                                } else {
                                    instance._error('end');
                                }
                            }
                        },
                        error: function() {
                            instance._debug('JSON ajax request failed.');
                            instance._error('end');
                        }
                    });

                    break;
            }
        },

        // Retrieve next set of content items
        retrieve: function infscr_retrieve(pageNum) {
            pageNum = pageNum || null;

            var instance = this,
            opts = instance.options;

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) {
                this['retrieve_'+opts.behavior].call(this,pageNum);
                return;
            }

            // for manual triggers, if destroyed, get out of here
            if (opts.state.isDestroyed) {
                this._debug('Instance is destroyed');
                return false;
            }

            // we dont want to fire the ajax multiple times
            opts.state.isDuringAjax = true;

            opts.loading.start.call($(opts.contentSelector)[0],opts);
        },

        // Check to see next page is needed
        scroll: function infscr_scroll() {

            var opts = this.options,
            state = opts.state;

            // if behavior is defined and this function is extended, call that instead of default
            if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) {
                this['scroll_'+opts.behavior].call(this);
                return;
            }

            if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) {
                return;
            }

            if (!this._nearbottom()) {
                return;
            }

            this.retrieve();

        },

        // Toggle pause value
        toggle: function infscr_toggle() {
            this._pausing();
        },

        // Unbind from scroll
        unbind: function infscr_unbind() {
            this._binding('unbind');
        },

        // update options
        update: function infscr_options(key) {
            if ($.isPlainObject(key)) {
                this.options = $.extend(true,this.options,key);
            }
        }
    };


    /*
        ----------------------------
        Infinite Scroll function
        ----------------------------

        Borrowed logic from the following...

        jQuery UI
        - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js

        jCarousel
        - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js

        Masonry
        - https://github.com/desandro/masonry/blob/master/jquery.masonry.js

*/

    $.fn.infinitescroll = function infscr_init(options, callback) {


        var thisCall = typeof options;

        switch (thisCall) {

            // method
            case 'string':
                var args = Array.prototype.slice.call(arguments, 1);

                this.each(function () {
                    var instance = $.data(this, 'infinitescroll');

                    if (!instance) {
                        // not setup yet
                        // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup');
                        return false;
                    }

                    if (!$.isFunction(instance[options]) || options.charAt(0) === '_') {
                        // return $.error('No such method ' + options + ' for Infinite Scroll');
                        return false;
                    }

                    // no errors!
                    instance[options].apply(instance, args);
                });

            break;

            // creation
            case 'object':

                this.each(function () {

                var instance = $.data(this, 'infinitescroll');

                if (instance) {

                    // update options of current instance
                    instance.update(options);

                } else {

                    // initialize new instance
                    instance = new $.infinitescroll(options, callback, this);

                    // don't attach if instantiation failed
                    if (!instance.failed) {
                        $.data(this, 'infinitescroll', instance);
                    }

                }

            });

            break;

        }

        return this;
    };



    /*
     * smartscroll: debounced scroll event for jQuery *
     * https://github.com/lukeshumard/smartscroll
     * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js *
     * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. *
     */

    var event = $.event,
    scrollTimeout;

    event.special.smartscroll = {
        setup: function () {
            $(this).bind('scroll', event.special.smartscroll.handler);
        },
        teardown: function () {
            $(this).unbind('scroll', event.special.smartscroll.handler);
        },
        handler: function (event, execAsap) {
            // Save the context
            var context = this,
            args = arguments;

            // set correct event type
            event.type = 'smartscroll';

            if (scrollTimeout) { clearTimeout(scrollTimeout); }
            scrollTimeout = setTimeout(function () {
                $(context).trigger('smartscroll', args);
            }, execAsap === 'execAsap' ? 0 : 100);
        }
    };

    $.fn.smartscroll = function (fn) {
        return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']);
    };

}));
;/*! http://mths.be/placeholder v2.0.7 by @mathias */
;(function(window, document, $) {

	var isInputSupported = 'placeholder' in document.createElement('input');
	var isTextareaSupported = 'placeholder' in document.createElement('textarea');
	var prototype = $.fn;
	var valHooks = $.valHooks;
	var propHooks = $.propHooks;
	var hooks;
	var placeholder;

	if (isInputSupported && isTextareaSupported) {

		placeholder = prototype.placeholder = function() {
			return this;
		};

		placeholder.input = placeholder.textarea = true;

	} else {

		placeholder = prototype.placeholder = function() {
			var $this = this;
			$this
				.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
				.not('.placeholder')
				.bind({
					'focus.placeholder': clearPlaceholder,
					'blur.placeholder': setPlaceholder
				})
				.data('placeholder-enabled', true)
				.trigger('blur.placeholder');
			return $this;
		};

		placeholder.input = isInputSupported;
		placeholder.textarea = isTextareaSupported;

		hooks = {
			'get': function(element) {
				var $element = $(element);

				var $passwordInput = $element.data('placeholder-password');
				if ($passwordInput) {
					return $passwordInput[0].value;
				}

				return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
			},
			'set': function(element, value) {
				var $element = $(element);

				var $passwordInput = $element.data('placeholder-password');
				if ($passwordInput) {
					return $passwordInput[0].value = value;
				}

				if (!$element.data('placeholder-enabled')) {
					return element.value = value;
				}
				if (value == '') {
					element.value = value;
					// Issue #56: Setting the placeholder causes problems if the element continues to have focus.
					if (element != safeActiveElement()) {
						// We can't use `triggerHandler` here because of dummy text/password inputs :(
						setPlaceholder.call(element);
					}
				} else if ($element.hasClass('placeholder')) {
					clearPlaceholder.call(element, true, value) || (element.value = value);
				} else {
					element.value = value;
				}
				// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
				return $element;
			}
		};

		if (!isInputSupported) {
			valHooks.input = hooks;
			propHooks.value = hooks;
		}
		if (!isTextareaSupported) {
			valHooks.textarea = hooks;
			propHooks.value = hooks;
		}

		$(function() {
			// Look for forms
			$(document).delegate('form', 'submit.placeholder', function() {
				// Clear the placeholder values so they don't get submitted
				var $inputs = $('.placeholder', this).each(clearPlaceholder);
				setTimeout(function() {
					$inputs.each(setPlaceholder);
				}, 10);
			});
		});

		// Clear placeholder values upon page reload
		$(window).bind('beforeunload.placeholder', function() {
			$('.placeholder').each(function() {
				this.value = '';
			});
		});

	}

	function args(elem) {
		// Return an object of element attributes
		var newAttrs = {};
		var rinlinejQuery = /^jQuery\d+$/;
		$.each(elem.attributes, function(i, attr) {
			if (attr.specified && !rinlinejQuery.test(attr.name)) {
				newAttrs[attr.name] = attr.value;
			}
		});
		return newAttrs;
	}

	function clearPlaceholder(event, value) {
		var input = this;
		var $input = $(input);
		if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
			if ($input.data('placeholder-password')) {
				$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
				// If `clearPlaceholder` was called from `$.valHooks.input.set`
				if (event === true) {
					return $input[0].value = value;
				}
				$input.focus();
			} else {
				input.value = '';
				$input.removeClass('placeholder');
				input == safeActiveElement() && input.select();
			}
		}
	}

	function setPlaceholder() {
		var $replacement;
		var input = this;
		var $input = $(input);
		var id = this.id;
		if (input.value == '') {
			if (input.type == 'password') {
				if (!$input.data('placeholder-textinput')) {
					try {
						$replacement = $input.clone().attr({ 'type': 'text' });
					} catch(e) {
						$replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
					}
					$replacement
						.removeAttr('name')
						.data({
							'placeholder-password': $input,
							'placeholder-id': id
						})
						.bind('focus.placeholder', clearPlaceholder);
					$input
						.data({
							'placeholder-textinput': $replacement,
							'placeholder-id': id
						})
						.before($replacement);
				}
				$input = $input.removeAttr('id').hide().prev().attr('id', id).show();
				// Note: `$input[0] != input` now!
			}
			$input.addClass('placeholder');
			$input[0].value = $input.attr('placeholder');
		} else {
			$input.removeClass('placeholder');
		}
	}

	function safeActiveElement() {
		// Avoid IE9 `document.activeElement` of death
		// https://github.com/mathiasbynens/jquery-placeholder/pull/99
		try {
			return document.activeElement;
		} catch (err) {}
	}

}(this, document, jQuery));;/*
|--------------------------------------------------------------------------
| UItoTop jQuery Plugin 1.2 by Matt Varone
| http://www.mattvarone.com/web-design/uitotop-jquery-plugin/
|--------------------------------------------------------------------------
*/
(function($){
	$.fn.UItoTop = function(options) {

 		var defaults = {
				text: '',
				min: 200,
				inDelay:600,
				outDelay:400,
	  			containerID: 'toTop',
				containerHoverID: 'toTopHover',
				scrollSpeed: 1200,
				easingType: 'linear'
 			},
			settings = $.extend(defaults, options),
			containerIDhash = '#' + settings.containerID,
			containerHoverIDHash = '#'+settings.containerHoverID;

		$('body').append('<div class="to-top-container"><a href="#" id="'+settings.containerID+'"><span class="screen-reader-text">'+toTopscreenReaderText.label+'</span>'+settings.text+'</a></div>');
		$(containerIDhash).hide().on('click.UItoTop',function(){
			$('html, body').animate({scrollTop:0}, settings.scrollSpeed, settings.easingType);
			$('#'+settings.containerHoverID, this).stop().animate({'opacity': 0 }, settings.inDelay, settings.easingType);
			return false;
		})
		.prepend('<span id="'+settings.containerHoverID+'"></span>')
		.hover(function() {
				$(containerHoverIDHash, this).stop().animate({
					'opacity': 1
				}, 600, 'linear');
			}, function() {
				$(containerHoverIDHash, this).stop().animate({
					'opacity': 0
				}, 700, 'linear');
			});

		$(window).scroll(function() {
			var sd = $(window).scrollTop();
			if(typeof document.body.style.maxHeight === "undefined") {
				$(containerIDhash).css({
					'position': 'absolute',
					'top': sd + $(window).height() - 50
				});
			}
			if ( sd > settings.min ) {
				$(containerIDhash).fadeIn(settings.inDelay);
			} else {
				$(containerIDhash).fadeOut(settings.Outdelay);
			}
		});
};
})(jQuery);
;// Generated by CoffeeScript 1.6.2
/*
jQuery Waypoints - v2.0.3
Copyright (c) 2011-2013 Caleb Troughton
Dual licensed under the MIT license and GPL license.
https://github.com/imakewebthings/jquery-waypoints/blob/master/licenses.txt
*/


(function() {
  var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
	__slice = [].slice;

  (function(root, factory) {
	if (typeof define === 'function' && define.amd) {
	  return define('waypoints', ['jquery'], function($) {
		return factory($, root);
	  });
	} else {
	  return factory(root.jQuery, root);
	}
  })(this, function($, window) {
	var $w, Context, Waypoint, allWaypoints, contextCounter, contextKey, contexts, isTouch, jQMethods, methods, resizeEvent, scrollEvent, waypointCounter, waypointKey, wp, wps;

	$w = $(window);
	isTouch = __indexOf.call(window, 'ontouchstart') >= 0;
	allWaypoints = {
	  horizontal: {},
	  vertical: {}
	};
	contextCounter = 1;
	contexts = {};
	contextKey = 'waypoints-context-id';
	resizeEvent = 'resize.waypoints';
	scrollEvent = 'scroll.waypoints';
	waypointCounter = 1;
	waypointKey = 'waypoints-waypoint-ids';
	wp = 'waypoint';
	wps = 'waypoints';
	Context = (function() {
	  function Context($element) {
		var _this = this;

		this.$element = $element;
		this.element = $element[0];
		this.didResize = false;
		this.didScroll = false;
		this.id = 'context' + contextCounter++;
		this.oldScroll = {
		  x: $element.scrollLeft(),
		  y: $element.scrollTop()
		};
		this.waypoints = {
		  horizontal: {},
		  vertical: {}
		};
		$element.data(contextKey, this.id);
		contexts[this.id] = this;
		$element.bind(scrollEvent, function() {
		  var scrollHandler;

		  if (!(_this.didScroll || isTouch)) {
			_this.didScroll = true;
			scrollHandler = function() {
			  _this.doScroll();
			  return _this.didScroll = false;
			};
			return window.setTimeout(scrollHandler, $[wps].settings.scrollThrottle);
		  }
		});
		$element.bind(resizeEvent, function() {
		  var resizeHandler;

		  if (!_this.didResize) {
			_this.didResize = true;
			resizeHandler = function() {
			  $[wps]('refresh');
			  return _this.didResize = false;
			};
			return window.setTimeout(resizeHandler, $[wps].settings.resizeThrottle);
		  }
		});
	  }

	  Context.prototype.doScroll = function() {
		var axes,
		  _this = this;

		axes = {
		  horizontal: {
			newScroll: this.$element.scrollLeft(),
			oldScroll: this.oldScroll.x,
			forward: 'right',
			backward: 'left'
		  },
		  vertical: {
			newScroll: this.$element.scrollTop(),
			oldScroll: this.oldScroll.y,
			forward: 'down',
			backward: 'up'
		  }
		};
		if (isTouch && (!axes.vertical.oldScroll || !axes.vertical.newScroll)) {
		  $[wps]('refresh');
		}
		$.each(axes, function(aKey, axis) {
		  var direction, isForward, triggered;

		  triggered = [];
		  isForward = axis.newScroll > axis.oldScroll;
		  direction = isForward ? axis.forward : axis.backward;
		  $.each(_this.waypoints[aKey], function(wKey, waypoint) {
			var _ref, _ref1;

			if ((axis.oldScroll < (_ref = waypoint.offset) && _ref <= axis.newScroll)) {
			  return triggered.push(waypoint);
			} else if ((axis.newScroll < (_ref1 = waypoint.offset) && _ref1 <= axis.oldScroll)) {
			  return triggered.push(waypoint);
			}
		  });
		  triggered.sort(function(a, b) {
			return a.offset - b.offset;
		  });
		  if (!isForward) {
			triggered.reverse();
		  }
		  return $.each(triggered, function(i, waypoint) {
			if (waypoint.options.continuous || i === triggered.length - 1) {
			  return waypoint.trigger([direction]);
			}
		  });
		});
		return this.oldScroll = {
		  x: axes.horizontal.newScroll,
		  y: axes.vertical.newScroll
		};
	  };

	  Context.prototype.refresh = function() {
		var axes, cOffset, isWin,
		  _this = this;

		isWin = $.isWindow(this.element);
		cOffset = this.$element.offset();
		this.doScroll();
		axes = {
		  horizontal: {
			contextOffset: isWin ? 0 : cOffset.left,
			contextScroll: isWin ? 0 : this.oldScroll.x,
			contextDimension: this.$element.width(),
			oldScroll: this.oldScroll.x,
			forward: 'right',
			backward: 'left',
			offsetProp: 'left'
		  },
		  vertical: {
			contextOffset: isWin ? 0 : cOffset.top,
			contextScroll: isWin ? 0 : this.oldScroll.y,
			contextDimension: isWin ? $[wps]('viewportHeight') : this.$element.height(),
			oldScroll: this.oldScroll.y,
			forward: 'down',
			backward: 'up',
			offsetProp: 'top'
		  }
		};
		return $.each(axes, function(aKey, axis) {
		  return $.each(_this.waypoints[aKey], function(i, waypoint) {
			var adjustment, elementOffset, oldOffset, _ref, _ref1;

			adjustment = waypoint.options.offset;
			oldOffset = waypoint.offset;
			elementOffset = $.isWindow(waypoint.element) ? 0 : waypoint.$element.offset()[axis.offsetProp];
			if ($.isFunction(adjustment)) {
			  adjustment = adjustment.apply(waypoint.element);
			} else if (typeof adjustment === 'string') {
			  adjustment = parseFloat(adjustment);
			  if (waypoint.options.offset.indexOf('%') > -1) {
				adjustment = Math.ceil(axis.contextDimension * adjustment / 100);
			  }
			}
			waypoint.offset = elementOffset - axis.contextOffset + axis.contextScroll - adjustment;
			if ((waypoint.options.onlyOnScroll && (oldOffset != null)) || !waypoint.enabled) {
			  return;
			}
			if (oldOffset !== null && (oldOffset < (_ref = axis.oldScroll) && _ref <= waypoint.offset)) {
			  return waypoint.trigger([axis.backward]);
			} else if (oldOffset !== null && (oldOffset > (_ref1 = axis.oldScroll) && _ref1 >= waypoint.offset)) {
			  return waypoint.trigger([axis.forward]);
			} else if (oldOffset === null && axis.oldScroll >= waypoint.offset) {
			  return waypoint.trigger([axis.forward]);
			}
		  });
		});
	  };

	  Context.prototype.checkEmpty = function() {
		if ($.isEmptyObject(this.waypoints.horizontal) && $.isEmptyObject(this.waypoints.vertical)) {
		  this.$element.unbind([resizeEvent, scrollEvent].join(' '));
		  return delete contexts[this.id];
		}
	  };

	  return Context;

	})();
	Waypoint = (function() {
	  function Waypoint($element, context, options) {
		var idList, _ref;

		options = $.extend({}, $.fn[wp].defaults, options);
		if (options.offset === 'bottom-in-view') {
		  options.offset = function() {
			var contextHeight;

			contextHeight = $[wps]('viewportHeight');
			if (!$.isWindow(context.element)) {
			  contextHeight = context.$element.height();
			}
			return contextHeight - $(this).outerHeight();
		  };
		}
		this.$element = $element;
		this.element = $element[0];
		this.axis = options.horizontal ? 'horizontal' : 'vertical';
		this.callback = options.handler;
		this.context = context;
		this.enabled = options.enabled;
		this.id = 'waypoints' + waypointCounter++;
		this.offset = null;
		this.options = options;
		context.waypoints[this.axis][this.id] = this;
		allWaypoints[this.axis][this.id] = this;
		idList = (_ref = $element.data(waypointKey)) != null ? _ref : [];
		idList.push(this.id);
		$element.data(waypointKey, idList);
	  }

	  Waypoint.prototype.trigger = function(args) {
		if (!this.enabled) {
		  return;
		}
		if (this.callback != null) {
		  this.callback.apply(this.element, args);
		}
		if (this.options.triggerOnce) {
		  return this.destroy();
		}
	  };

	  Waypoint.prototype.disable = function() {
		return this.enabled = false;
	  };

	  Waypoint.prototype.enable = function() {
		this.context.refresh();
		return this.enabled = true;
	  };

	  Waypoint.prototype.destroy = function() {
		delete allWaypoints[this.axis][this.id];
		delete this.context.waypoints[this.axis][this.id];
		return this.context.checkEmpty();
	  };

	  Waypoint.getWaypointsByElement = function(element) {
		var all, ids;

		ids = $(element).data(waypointKey);
		if (!ids) {
		  return [];
		}
		all = $.extend({}, allWaypoints.horizontal, allWaypoints.vertical);
		return $.map(ids, function(id) {
		  return all[id];
		});
	  };

	  return Waypoint;

	})();
	methods = {
	  init: function(f, options) {
		var _ref;

		if (options == null) {
		  options = {};
		}
		if ((_ref = options.handler) == null) {
		  options.handler = f;
		}
		this.each(function() {
		  var $this, context, contextElement, _ref1;

		  $this = $(this);
		  contextElement = (_ref1 = options.context) != null ? _ref1 : $.fn[wp].defaults.context;
		  if (!$.isWindow(contextElement)) {
			contextElement = $this.closest(contextElement);
		  }
		  contextElement = $(contextElement);
		  context = contexts[contextElement.data(contextKey)];
		  if (!context) {
			context = new Context(contextElement);
		  }
		  return new Waypoint($this, context, options);
		});
		$[wps]('refresh');
		return this;
	  },
	  disable: function() {
		return methods._invoke(this, 'disable');
	  },
	  enable: function() {
		return methods._invoke(this, 'enable');
	  },
	  destroy: function() {
		return methods._invoke(this, 'destroy');
	  },
	  prev: function(axis, selector) {
		return methods._traverse.call(this, axis, selector, function(stack, index, waypoints) {
		  if (index > 0) {
			return stack.push(waypoints[index - 1]);
		  }
		});
	  },
	  next: function(axis, selector) {
		return methods._traverse.call(this, axis, selector, function(stack, index, waypoints) {
		  if (index < waypoints.length - 1) {
			return stack.push(waypoints[index + 1]);
		  }
		});
	  },
	  _traverse: function(axis, selector, push) {
		var stack, waypoints;

		if (axis == null) {
		  axis = 'vertical';
		}
		if (selector == null) {
		  selector = window;
		}
		waypoints = jQMethods.aggregate(selector);
		stack = [];
		this.each(function() {
		  var index;

		  index = $.inArray(this, waypoints[axis]);
		  return push(stack, index, waypoints[axis]);
		});
		return this.pushStack(stack);
	  },
	  _invoke: function($elements, method) {
		$elements.each(function() {
		  var waypoints;

		  waypoints = Waypoint.getWaypointsByElement(this);
		  return $.each(waypoints, function(i, waypoint) {
			waypoint[method]();
			return true;
		  });
		});
		return this;
	  }
	};
	$.fn[wp] = function() {
	  var args, method;

	  method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
	  if (methods[method]) {
		return methods[method].apply(this, args);
	  } else if ($.isFunction(method)) {
		return methods.init.apply(this, arguments);
	  } else if ($.isPlainObject(method)) {
		return methods.init.apply(this, [null, method]);
	  } else if (!method) {
		return $.error("jQuery Waypoints needs a callback function or handler option.");
	  } else {
		return $.error("The " + method + " method does not exist in jQuery Waypoints.");
	  }
	};
	$.fn[wp].defaults = {
	  context: window,
	  continuous: true,
	  enabled: true,
	  horizontal: false,
	  offset: 0,
	  triggerOnce: false
	};
	jQMethods = {
	  refresh: function() {
		return $.each(contexts, function(i, context) {
		  return context.refresh();
		});
	  },
	  viewportHeight: function() {
		var _ref;

		return (_ref = window.innerHeight) != null ? _ref : $w.height();
	  },
	  aggregate: function(contextSelector) {
		var collection, waypoints, _ref;

		collection = allWaypoints;
		if (contextSelector) {
		  collection = (_ref = contexts[$(contextSelector).data(contextKey)]) != null ? _ref.waypoints : void 0;
		}
		if (!collection) {
		  return [];
		}
		waypoints = {
		  horizontal: [],
		  vertical: []
		};
		$.each(waypoints, function(axis, arr) {
		  $.each(collection[axis], function(key, waypoint) {
			return arr.push(waypoint);
		  });
		  arr.sort(function(a, b) {
			return a.offset - b.offset;
		  });
		  waypoints[axis] = $.map(arr, function(waypoint) {
			return waypoint.element;
		  });
		  return waypoints[axis] = $.unique(waypoints[axis]);
		});
		return waypoints;
	  },
	  above: function(contextSelector) {
		if (contextSelector == null) {
		  contextSelector = window;
		}
		return jQMethods._filter(contextSelector, 'vertical', function(context, waypoint) {
		  return waypoint.offset <= context.oldScroll.y;
		});
	  },
	  below: function(contextSelector) {
		if (contextSelector == null) {
		  contextSelector = window;
		}
		return jQMethods._filter(contextSelector, 'vertical', function(context, waypoint) {
		  return waypoint.offset > context.oldScroll.y;
		});
	  },
	  left: function(contextSelector) {
		if (contextSelector == null) {
		  contextSelector = window;
		}
		return jQMethods._filter(contextSelector, 'horizontal', function(context, waypoint) {
		  return waypoint.offset <= context.oldScroll.x;
		});
	  },
	  right: function(contextSelector) {
		if (contextSelector == null) {
		  contextSelector = window;
		}
		return jQMethods._filter(contextSelector, 'horizontal', function(context, waypoint) {
		  return waypoint.offset > context.oldScroll.x;
		});
	  },
	  enable: function() {
		return jQMethods._invoke('enable');
	  },
	  disable: function() {
		return jQMethods._invoke('disable');
	  },
	  destroy: function() {
		return jQMethods._invoke('destroy');
	  },
	  extendFn: function(methodName, f) {
		return methods[methodName] = f;
	  },
	  _invoke: function(method) {
		var waypoints;

		waypoints = $.extend({}, allWaypoints.vertical, allWaypoints.horizontal);
		return $.each(waypoints, function(key, waypoint) {
		  waypoint[method]();
		  return true;
		});
	  },
	  _filter: function(selector, axis, test) {
		var context, waypoints;

		context = contexts[$(selector).data(contextKey)];
		if (!context) {
		  return [];
		}
		waypoints = [];
		$.each(context.waypoints[axis], function(i, waypoint) {
		  if (test(context, waypoint)) {
			return waypoints.push(waypoint);
		  }
		});
		waypoints.sort(function(a, b) {
		  return a.offset - b.offset;
		});
		return $.map(waypoints, function(waypoint) {
		  return waypoint.element;
		});
	  }
	};
	$[wps] = function() {
	  var args, method;

	  method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
	  if (jQMethods[method]) {
		return jQMethods[method].apply(null, args);
	  } else {
		return jQMethods.aggregate.call(null, method);
	  }
	};
	$[wps].settings = {
	  resizeThrottle: 100,
	  scrollThrottle: 30
	};
	return $w.load(function() {
	  return $[wps]('refresh');
	});
  });

}).call(this);;/*!
 * modernizr v3.3.1
 * Build http://modernizr.com/download?-applicationcache-audio-backgroundsize-borderimage-borderradius-boxshadow-canvas-canvastext-cssanimations-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-flexbox-fontface-generatedcontent-geolocation-hashchange-history-hsla-indexeddb-inlinesvg-input-inputtypes-localstorage-multiplebgs-opacity-postmessage-rgba-sessionstorage-smil-svgclippaths-textshadow-touchevents-video-webgl-websockets-websqldatabase-webworkers-addtest-domprefixes-hasevent-mq-prefixed-prefixes-setclasses-testallprops-testprop-teststyles-dontmin
 *
 * Copyright (c)
 *  Faruk Ates
 *  Paul Irish
 *  Alex Sexton
 *  Ryan Seddon
 *  Patrick Kettner
 *  Stu Cox
 *  Richard Herrera

 * MIT License
 */

/*
 * Modernizr tests which native CSS3 and HTML5 features are available in the
 * current UA and makes the results available to you in two ways: as properties on
 * a global `Modernizr` object, and as classes on the `<html>` element. This
 * information allows you to progressively enhance your pages with a granular level
 * of control over the experience.
*/

;(function(window, document, undefined){
  var classes = [];


  var tests = [];


  /**
   *
   * ModernizrProto is the constructor for Modernizr
   *
   * @class
   * @access public
   */

  var ModernizrProto = {
    // The current version, dummy
    _version: '3.3.1',

    // Any settings that don't work as separate modules
    // can go in here as configuration.
    _config: {
      'classPrefix': '',
      'enableClasses': true,
      'enableJSClass': true,
      'usePrefixes': true
    },

    // Queue of tests
    _q: [],

    // Stub these for people who are listening
    on: function(test, cb) {
      // I don't really think people should do this, but we can
      // safe guard it a bit.
      // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests.
      // This is in case people listen to synchronous tests. I would leave it out,
      // but the code to *disallow* sync tests in the real version of this
      // function is actually larger than this.
      var self = this;
      setTimeout(function() {
        cb(self[test]);
      }, 0);
    },

    addTest: function(name, fn, options) {
      tests.push({name: name, fn: fn, options: options});
    },

    addAsyncTest: function(fn) {
      tests.push({name: null, fn: fn});
    }
  };



  // Fake some of Object.create so we can force non test results to be non "own" properties.
  var Modernizr = function() {};
  Modernizr.prototype = ModernizrProto;

  // Leak modernizr globally when you `require` it rather than force it here.
  // Overwrite name so constructor name is nicer :D
  Modernizr = new Modernizr();


/*!
{
  "name": "Application Cache",
  "property": "applicationcache",
  "caniuse": "offline-apps",
  "tags": ["storage", "offline"],
  "notes": [{
    "name": "MDN documentation",
    "href": "https://developer.mozilla.org/en/docs/HTML/Using_the_application_cache"
  }],
  "polyfills": ["html5gears"]
}
!*/
/* DOC
Detects support for the Application Cache, for storing data to enable web-based applications run offline.

The API has been [heavily criticized](http://alistapart.com/article/application-cache-is-a-douchebag) and discussions are underway to address this.
*/

  Modernizr.addTest('applicationcache', 'applicationCache' in window);

/*!
{
  "name": "Geolocation API",
  "property": "geolocation",
  "caniuse": "geolocation",
  "tags": ["media"],
  "notes": [{
    "name": "MDN documentation",
    "href": "https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation"
  }],
  "polyfills": [
    "joshuabell-polyfill",
    "webshims",
    "geo-location-javascript",
    "geolocation-api-polyfill"
  ]
}
!*/
/* DOC
Detects support for the Geolocation API for users to provide their location to web applications.
*/

  // geolocation is often considered a trivial feature detect...
  // Turns out, it's quite tricky to get right:
  //
  // Using !!navigator.geolocation does two things we don't want. It:
  //   1. Leaks memory in IE9: github.com/Modernizr/Modernizr/issues/513
  //   2. Disables page caching in WebKit: webk.it/43956
  //
  // Meanwhile, in Firefox < 8, an about:config setting could expose
  // a false positive that would throw an exception: bugzil.la/688158

  Modernizr.addTest('geolocation', 'geolocation' in navigator);

/*!
{
  "name": "History API",
  "property": "history",
  "caniuse": "history",
  "tags": ["history"],
  "authors": ["Hay Kranen", "Alexander Farkas"],
  "notes": [{
    "name": "W3C Spec",
    "href": "https://www.w3.org/TR/html51/browsers.html#the-history-interface"
  }, {
    "name": "MDN documentation",
    "href": "https://developer.mozilla.org/en-US/docs/Web/API/window.history"
  }],
  "polyfills": ["historyjs", "html5historyapi"]
}
!*/
/* DOC
Detects support for the History API for manipulating the browser session history.
*/

  Modernizr.addTest('history', function() {
    // Issue #733
    // The stock browser on Android 2.2 & 2.3, and 4.0.x returns positive on history support
    // Unfortunately support is really buggy and there is no clean way to detect
    // these bugs, so we fall back to a user agent sniff :(
    var ua = navigator.userAgent;

    // We only want Android 2 and 4.0, stock browser, and not Chrome which identifies
    // itself as 'Mobile Safari' as well, nor Windows Phone (issue #1471).
    if ((ua.indexOf('Android 2.') !== -1 ||
        (ua.indexOf('Android 4.0') !== -1)) &&
        ua.indexOf('Mobile Safari') !== -1 &&
        ua.indexOf('Chrome') === -1 &&
        ua.indexOf('Windows Phone') === -1) {
      return false;
    }

    // Return the regular check
    return (window.history && 'pushState' in window.history);
  });

/*!
{
  "name": "postMessage",
  "property": "postmessage",
  "caniuse": "x-doc-messaging",
  "notes": [{
    "name": "W3C Spec",
    "href": "http://www.w3.org/TR/html5/comms.html#posting-messages"
  }],
  "polyfills": ["easyxdm", "postmessage-jquery"]
}
!*/
/* DOC
Detects support for the `window.postMessage` protocol for cross-document messaging.
*/

  Modernizr.addTest('postmessage', 'postMessage' in window);

/*!
{
  "name": "WebSockets Support",
  "property": "websockets",
  "authors": ["Phread [fearphage]", "Mike Sherov [mikesherov]", "Burak Yigit Kaya [BYK]"],
  "caniuse": "websockets",
  "tags": ["html5"],
  "warnings": [
    "This test will reject any old version of WebSockets even if it is not prefixed such as in Safari 5.1"
  ],
  "notes": [{
    "name": "CLOSING State and Spec",
    "href": "https://www.w3.org/TR/websockets/#the-websocket-interface"
  }],
  "polyfills": [
    "sockjs",
    "socketio",
    "kaazing-websocket-gateway",
    "websocketjs",
    "atmosphere",
    "graceful-websocket",
    "portal",
    "datachannel"
  ]
}
!*/

  Modernizr.addTest('websockets', 'WebSocket' in window && window.WebSocket.CLOSING === 2);

/*!
{
  "name": "Local Storage",
  "property": "localstorage",
  "caniuse": "namevalue-storage",
  "tags": ["storage"],
  "knownBugs": [],
  "notes": [],
  "warnings": [],
  "polyfills": [
    "joshuabell-polyfill",
    "cupcake",
    "storagepolyfill",
    "amplifyjs",
    "yui-cacheoffline"
  ]
}
!*/

  // In FF4, if disabled, window.localStorage should === null.

  // Normally, we could not test that directly and need to do a
  //   `('localStorage' in window) && ` test first because otherwise Firefox will
  //   throw bugzil.la/365772 if cookies are disabled

  // Also in iOS5 Private Browsing mode, attempting to use localStorage.setItem
  // will throw the exception:
  //   QUOTA_EXCEEDED_ERROR DOM Exception 22.
  // Peculiarly, getItem and removeItem calls do not throw.

  // Because we are forced to try/catch this, we'll go aggressive.

  // Just FWIW: IE8 Compat mode supports these features completely:
  //   www.quirksmode.org/dom/html5.html
  // But IE8 doesn't support either with local files

  Modernizr.addTest('localstorage', function() {
    var mod = 'modernizr';
    try {
      localStorage.setItem(mod, mod);
      localStorage.removeItem(mod);
      return true;
    } catch (e) {
      return false;
    }
  });

/*!
{
  "name": "Session Storage",
  "property": "sessionstorage",
  "tags": ["storage"],
  "polyfills": ["joshuabell-polyfill", "cupcake", "sessionstorage"]
}
!*/

  // Because we are forced to try/catch this, we'll go aggressive.

  // Just FWIW: IE8 Compat mode supports these features completely:
  //   www.quirksmode.org/dom/html5.html
  // But IE8 doesn't support either with local files
  Modernizr.addTest('sessionstorage', function() {
    var mod = 'modernizr';
    try {
      sessionStorage.setItem(mod, mod);
      sessionStorage.removeItem(mod);
      return true;
    } catch (e) {
      return false;
    }
  });

/*!
{
  "name": "Web SQL Database",
  "property": "websqldatabase",
  "caniuse": "sql-storage",
  "tags": ["storage"]
}
!*/

  // Chrome incognito mode used to throw an exception when using openDatabase
  // It doesn't anymore.
  Modernizr.addTest('websqldatabase', 'openDatabase' in window);

/*!
{
  "name": "Web Workers",
  "property": "webworkers",
  "caniuse" : "webworkers",
  "tags": ["performance", "workers"],
  "notes": [{
    "name": "W3C Reference",
    "href": "https://www.w3.org/TR/workers/"
  }, {
    "name": "HTML5 Rocks article",
    "href": "http://www.html5rocks.com/en/tutorials/workers/basics/"
  }, {
    "name": "MDN documentation",
    "href": "https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers"
  }],
  "polyfills": ["fakeworker", "html5shims"]
}
!*/
/* DOC
Detects support for the basic `Worker` API from the Web Workers spec. Web Workers provide a simple means for web content to run scripts in background threads.
*/

  Modernizr.addTest('webworkers', 'Worker' in window);


  /**
   * List of property values to set for css tests. See ticket #21
   * http://git.io/vUGl4
   *
   * @memberof Modernizr
   * @name Modernizr._prefixes
   * @optionName Modernizr._prefixes
   * @optionProp prefixes
   * @access public
   * @example
   *
   * Modernizr._prefixes is the internal list of prefixes that we test against
   * inside of things like [prefixed](#modernizr-prefixed) and [prefixedCSS](#-code-modernizr-prefixedcss). It is simply
   * an array of kebab-case vendor prefixes you can use within your code.
   *
   * Some common use cases include
   *
   * Generating all possible prefixed version of a CSS property
   * ```js
   * var rule = Modernizr._prefixes.join('transform: rotate(20deg); ');
   *
   * rule === 'transform: rotate(20deg); webkit-transform: rotate(20deg); moz-transform: rotate(20deg); o-transform: rotate(20deg); ms-transform: rotate(20deg);'
   * ```
   *
   * Generating all possible prefixed version of a CSS value
   * ```js
   * rule = 'display:' +  Modernizr._prefixes.join('flex; display:') + 'flex';
   *
   * rule === 'display:flex; display:-webkit-flex; display:-moz-flex; display:-o-flex; display:-ms-flex; display:flex'
   * ```
   */

  // we use ['',''] rather than an empty array in order to allow a pattern of .`join()`ing prefixes to test
  // values in feature detects to continue to work
  var prefixes = (ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : ['','']);

  // expose these for the plugin API. Look in the source for how to join() them against your input
  ModernizrProto._prefixes = prefixes;



  /**
   * is returns a boolean if the typeof an obj is exactly type.
   *
   * @access private
   * @function is
   * @param {*} obj - A thing we want to check the type of
   * @param {string} type - A string to compare the typeof against
   * @returns {boolean}
   */

  function is(obj, type) {
    return typeof obj === type;
  }
  ;

  /**
   * Run through all tests and detect their support in the current UA.
   *
   * @access private
   */

  function testRunner() {
    var featureNames;
    var feature;
    var aliasIdx;
    var result;
    var nameIdx;
    var featureName;
    var featureNameSplit;

    for (var featureIdx in tests) {
      if (tests.hasOwnProperty(featureIdx)) {
        featureNames = [];
        feature = tests[featureIdx];
        // run the test, throw the return value into the Modernizr,
        // then based on that boolean, define an appropriate className
        // and push it into an array of classes we'll join later.
        //
        // If there is no name, it's an 'async' test that is run,
        // but not directly added to the object. That should
        // be done with a post-run addTest call.
        if (feature.name) {
          featureNames.push(feature.name.toLowerCase());

          if (feature.options && feature.options.aliases && feature.options.aliases.length) {
            // Add all the aliases into the names list
            for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {
              featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());
            }
          }
        }

        // Run the test, or use the raw value if it's not a function
        result = is(feature.fn, 'function') ? feature.fn() : feature.fn;


        // Set each of the names on the Modernizr object
        for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {
          featureName = featureNames[nameIdx];
          // Support dot properties as sub tests. We don't do checking to make sure
          // that the implied parent tests have been added. You must call them in
          // order (either in the test, or make the parent test a dependency).
          //
          // Cap it to TWO to make the logic simple and because who needs that kind of subtesting
          // hashtag famous last words
          featureNameSplit = featureName.split('.');

          if (featureNameSplit.length === 1) {
            Modernizr[featureNameSplit[0]] = result;
          } else {
            // cast to a Boolean, if not one already
            /* jshint -W053 */
            if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
              Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
            }

            Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
          }

          classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
        }
      }
    }
  }
  ;

  /**
   * docElement is a convenience wrapper to grab the root element of the document
   *
   * @access private
   * @returns {HTMLElement|SVGElement} The root element of the document
   */

  var docElement = document.documentElement;


  /**
   * A convenience helper to check if the document we are running in is an SVG document
   *
   * @access private
   * @returns {boolean}
   */

  var isSVG = docElement.nodeName.toLowerCase() === 'svg';


  /**
   * setClasses takes an array of class names and adds them to the root element
   *
   * @access private
   * @function setClasses
   * @param {string[]} classes - Array of class names
   */

  // Pass in an and array of class names, e.g.:
  //  ['no-webp', 'borderradius', ...]
  function setClasses(classes) {
    var className = docElement.className;
    var classPrefix = Modernizr._config.classPrefix || '';

    if (isSVG) {
      className = className.baseVal;
    }

    // Change `no-js` to `js` (independently of the `enableClasses` option)
    // Handle classPrefix on this too
    if (Modernizr._config.enableJSClass) {
      var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)');
      className = className.replace(reJS, '$1' + classPrefix + 'js$2');
    }

    if (Modernizr._config.enableClasses) {
      // Add the new classes
      className += ' ' + classPrefix + classes.join(' ' + classPrefix);
      isSVG ? docElement.className.baseVal = className : docElement.className = className;
    }

  }

  ;

  /**
   * If the browsers follow the spec, then they would expose vendor-specific style as:
   *   elem.style.WebkitBorderRadius
   * instead of something like the following, which would be technically incorrect:
   *   elem.style.webkitBorderRadius

   * Webkit ghosts their properties in lowercase but Opera & Moz do not.
   * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
   *   erik.eae.net/archives/2008/03/10/21.48.10/

   * More here: github.com/Modernizr/Modernizr/issues/issue/21
   *
   * @access private
   * @returns {string} The string representing the vendor-specific style properties
   */

  var omPrefixes = 'Moz O ms Webkit';


  /**
   * List of JavaScript DOM values used for tests
   *
   * @memberof Modernizr
   * @name Modernizr._domPrefixes
   * @optionName Modernizr._domPrefixes
   * @optionProp domPrefixes
   * @access public
   * @example
   *
   * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather
   * than kebab-case properties, all properties are their Capitalized variant
   *
   * ```js
   * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ];
   * ```
   */

  var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []);
  ModernizrProto._domPrefixes = domPrefixes;


  /**
   * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support
   *
   * @author kangax
   * @access private
   * @function hasOwnProp
   * @param {object} object - The object to check for a property
   * @param {string} property - The property to check for
   * @returns {boolean}
   */

  // hasOwnProperty shim by kangax needed for Safari 2.0 support
  var hasOwnProp;

  (function() {
    var _hasOwnProperty = ({}).hasOwnProperty;
    /* istanbul ignore else */
    /* we have no way of testing IE 5.5 or safari 2,
     * so just assume the else gets hit */
    if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {
      hasOwnProp = function(object, property) {
        return _hasOwnProperty.call(object, property);
      };
    }
    else {
      hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
        return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
      };
    }
  })();




   // _l tracks listeners for async tests, as well as tests that execute after the initial run
  ModernizrProto._l = {};

  /**
   * Modernizr.on is a way to listen for the completion of async tests. Being
   * asynchronous, they may not finish before your scripts run. As a result you
   * will get a possibly false negative `undefined` value.
   *
   * @memberof Modernizr
   * @name Modernizr.on
   * @access public
   * @function on
   * @param {string} feature - String name of the feature detect
   * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not
   * @example
   *
   * ```js
   * Modernizr.on('flash', function( result ) {
   *   if (result) {
   *    // the browser has flash
   *   } else {
   *     // the browser does not have flash
   *   }
   * });
   * ```
   */

  ModernizrProto.on = function(feature, cb) {
    // Create the list of listeners if it doesn't exist
    if (!this._l[feature]) {
      this._l[feature] = [];
    }

    // Push this test on to the listener list
    this._l[feature].push(cb);

    // If it's already been resolved, trigger it on next tick
    if (Modernizr.hasOwnProperty(feature)) {
      // Next Tick
      setTimeout(function() {
        Modernizr._trigger(feature, Modernizr[feature]);
      }, 0);
    }
  };

  /**
   * _trigger is the private function used to signal test completion and run any
   * callbacks registered through [Modernizr.on](#modernizr-on)
   *
   * @memberof Modernizr
   * @name Modernizr._trigger
   * @access private
   * @function _trigger
   * @param {string} feature - string name of the feature detect
   * @param {function|boolean} [res] - A feature detection function, or the boolean =
   * result of a feature detection function
   */

  ModernizrProto._trigger = function(feature, res) {
    if (!this._l[feature]) {
      return;
    }

    var cbs = this._l[feature];

    // Force async
    setTimeout(function() {
      var i, cb;
      for (i = 0; i < cbs.length; i++) {
        cb = cbs[i];
        cb(res);
      }
    }, 0);

    // Don't trigger these again
    delete this._l[feature];
  };

  /**
   * addTest allows you to define your own feature detects that are not currently
   * included in Modernizr (under the covers it's the exact same code Modernizr
   * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result
   * will be added onto the Modernizr object, as well as an appropriate className set on
   * the html element when configured to do so
   *
   * @memberof Modernizr
   * @name Modernizr.addTest
   * @optionName Modernizr.addTest()
   * @optionProp addTest
   * @access public
   * @function addTest
   * @param {string|object} feature - The string name of the feature detect, or an
   * object of feature detect names and test
   * @param {function|boolean} test - Function returning true if feature is supported,
   * false if not. Otherwise a boolean representing the results of a feature detection
   * @example
   *
   * The most common way of creating your own feature detects is by calling
   * `Modernizr.addTest` with a string (preferably just lowercase, without any
   * punctuation), and a function you want executed that will return a boolean result
   *
   * ```js
   * Modernizr.addTest('itsTuesday', function() {
   *  var d = new Date();
   *  return d.getDay() === 2;
   * });
   * ```
   *
   * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday,
   * and to `false` every other day of the week. One thing to notice is that the names of
   * feature detect functions are always lowercased when added to the Modernizr object. That
   * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will.
   *
   *
   *  Since we only look at the returned value from any feature detection function,
   *  you do not need to actually use a function. For simple detections, just passing
   *  in a statement that will return a boolean value works just fine.
   *
   * ```js
   * Modernizr.addTest('hasJquery', 'jQuery' in window);
   * ```
   *
   * Just like before, when the above runs `Modernizr.hasjquery` will be true if
   * jQuery has been included on the page. Not using a function saves a small amount
   * of overhead for the browser, as well as making your code much more readable.
   *
   * Finally, you also have the ability to pass in an object of feature names and
   * their tests. This is handy if you want to add multiple detections in one go.
   * The keys should always be a string, and the value can be either a boolean or
   * function that returns a boolean.
   *
   * ```js
   * var detects = {
   *  'hasjquery': 'jQuery' in window,
   *  'itstuesday': function() {
   *    var d = new Date();
   *    return d.getDay() === 2;
   *  }
   * }
   *
   * Modernizr.addTest(detects);
   * ```
   *
   * There is really no difference between the first methods and this one, it is
   * just a convenience to let you write more readable code.
   */

  function addTest(feature, test) {

    if (typeof feature == 'object') {
      for (var key in feature) {
        if (hasOwnProp(feature, key)) {
          addTest(key, feature[ key ]);
        }
      }
    } else {

      feature = feature.toLowerCase();
      var featureNameSplit = feature.split('.');
      var last = Modernizr[featureNameSplit[0]];

      // Again, we don't check for parent test existence. Get that right, though.
      if (featureNameSplit.length == 2) {
        last = last[featureNameSplit[1]];
      }

      if (typeof last != 'undefined') {
        // we're going to quit if you're trying to overwrite an existing test
        // if we were to allow it, we'd do this:
        //   var re = new RegExp("\\b(no-)?" + feature + "\\b");
        //   docElement.className = docElement.className.replace( re, '' );
        // but, no rly, stuff 'em.
        return Modernizr;
      }

      test = typeof test == 'function' ? test() : test;

      // Set the value (this is the magic, right here).
      if (featureNameSplit.length == 1) {
        Modernizr[featureNameSplit[0]] = test;
      } else {
        // cast to a Boolean, if not one already
        /* jshint -W053 */
        if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
          Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
        }

        Modernizr[featureNameSplit[0]][featureNameSplit[1]] = test;
      }

      // Set a single class (either `feature` or `no-feature`)
      /* jshint -W041 */
      setClasses([(!!test && test != false ? '' : 'no-') + featureNameSplit.join('-')]);
      /* jshint +W041 */

      // Trigger the event
      Modernizr._trigger(feature, test);
    }

    return Modernizr; // allow chaining.
  }

  // After all the tests are run, add self to the Modernizr prototype
  Modernizr._q.push(function() {
    ModernizrProto.addTest = addTest;
  });




  /**
   * createElement is a convenience wrapper around document.createElement. Since we
   * use createElement all over the place, this allows for (slightly) smaller code
   * as well as abstracting away issues with creating elements in contexts other than
   * HTML documents (e.g. SVG documents).
   *
   * @access private
   * @function createElement
   * @returns {HTMLElement|SVGElement} An HTML or SVG element
   */

  function createElement() {
    if (typeof document.createElement !== 'function') {
      // This is the case in IE7, where the type of createElement is "object".
      // For this reason, we cannot call apply() as Object is not a Function.
      return document.createElement(arguments[0]);
    } else if (isSVG) {
      return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]);
    } else {
      return document.createElement.apply(document, arguments);
    }
  }

  ;

  /**
   * Modernizr.hasEvent() detects support for a given event
   *
   * @memberof Modernizr
   * @name Modernizr.hasEvent
   * @optionName Modernizr.hasEvent()
   * @optionProp hasEvent
   * @access public
   * @function hasEvent
   * @param  {string|*} eventName - the name of an event to test for (e.g. "resize")
   * @param  {Element|string} [element=HTMLDivElement] - is the element|document|window|tagName to test on
   * @returns {boolean}
   * @example
   *  `Modernizr.hasEvent` lets you determine if the browser supports a supplied event.
   *  By default, it does this detection on a div element
   *
   * ```js
   *  hasEvent('blur') // true;
   * ```
   *
   * However, you are able to give an object as a second argument to hasEvent to
   * detect an event on something other than a div.
   *
   * ```js
   *  hasEvent('devicelight', window) // true;
   * ```
   *
   */

  var hasEvent = (function() {

    // Detect whether event support can be detected via `in`. Test on a DOM element
    // using the "blur" event b/c it should always exist. bit.ly/event-detection
    var needsFallback = !('onblur' in document.documentElement);

    function inner(eventName, element) {

      var isSupported;
      if (!eventName) { return false; }
      if (!element || typeof element === 'string') {
        element = createElement(element || 'div');
      }

      // Testing via the `in` operator is sufficient for modern browsers and IE.
      // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and
      // "resize", whereas `in` "catches" those.
      eventName = 'on' + eventName;
      isSupported = eventName in element;

      // Fallback technique for old Firefox - bit.ly/event-detection
      if (!isSupported && needsFallback) {
        if (!element.setAttribute) {
          // Switch to generic element if it lacks `setAttribute`.
          // It could be the `document`, `window`, or something else.
          element = createElement('div');
        }

        element.setAttribute(eventName, '');
        isSupported = typeof element[eventName] === 'function';

        if (element[eventName] !== undefined) {
          // If property was created, "remove it" by setting value to `undefined`.
          element[eventName] = undefined;
        }
        element.removeAttribute(eventName);
      }

      return isSupported;
    }
    return inner;
  })();


  ModernizrProto.hasEvent = hasEvent;

/*!
{
  "name": "Hashchange event",
  "property": "hashchange",
  "caniuse": "hashchange",
  "tags": ["history"],
  "notes": [{
    "name": "MDN documentation",
    "href": "https://developer.mozilla.org/en-US/docs/Web/API/window.onhashchange"
  }],
  "polyfills": [
    "jquery-hashchange",
    "moo-historymanager",
    "jquery-ajaxy",
    "hasher",
    "shistory"
  ]
}
!*/
/* DOC
Detects support for the `hashchange` event, fired when the current location fragment changes.
*/

  Modernizr.addTest('hashchange', function() {
    if (hasEvent('hashchange', window) === false) {
      return false;
    }

    // documentMode logic from YUI to filter out IE8 Compat Mode
    //   which false positives.
    return (document.documentMode === undefined || document.documentMode > 7);
  });

/*!
{
  "name" : "HTML5 Audio Element",
  "property": "audio",
  "tags" : ["html5", "audio", "media"]
}
!*/
/* DOC
Detects the audio element
*/

  // This tests evaluates support of the audio element, as well as
  // testing what types of content it supports.
  //
  // We're using the Boolean constructor here, so that we can extend the value
  // e.g.  Modernizr.audio     // true
  //       Modernizr.audio.ogg // 'probably'
  //
  // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
  //                     thx to NielsLeenheer and zcorpan

  // Note: in some older browsers, "no" was a return value instead of empty string.
  //   It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
  //   It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5
  Modernizr.addTest('audio', function() {
    /* jshint -W053 */
    var elem = createElement('audio');
    var bool = false;

    try {
      if (bool = !!elem.canPlayType) {
        bool      = new Boolean(bool);
        bool.ogg  = elem.canPlayType('audio/ogg; codecs="vorbis"') .replace(/^no$/, '');
        bool.mp3  = elem.canPlayType('audio/mpeg; codecs="mp3"')   .replace(/^no$/, '');
        bool.opus  = elem.canPlayType('audio/ogg; codecs="opus"')  ||
                     elem.canPlayType('audio/webm; codecs="opus"') .replace(/^no$/, '');

        // Mimetypes accepted:
        //   developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
        //   bit.ly/iphoneoscodecs
        bool.wav  = elem.canPlayType('audio/wav; codecs="1"')     .replace(/^no$/, '');
        bool.m4a  = (elem.canPlayType('audio/x-m4a;')            ||
                     elem.canPlayType('audio/aac;'))             .replace(/^no$/, '');
      }
    } catch (e) { }

    return bool;
  });

/*!
{
  "name": "Canvas",
  "property": "canvas",
  "caniuse": "canvas",
  "tags": ["canvas", "graphics"],
  "polyfills": ["flashcanvas", "excanvas", "slcanvas", "fxcanvas"]
}
!*/
/* DOC
Detects support for the `<canvas>` element for 2D drawing.
*/

  // On the S60 and BB Storm, getContext exists, but always returns undefined
  // so we actually have to call getContext() to verify
  // github.com/Modernizr/Modernizr/issues/issue/97/
  Modernizr.addTest('canvas', function() {
    var elem = createElement('canvas');
    return !!(elem.getContext && elem.getContext('2d'));
  });

/*!
{
  "name": "Canvas text",
  "property": "canvastext",
  "caniuse": "canvas-text",
  "tags": ["canvas", "graphics"],
  "polyfills": ["canvastext"]
}
!*/
/* DOC
Detects support for the text APIs for `<canvas>` elements.
*/

  Modernizr.addTest('canvastext',  function() {
    if (Modernizr.canvas  === false) {
      return false;
    }
    return typeof createElement('canvas').getContext('2d').fillText == 'function';
  });

/*!
{
  "name": "HTML5 Video",
  "property": "video",
  "caniuse": "video",
  "tags": ["html5"],
  "knownBugs": [
    "Without QuickTime, `Modernizr.video.h264` will be `undefined`; https://github.com/Modernizr/Modernizr/issues/546"
  ],
  "polyfills": [
    "html5media",
    "mediaelementjs",
    "sublimevideo",
    "videojs",
    "leanbackplayer",
    "videoforeverybody"
  ]
}
!*/
/* DOC
Detects support for the video element, as well as testing what types of content it supports.

Subproperties are provided to describe support for `ogg`, `h264` and `webm` formats, e.g.:

```javascript
Modernizr.video         // true
Modernizr.video.ogg     // 'probably'
```
*/

  // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
  //                     thx to NielsLeenheer and zcorpan

  // Note: in some older browsers, "no" was a return value instead of empty string.
  //   It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2
  //   It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5

  Modernizr.addTest('video', function() {
    /* jshint -W053 */
    var elem = createElement('video');
    var bool = false;

    // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
    try {
      if (bool = !!elem.canPlayType) {
        bool = new Boolean(bool);
        bool.ogg = elem.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, '');

        // Without QuickTime, this value will be `undefined`. github.com/Modernizr/Modernizr/issues/546
        bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, '');

        bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, '');

        bool.vp9 = elem.canPlayType('video/webm; codecs="vp9"').replace(/^no$/, '');

        bool.hls = elem.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/, '');
      }
    } catch (e) {}

    return bool;
  });

/*!
{
  "name": "WebGL",
  "property": "webgl",
  "caniuse": "webgl",
  "tags": ["webgl", "graphics"],
  "polyfills": ["jebgl", "cwebgl", "iewebgl"]
}
!*/

  Modernizr.addTest('webgl', function() {
    var canvas = createElement('canvas');
    var supports = 'probablySupportsContext' in canvas ? 'probablySupportsContext' :  'supportsContext';
    if (supports in canvas) {
      return canvas[supports]('webgl') || canvas[supports]('experimental-webgl');
    }
    return 'WebGLRenderingContext' in window;
  });

/*!
{
  "name": "CSS Gradients",
  "caniuse": "css-gradients",
  "property": "cssgradients",
  "tags": ["css"],
  "knownBugs": ["False-positives on webOS (https://github.com/Modernizr/Modernizr/issues/202)"],
  "notes": [{
    "name": "Webkit Gradient Syntax",
    "href": "https://webkit.org/blog/175/introducing-css-gradients/"
  },{
    "name": "Linear Gradient Syntax",
    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient"
  },{
    "name": "W3C Gradient Spec",
    "href": "https://drafts.csswg.org/css-images-3/#gradients"
  }]
}
!*/


  Modernizr.addTest('cssgradients', function() {

    var str1 = 'background-image:';
    var str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));';
    var css = '';
    var angle;

    for (var i = 0, len = prefixes.length - 1; i < len; i++) {
      angle = (i === 0 ? 'to ' : '');
      css += str1 + prefixes[i] + 'linear-gradient(' + angle + 'left top, #9f9, white);';
    }

    if (Modernizr._config.usePrefixes) {
    // legacy webkit syntax (FIXME: remove when syntax not in use anymore)
      css += str1 + '-webkit-' + str2;
    }

    var elem = createElement('a');
    var style = elem.style;
    style.cssText = css;

    // IE6 returns undefined so cast to string
    return ('' + style.backgroundImage).indexOf('gradient') > -1;
  });

/*!
{
  "name": "CSS Multiple Backgrounds",
  "caniuse": "multibackgrounds",
  "property": "multiplebgs",
  "tags": ["css"]
}
!*/

  // Setting multiple images AND a color on the background shorthand property
  // and then querying the style.background property value for the number of
  // occurrences of "url(" is a reliable method for detecting ACTUAL support for this!

  Modernizr.addTest('multiplebgs', function() {
    var style = createElement('a').style;
    style.cssText = 'background:url(https://),url(https://),red url(https://)';

    // If the UA supports multiple backgrounds, there should be three occurrences
    // of the string "url(" in the return value for elemStyle.background
    return (/(url\s*\(.*?){3}/).test(style.background);
  });

/*!
{
  "name": "CSS Opacity",
  "caniuse": "css-opacity",
  "property": "opacity",
  "tags": ["css"]
}
!*/

  // Browsers that actually have CSS Opacity implemented have done so
  // according to spec, which means their return values are within the
  // range of [0.0,1.0] - including the leading zero.

  Modernizr.addTest('opacity', function() {
    var style = createElement('a').style;
    style.cssText = prefixes.join('opacity:.55;');

    // The non-literal . in this regex is intentional:
    // German Chrome returns this value as 0,55
    // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
    return (/^0.55$/).test(style.opacity);
  });

/*!
{
  "name": "CSS rgba",
  "caniuse": "css3-colors",
  "property": "rgba",
  "tags": ["css"],
  "notes": [{
    "name": "CSSTricks Tutorial",
    "href": "https://css-tricks.com/rgba-browser-support/"
  }]
}
!*/

  Modernizr.addTest('rgba', function() {
    var style = createElement('a').style;
    style.cssText = 'background-color:rgba(150,255,150,.5)';

    return ('' + style.backgroundColor).indexOf('rgba') > -1;
  });

/*!
{
  "name": "Inline SVG",
  "property": "inlinesvg",
  "caniuse": "svg-html5",
  "tags": ["svg"],
  "notes": [{
    "name": "Test page",
    "href": "https://paulirish.com/demo/inline-svg"
  }, {
    "name": "Test page and results",
    "href": "https://codepen.io/eltonmesquita/full/GgXbvo/"
  }],
  "polyfills": ["inline-svg-polyfill"],
  "knownBugs": ["False negative on some Chromia browsers."]
}
!*/
/* DOC
Detects support for inline SVG in HTML (not within XHTML).
*/

  Modernizr.addTest('inlinesvg', function() {
    var div = createElement('div');
    div.innerHTML = '<svg/>';
    return (typeof SVGRect != 'undefined' && div.firstChild && div.firstChild.namespaceURI) == 'http://www.w3.org/2000/svg';
  });


  /**
   * cssToDOM takes a kebab-case string and converts it to camelCase
   * e.g. box-sizing -> boxSizing
   *
   * @access private
   * @function cssToDOM
   * @param {string} name - String name of kebab-case prop we want to convert
   * @returns {string} The camelCase version of the supplied name
   */

  function cssToDOM(name) {
    return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
      return m1 + m2.toUpperCase();
    }).replace(/^-/, '');
  }
  ;

  /**
   * since we have a fairly large number of input tests that don't mutate the input
   * we create a single element that can be shared with all of those tests for a
   * minor perf boost
   *
   * @access private
   * @returns {HTMLInputElement}
   */
  var inputElem = createElement('input');

/*!
{
  "name": "Input attributes",
  "property": "input",
  "tags": ["forms"],
  "authors": ["Mike Taylor"],
  "notes": [{
    "name": "WHATWG spec",
    "href": "https://html.spec.whatwg.org/multipage/forms.html#input-type-attr-summary"
  }],
  "knownBugs": ["Some blackberry devices report false positive for input.multiple"]
}
!*/
/* DOC
Detects support for HTML5 `<input>` element attributes and exposes Boolean subproperties with the results:

```javascript
Modernizr.input.autocomplete
Modernizr.input.autofocus
Modernizr.input.list
Modernizr.input.max
Modernizr.input.min
Modernizr.input.multiple
Modernizr.input.pattern
Modernizr.input.placeholder
Modernizr.input.required
Modernizr.input.step
```
*/

  // Run through HTML5's new input attributes to see if the UA understands any.
  // Mike Taylr has created a comprehensive resource for testing these attributes
  //   when applied to all input types:
  //   miketaylr.com/code/input-type-attr.html

  // Only input placeholder is tested while textarea's placeholder is not.
  // Currently Safari 4 and Opera 11 have support only for the input placeholder
  // Both tests are available in feature-detects/forms-placeholder.js

  var inputattrs = 'autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ');
  var attrs = {};

  Modernizr.input = (function(props) {
    for (var i = 0, len = props.length; i < len; i++) {
      attrs[ props[i] ] = !!(props[i] in inputElem);
    }
    if (attrs.list) {
      // safari false positive's on datalist: webk.it/74252
      // see also github.com/Modernizr/Modernizr/issues/146
      attrs.list = !!(createElement('datalist') && window.HTMLDataListElement);
    }
    return attrs;
  })(inputattrs);

/*!
{
  "name": "Form input types",
  "property": "inputtypes",
  "caniuse": "forms",
  "tags": ["forms"],
  "authors": ["Mike Taylor"],
  "polyfills": [
    "jquerytools",
    "webshims",
    "h5f",
    "webforms2",
    "nwxforms",
    "fdslider",
    "html5slider",
    "galleryhtml5forms",
    "jscolor",
    "html5formshim",
    "selectedoptionsjs",
    "formvalidationjs"
  ]
}
!*/
/* DOC
Detects support for HTML5 form input types and exposes Boolean subproperties with the results:

```javascript
Modernizr.inputtypes.color
Modernizr.inputtypes.date
Modernizr.inputtypes.datetime
Modernizr.inputtypes['datetime-local']
Modernizr.inputtypes.email
Modernizr.inputtypes.month
Modernizr.inputtypes.number
Modernizr.inputtypes.range
Modernizr.inputtypes.search
Modernizr.inputtypes.tel
Modernizr.inputtypes.time
Modernizr.inputtypes.url
Modernizr.inputtypes.week
```
*/

  // Run through HTML5's new input types to see if the UA understands any.
  //   This is put behind the tests runloop because it doesn't return a
  //   true/false like all the other tests; instead, it returns an object
  //   containing each input type with its corresponding true/false value

  // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/
  var inputtypes = 'search tel url email datetime date month week time datetime-local number range color'.split(' ');
  var inputs = {};

  Modernizr.inputtypes = (function(props) {
    var len = props.length;
    var smile = '1)';
    var inputElemType;
    var defaultView;
    var bool;

    for (var i = 0; i < len; i++) {

      inputElem.setAttribute('type', inputElemType = props[i]);
      bool = inputElem.type !== 'text' && 'style' in inputElem;

      // We first check to see if the type we give it sticks..
      // If the type does, we feed it a textual value, which shouldn't be valid.
      // If the value doesn't stick, we know there's input sanitization which infers a custom UI
      if (bool) {

        inputElem.value         = smile;
        inputElem.style.cssText = 'position:absolute;visibility:hidden;';

        if (/^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined) {

          docElement.appendChild(inputElem);
          defaultView = document.defaultView;

          // Safari 2-4 allows the smiley as a value, despite making a slider
          bool =  defaultView.getComputedStyle &&
            defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
            // Mobile android web browser has false positive, so must
            // check the height to see if the widget is actually there.
            (inputElem.offsetHeight !== 0);

          docElement.removeChild(inputElem);

        } else if (/^(search|tel)$/.test(inputElemType)) {
          // Spec doesn't define any special parsing or detectable UI
          //   behaviors so we pass these through as true

          // Interestingly, opera fails the earlier test, so it doesn't
          //  even make it here.

        } else if (/^(url|email)$/.test(inputElemType)) {
          // Real url and email support comes with prebaked validation.
          bool = inputElem.checkValidity && inputElem.checkValidity() === false;

        } else {
          // If the upgraded input compontent rejects the :) text, we got a winner
          bool = inputElem.value != smile;
        }
      }

      inputs[ props[i] ] = !!bool;
    }
    return inputs;
  })(inputtypes);



  /**
   * contains checks to see if a string contains another string
   *
   * @access private
   * @function contains
   * @param {string} str - The string we want to check for substrings
   * @param {string} substr - The substring we want to search the first string for
   * @returns {boolean}
   */

  function contains(str, substr) {
    return !!~('' + str).indexOf(substr);
  }

  ;
/*!
{
  "name": "CSS HSLA Colors",
  "caniuse": "css3-colors",
  "property": "hsla",
  "tags": ["css"]
}
!*/

  Modernizr.addTest('hsla', function() {
    var style = createElement('a').style;
    style.cssText = 'background-color:hsla(120,40%,100%,.5)';
    return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
  });

/*!
{
  "name": "CSS Supports",
  "property": "supports",
  "caniuse": "css-featurequeries",
  "tags": ["css"],
  "builderAliases": ["css_supports"],
  "notes": [{
    "name": "W3 Spec",
    "href": "http://dev.w3.org/csswg/css3-conditional/#at-supports"
  },{
    "name": "Related Github Issue",
    "href": "github.com/Modernizr/Modernizr/issues/648"
  },{
    "name": "W3 Info",
    "href": "http://dev.w3.org/csswg/css3-conditional/#the-csssupportsrule-interface"
  }]
}
!*/

  var newSyntax = 'CSS' in window && 'supports' in window.CSS;
  var oldSyntax = 'supportsCSS' in window;
  Modernizr.addTest('supports', newSyntax || oldSyntax);


  /**
   * Object.prototype.toString can be used with every object and allows you to
   * get its class easily. Abstracting it off of an object prevents situations
   * where the toString property has been overridden
   *
   * @access private
   * @function toStringFn
   * @returns {function} An abstracted toString function
   */

  var toStringFn = ({}).toString;

/*!
{
  "name": "SVG clip paths",
  "property": "svgclippaths",
  "tags": ["svg"],
  "notes": [{
    "name": "Demo",
    "href": "http://srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg"
  }]
}
!*/
/* DOC
Detects support for clip paths in SVG (only, not on HTML content).

See [this discussion](https://github.com/Modernizr/Modernizr/issues/213) regarding applying SVG clip paths to HTML content.
*/

  Modernizr.addTest('svgclippaths', function() {
    return !!document.createElementNS &&
      /SVGClipPath/.test(toStringFn.call(document.createElementNS('http://www.w3.org/2000/svg', 'clipPath')));
  });

/*!
{
  "name": "SVG SMIL animation",
  "property": "smil",
  "caniuse": "svg-smil",
  "tags": ["svg"],
  "notes": [{
  "name": "W3C Synchronised Multimedia spec",
  "href": "https://www.w3.org/AudioVideo/"
  }]
}
!*/

  // SVG SMIL animation
  Modernizr.addTest('smil', function() {
    return !!document.createElementNS &&
      /SVGAnimate/.test(toStringFn.call(document.createElementNS('http://www.w3.org/2000/svg', 'animate')));
  });


  /**
   * getBody returns the body of a document, or an element that can stand in for
   * the body if a real body does not exist
   *
   * @access private
   * @function getBody
   * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an
   * artificially created element that stands in for the body
   */

  function getBody() {
    // After page load injecting a fake body doesn't work so check if body exists
    var body = document.body;

    if (!body) {
      // Can't use the real body create a fake one.
      body = createElement(isSVG ? 'svg' : 'body');
      body.fake = true;
    }

    return body;
  }

  ;

  /**
   * injectElementWithStyles injects an element with style element and some CSS rules
   *
   * @access private
   * @function injectElementWithStyles
   * @param {string} rule - String representing a css rule
   * @param {function} callback - A function that is used to test the injected element
   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
   * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
   * @returns {boolean}
   */

  function injectElementWithStyles(rule, callback, nodes, testnames) {
    var mod = 'modernizr';
    var style;
    var ret;
    var node;
    var docOverflow;
    var div = createElement('div');
    var body = getBody();

    if (parseInt(nodes, 10)) {
      // In order not to give false positives we create a node for each test
      // This also allows the method to scale for unspecified uses
      while (nodes--) {
        node = createElement('div');
        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
        div.appendChild(node);
      }
    }

    style = createElement('style');
    style.type = 'text/css';
    style.id = 's' + mod;

    // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
    // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
    (!body.fake ? div : body).appendChild(style);
    body.appendChild(div);

    if (style.styleSheet) {
      style.styleSheet.cssText = rule;
    } else {
      style.appendChild(document.createTextNode(rule));
    }
    div.id = mod;

    if (body.fake) {
      //avoid crashing IE8, if background image is used
      body.style.background = '';
      //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
      body.style.overflow = 'hidden';
      docOverflow = docElement.style.overflow;
      docElement.style.overflow = 'hidden';
      docElement.appendChild(body);
    }

    ret = callback(div, rule);
    // If this is done after page load we don't want to remove the body so check if body exists
    if (body.fake) {
      body.parentNode.removeChild(body);
      docElement.style.overflow = docOverflow;
      // Trigger layout so kinetic scrolling isn't disabled in iOS6+
      docElement.offsetHeight;
    } else {
      div.parentNode.removeChild(div);
    }

    return !!ret;

  }

  ;

  /**
   * Modernizr.mq tests a given media query, live against the current state of the window
   * adapted from matchMedia polyfill by Scott Jehl and Paul Irish
   * gist.github.com/786768
   *
   * @memberof Modernizr
   * @name Modernizr.mq
   * @optionName Modernizr.mq()
   * @optionProp mq
   * @access public
   * @function mq
   * @param {string} mq - String of the media query we want to test
   * @returns {boolean}
   * @example
   * Modernizr.mq allows for you to programmatically check if the current browser
   * window state matches a media query.
   *
   * ```js
   *  var query = Modernizr.mq('(min-width: 900px)');
   *
   *  if (query) {
   *    // the browser window is larger than 900px
   *  }
   * ```
   *
   * Only valid media queries are supported, therefore you must always include values
   * with your media query
   *
   * ```js
   * // good
   *  Modernizr.mq('(min-width: 900px)');
   *
   * // bad
   *  Modernizr.mq('min-width');
   * ```
   *
   * If you would just like to test that media queries are supported in general, use
   *
   * ```js
   *  Modernizr.mq('only all'); // true if MQ are supported, false if not
   * ```
   *
   *
   * Note that if the browser does not support media queries (e.g. old IE) mq will
   * always return false.
   */

  var mq = (function() {
    var matchMedia = window.matchMedia || window.msMatchMedia;
    if (matchMedia) {
      return function(mq) {
        var mql = matchMedia(mq);
        return mql && mql.matches || false;
      };
    }

    return function(mq) {
      var bool = false;

      injectElementWithStyles('@media ' + mq + ' { #modernizr { position: absolute; } }', function(node) {
        bool = (window.getComputedStyle ?
                window.getComputedStyle(node, null) :
                node.currentStyle).position == 'absolute';
      });

      return bool;
    };
  })();


  ModernizrProto.mq = mq;



  /**
   * testStyles injects an element with style element and some CSS rules
   *
   * @memberof Modernizr
   * @name Modernizr.testStyles
   * @optionName Modernizr.testStyles()
   * @optionProp testStyles
   * @access public
   * @function testStyles
   * @param {string} rule - String representing a css rule
   * @param {function} callback - A function that is used to test the injected element
   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
   * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
   * @returns {boolean}
   * @example
   *
   * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page
   * along with (possibly multiple) DOM elements. This lets you check for features
   * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules).
   *
   * ```js
   * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) {
   *   // elem is the first DOM node in the page (by default #modernizr)
   *   // rule is the first argument you supplied - the CSS rule in string form
   *
   *   addTest('widthworks', elem.style.width === '9px')
   * });
   * ```
   *
   * If your test requires multiple nodes, you can include a third argument
   * indicating how many additional div elements to include on the page. The
   * additional nodes are injected as children of the `elem` that is returned as
   * the first argument to the callback.
   *
   * ```js
   * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) {
   *   document.getElementById('modernizr').style.width === '1px'; // true
   *   document.getElementById('modernizr2').style.width === '2px'; // true
   *   elem.firstChild === document.getElementById('modernizr2'); // true
   * }, 1);
   * ```
   *
   * By default, all of the additional elements have an ID of `modernizr[n]`, where
   * `n` is its index (e.g. the first additional, second overall is `#modernizr2`,
   * the second additional is `#modernizr3`, etc.).
   * If you want to have more meaningful IDs for your function, you can provide
   * them as the fourth argument, as an array of strings
   *
   * ```js
   * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) {
   *   elem.firstChild === document.getElementById('foo'); // true
   *   elem.lastChild === document.getElementById('bar'); // true
   * }, 2, ['foo', 'bar']);
   * ```
   *
   */

  var testStyles = ModernizrProto.testStyles = injectElementWithStyles;

/*!
{
  "name": "Touch Events",
  "property": "touchevents",
  "caniuse" : "touch",
  "tags": ["media", "attribute"],
  "notes": [{
    "name": "Touch Events spec",
    "href": "https://www.w3.org/TR/2013/WD-touch-events-20130124/"
  }],
  "warnings": [
    "Indicates if the browser supports the Touch Events spec, and does not necessarily reflect a touchscreen device"
  ],
  "knownBugs": [
    "False-positive on some configurations of Nokia N900",
    "False-positive on some BlackBerry 6.0 builds – https://github.com/Modernizr/Modernizr/issues/372#issuecomment-3112695"
  ]
}
!*/
/* DOC
Indicates if the browser supports the W3C Touch Events API.

This *does not* necessarily reflect a touchscreen device:

* Older touchscreen devices only emulate mouse events
* Modern IE touch devices implement the Pointer Events API instead: use `Modernizr.pointerevents` to detect support for that
* Some browsers & OS setups may enable touch APIs when no touchscreen is connected
* Future browsers may implement other event models for touch interactions

See this article: [You Can't Detect A Touchscreen](http://www.stucox.com/blog/you-cant-detect-a-touchscreen/).

It's recommended to bind both mouse and touch/pointer events simultaneously – see [this HTML5 Rocks tutorial](http://www.html5rocks.com/en/mobile/touchandmouse/).

This test will also return `true` for Firefox 4 Multitouch support.
*/

  // Chrome (desktop) used to lie about its support on this, but that has since been rectified: http://crbug.com/36415
  Modernizr.addTest('touchevents', function() {
    var bool;
    if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
      bool = true;
    } else {
      // include the 'heartz' as a way to have a non matching MQ to help terminate the join
      // https://git.io/vznFH
      var query = ['@media (', prefixes.join('touch-enabled),('), 'heartz', ')', '{#modernizr{top:9px;position:absolute}}'].join('');
      testStyles(query, function(node) {
        bool = node.offsetTop === 9;
      });
    }
    return bool;
  });

/*!
{
  "name": "@font-face",
  "property": "fontface",
  "authors": ["Diego Perini", "Mat Marquis"],
  "tags": ["css"],
  "knownBugs": [
    "False Positive: WebOS https://github.com/Modernizr/Modernizr/issues/342",
    "False Postive: WP7 https://github.com/Modernizr/Modernizr/issues/538"
  ],
  "notes": [{
    "name": "@font-face detection routine by Diego Perini",
    "href": "http://javascript.nwbox.com/CSSSupport/"
  },{
    "name": "Filament Group @font-face compatibility research",
    "href": "https://docs.google.com/presentation/d/1n4NyG4uPRjAA8zn_pSQ_Ket0RhcWC6QlZ6LMjKeECo0/edit#slide=id.p"
  },{
    "name": "Filament Grunticon/@font-face device testing results",
    "href": "https://docs.google.com/spreadsheet/ccc?key=0Ag5_yGvxpINRdHFYeUJPNnZMWUZKR2ItMEpRTXZPdUE#gid=0"
  },{
    "name": "CSS fonts on Android",
    "href": "https://stackoverflow.com/questions/3200069/css-fonts-on-android"
  },{
    "name": "@font-face and Android",
    "href": "http://archivist.incutio.com/viewlist/css-discuss/115960"
  }]
}
!*/

  var blacklist = (function() {
    var ua = navigator.userAgent;
    var wkvers = ua.match(/applewebkit\/([0-9]+)/gi) && parseFloat(RegExp.$1);
    var webos = ua.match(/w(eb)?osbrowser/gi);
    var wppre8 = ua.match(/windows phone/gi) && ua.match(/iemobile\/([0-9])+/gi) && parseFloat(RegExp.$1) >= 9;
    var oldandroid = wkvers < 533 && ua.match(/android/gi);
    return webos || oldandroid || wppre8;
  }());
  if (blacklist) {
    Modernizr.addTest('fontface', false);
  } else {
    testStyles('@font-face {font-family:"font";src:url("https://")}', function(node, rule) {
      var style = document.getElementById('smodernizr');
      var sheet = style.sheet || style.styleSheet;
      var cssText = sheet ? (sheet.cssRules && sheet.cssRules[0] ? sheet.cssRules[0].cssText : sheet.cssText || '') : '';
      var bool = /src/i.test(cssText) && cssText.indexOf(rule.split(' ')[0]) === 0;
      Modernizr.addTest('fontface', bool);
    });
  }
;
/*!
{
  "name": "CSS Generated Content",
  "property": "generatedcontent",
  "tags": ["css"],
  "warnings": ["Android won't return correct height for anything below 7px #738"],
  "notes": [{
    "name": "W3C CSS Selectors Level 3 spec",
    "href": "https://www.w3.org/TR/css3-selectors/#gen-content"
  },{
    "name": "MDN article on :before",
    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/::before"
  },{
    "name": "MDN article on :after",
    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/::before"
  }]
}
!*/

  testStyles('#modernizr{font:0/0 a}#modernizr:after{content:":)";visibility:hidden;font:7px/1 a}', function(node) {
    Modernizr.addTest('generatedcontent', node.offsetHeight >= 7);
  });


  var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);
  ModernizrProto._cssomPrefixes = cssomPrefixes;


  /**
   * atRule returns a given CSS property at-rule (eg @keyframes), possibly in
   * some prefixed form, or false, in the case of an unsupported rule
   *
   * @memberof Modernizr
   * @name Modernizr.atRule
   * @optionName Modernizr.atRule()
   * @optionProp atRule
   * @access public
   * @function atRule
   * @param {string} prop - String name of the @-rule to test for
   * @returns {string|boolean} The string representing the (possibly prefixed)
   * valid version of the @-rule, or `false` when it is unsupported.
   * @example
   * ```js
   *  var keyframes = Modernizr.atRule('@keyframes');
   *
   *  if (keyframes) {
   *    // keyframes are supported
   *    // could be `@-webkit-keyframes` or `@keyframes`
   *  } else {
   *    // keyframes === `false`
   *  }
   * ```
   *
   */

  var atRule = function(prop) {
    var length = prefixes.length;
    var cssrule = window.CSSRule;
    var rule;

    if (typeof cssrule === 'undefined') {
      return undefined;
    }

    if (!prop) {
      return false;
    }

    // remove literal @ from beginning of provided property
    prop = prop.replace(/^@/, '');

    // CSSRules use underscores instead of dashes
    rule = prop.replace(/-/g, '_').toUpperCase() + '_RULE';

    if (rule in cssrule) {
      return '@' + prop;
    }

    for (var i = 0; i < length; i++) {
      // prefixes gives us something like -o-, and we want O_
      var prefix = prefixes[i];
      var thisRule = prefix.toUpperCase() + '_' + rule;

      if (thisRule in cssrule) {
        return '@-' + prefix.toLowerCase() + '-' + prop;
      }
    }

    return false;
  };

  ModernizrProto.atRule = atRule;



  /**
   * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.
   *
   * @access private
   * @function fnBind
   * @param {function} fn - a function you want to change `this` reference to
   * @param {object} that - the `this` you want to call the function with
   * @returns {function} The wrapped version of the supplied function
   */

  function fnBind(fn, that) {
    return function() {
      return fn.apply(that, arguments);
    };
  }

  ;

  /**
   * testDOMProps is a generic DOM property test; if a browser supports
   *   a certain property, it won't return undefined for it.
   *
   * @access private
   * @function testDOMProps
   * @param {array.<string>} props - An array of properties to test for
   * @param {object} obj - An object or Element you want to use to test the parameters again
   * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check
   */
  function testDOMProps(props, obj, elem) {
    var item;

    for (var i in props) {
      if (props[i] in obj) {

        // return the property name as a string
        if (elem === false) {
          return props[i];
        }

        item = obj[props[i]];

        // let's bind a function
        if (is(item, 'function')) {
          // bind to obj unless overriden
          return fnBind(item, elem || obj);
        }

        // return the unbound function or obj or value
        return item;
      }
    }
    return false;
  }

  ;

  /**
   * Create our "modernizr" element that we do most feature tests on.
   *
   * @access private
   */

  var modElem = {
    elem: createElement('modernizr')
  };

  // Clean up this element
  Modernizr._q.push(function() {
    delete modElem.elem;
  });



  var mStyle = {
    style: modElem.elem.style
  };

  // kill ref for gc, must happen before mod.elem is removed, so we unshift on to
  // the front of the queue.
  Modernizr._q.unshift(function() {
    delete mStyle.style;
  });



  /**
   * domToCSS takes a camelCase string and converts it to kebab-case
   * e.g. boxSizing -> box-sizing
   *
   * @access private
   * @function domToCSS
   * @param {string} name - String name of camelCase prop we want to convert
   * @returns {string} The kebab-case version of the supplied name
   */

  function domToCSS(name) {
    return name.replace(/([A-Z])/g, function(str, m1) {
      return '-' + m1.toLowerCase();
    }).replace(/^ms-/, '-ms-');
  }
  ;

  /**
   * nativeTestProps allows for us to use native feature detection functionality if available.
   * some prefixed form, or false, in the case of an unsupported rule
   *
   * @access private
   * @function nativeTestProps
   * @param {array} props - An array of property names
   * @param {string} value - A string representing the value we want to check via @supports
   * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise
   */

  // Accepts a list of property names and a single value
  // Returns `undefined` if native detection not available
  function nativeTestProps(props, value) {
    var i = props.length;
    // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface
    if ('CSS' in window && 'supports' in window.CSS) {
      // Try every prefixed variant of the property
      while (i--) {
        if (window.CSS.supports(domToCSS(props[i]), value)) {
          return true;
        }
      }
      return false;
    }
    // Otherwise fall back to at-rule (for Opera 12.x)
    else if ('CSSSupportsRule' in window) {
      // Build a condition string for every prefixed variant
      var conditionText = [];
      while (i--) {
        conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
      }
      conditionText = conditionText.join(' or ');
      return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) {
        return getComputedStyle(node, null).position == 'absolute';
      });
    }
    return undefined;
  }
  ;

  // testProps is a generic CSS / DOM property test.

  // In testing support for a given CSS property, it's legit to test:
  //    `elem.style[styleName] !== undefined`
  // If the property is supported it will return an empty string,
  // if unsupported it will return undefined.

  // We'll take advantage of this quick test and skip setting a style
  // on our modernizr element, but instead just testing undefined vs
  // empty string.

  // Property names can be provided in either camelCase or kebab-case.

  function testProps(props, prefixed, value, skipValueTest) {
    skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;

    // Try native detect first
    if (!is(value, 'undefined')) {
      var result = nativeTestProps(props, value);
      if (!is(result, 'undefined')) {
        return result;
      }
    }

    // Otherwise do it properly
    var afterInit, i, propsLength, prop, before;

    // If we don't have a style element, that means we're running async or after
    // the core tests, so we'll need to create our own elements to use

    // inside of an SVG element, in certain browsers, the `style` element is only
    // defined for valid tags. Therefore, if `modernizr` does not have one, we
    // fall back to a less used element and hope for the best.
    var elems = ['modernizr', 'tspan'];
    while (!mStyle.style) {
      afterInit = true;
      mStyle.modElem = createElement(elems.shift());
      mStyle.style = mStyle.modElem.style;
    }

    // Delete the objects if we created them.
    function cleanElems() {
      if (afterInit) {
        delete mStyle.style;
        delete mStyle.modElem;
      }
    }

    propsLength = props.length;
    for (i = 0; i < propsLength; i++) {
      prop = props[i];
      before = mStyle.style[prop];

      if (contains(prop, '-')) {
        prop = cssToDOM(prop);
      }

      if (mStyle.style[prop] !== undefined) {

        // If value to test has been passed in, do a set-and-check test.
        // 0 (integer) is a valid property value, so check that `value` isn't
        // undefined, rather than just checking it's truthy.
        if (!skipValueTest && !is(value, 'undefined')) {

          // Needs a try catch block because of old IE. This is slow, but will
          // be avoided in most cases because `skipValueTest` will be used.
          try {
            mStyle.style[prop] = value;
          } catch (e) {}

          // If the property value has changed, we assume the value used is
          // supported. If `value` is empty string, it'll fail here (because
          // it hasn't changed), which matches how browsers have implemented
          // CSS.supports()
          if (mStyle.style[prop] != before) {
            cleanElems();
            return prefixed == 'pfx' ? prop : true;
          }
        }
        // Otherwise just return true, or the property name if this is a
        // `prefixed()` call
        else {
          cleanElems();
          return prefixed == 'pfx' ? prop : true;
        }
      }
    }
    cleanElems();
    return false;
  }

  ;

  /**
   * testProp() investigates whether a given style property is recognized
   * Property names can be provided in either camelCase or kebab-case.
   *
   * @memberof Modernizr
   * @name Modernizr.testProp
   * @access public
   * @optionName Modernizr.testProp()
   * @optionProp testProp
   * @function testProp
   * @param {string} prop - Name of the CSS property to check
   * @param {string} [value] - Name of the CSS value to check
   * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported
   * @returns {boolean}
   * @example
   *
   * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed
   * version of the string.
   *
   * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing)
   *
   * ```js
   * Modernizr.testProp('pointerEvents')  // true
   * ```
   *
   * You can also provide a value as an optional second argument to check if a
   * specific value is supported
   *
   * ```js
   * Modernizr.testProp('pointerEvents', 'none') // true
   * Modernizr.testProp('pointerEvents', 'penguin') // false
   * ```
   */

  var testProp = ModernizrProto.testProp = function(prop, value, useValue) {
    return testProps([prop], undefined, value, useValue);
  };

/*!
{
  "name": "CSS textshadow",
  "property": "textshadow",
  "caniuse": "css-textshadow",
  "tags": ["css"],
  "knownBugs": ["FF3.0 will false positive on this test"]
}
!*/

  Modernizr.addTest('textshadow', testProp('textShadow', '1px 1px'));


  /**
   * testPropsAll tests a list of DOM properties we want to check against.
   * We specify literally ALL possible (known and/or likely) properties on
   * the element including the non-vendor prefixed one, for forward-
   * compatibility.
   *
   * @access private
   * @function testPropsAll
   * @param {string} prop - A string of the property to test for
   * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip
   * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against
   * @param {string} [value] - A string of a css value
   * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set
   */
  function testPropsAll(prop, prefixed, elem, value, skipValueTest) {

    var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
    props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');

    // did they call .prefixed('boxSizing') or are we just testing a prop?
    if (is(prefixed, 'string') || is(prefixed, 'undefined')) {
      return testProps(props, prefixed, value, skipValueTest);

      // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
    } else {
      props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
      return testDOMProps(props, prefixed, elem);
    }
  }

  // Modernizr.testAllProps() investigates whether a given style property,
  // or any of its vendor-prefixed variants, is recognized
  //
  // Note that the property names must be provided in the camelCase variant.
  // Modernizr.testAllProps('boxSizing')
  ModernizrProto.testAllProps = testPropsAll;



  /**
   * prefixed returns the prefixed or nonprefixed property name variant of your input
   *
   * @memberof Modernizr
   * @name Modernizr.prefixed
   * @optionName Modernizr.prefixed()
   * @optionProp prefixed
   * @access public
   * @function prefixed
   * @param {string} prop - String name of the property to test for
   * @param {object} [obj] - An object to test for the prefixed properties on
   * @param {HTMLElement} [elem] - An element used to test specific properties against
   * @returns {string|false} The string representing the (possibly prefixed) valid
   * version of the property, or `false` when it is unsupported.
   * @example
   *
   * Modernizr.prefixed takes a string css value in the DOM style camelCase (as
   * opposed to the css style kebab-case) form and returns the (possibly prefixed)
   * version of that property that the browser actually supports.
   *
   * For example, in older Firefox...
   * ```js
   * prefixed('boxSizing')
   * ```
   * returns 'MozBoxSizing'
   *
   * In newer Firefox, as well as any other browser that support the unprefixed
   * version would simply return `boxSizing`. Any browser that does not support
   * the property at all, it will return `false`.
   *
   * By default, prefixed is checked against a DOM element. If you want to check
   * for a property on another object, just pass it as a second argument
   *
   * ```js
   * var rAF = prefixed('requestAnimationFrame', window);
   *
   * raf(function() {
   *  renderFunction();
   * })
   * ```
   *
   * Note that this will return _the actual function_ - not the name of the function.
   * If you need the actual name of the property, pass in `false` as a third argument
   *
   * ```js
   * var rAFProp = prefixed('requestAnimationFrame', window, false);
   *
   * rafProp === 'WebkitRequestAnimationFrame' // in older webkit
   * ```
   *
   * One common use case for prefixed is if you're trying to determine which transition
   * end event to bind to, you might do something like...
   * ```js
   * var transEndEventNames = {
   *     'WebkitTransition' : 'webkitTransitionEnd', * Saf 6, Android Browser
   *     'MozTransition'    : 'transitionend',       * only for FF < 15
   *     'transition'       : 'transitionend'        * IE10, Opera, Chrome, FF 15+, Saf 7+
   * };
   *
   * var transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
   * ```
   *
   * If you want a similar lookup, but in kebab-case, you can use [prefixedCSS](#modernizr-prefixedcss).
   */

  var prefixed = ModernizrProto.prefixed = function(prop, obj, elem) {
    if (prop.indexOf('@') === 0) {
      return atRule(prop);
    }

    if (prop.indexOf('-') != -1) {
      // Convert kebab-case to camelCase
      prop = cssToDOM(prop);
    }
    if (!obj) {
      return testPropsAll(prop, 'pfx');
    } else {
      // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
      return testPropsAll(prop, obj, elem);
    }
  };


/*!
{
  "name": "IndexedDB",
  "property": "indexeddb",
  "caniuse": "indexeddb",
  "tags": ["storage"],
  "polyfills": ["indexeddb"]
}
!*/
/* DOC
Detects support for the IndexedDB client-side storage API (final spec).
*/

  // Vendors had inconsistent prefixing with the experimental Indexed DB:
  // - Webkit's implementation is accessible through webkitIndexedDB
  // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
  // For speed, we don't test the legacy (and beta-only) indexedDB

  var indexeddb;
  try {
    indexeddb = prefixed('indexedDB', window);
  } catch (e) {
  }

  Modernizr.addTest('indexeddb', !!indexeddb);

  if (!!indexeddb) {
    Modernizr.addTest('indexeddb.deletedatabase', 'deleteDatabase' in indexeddb);
  }
;

  /**
   * testAllProps determines whether a given CSS property is supported in the browser
   *
   * @memberof Modernizr
   * @name Modernizr.testAllProps
   * @optionName Modernizr.testAllProps()
   * @optionProp testAllProps
   * @access public
   * @function testAllProps
   * @param {string} prop - String naming the property to test (either camelCase or kebab-case)
   * @param {string} [value] - String of the value to test
   * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection
   * @example
   *
   * testAllProps determines whether a given CSS property, in some prefixed form,
   * is supported by the browser.
   *
   * ```js
   * testAllProps('boxSizing')  // true
   * ```
   *
   * It can optionally be given a CSS value in string form to test if a property
   * value is valid
   *
   * ```js
   * testAllProps('display', 'block') // true
   * testAllProps('display', 'penguin') // false
   * ```
   *
   * A boolean can be passed as a third parameter to skip the value check when
   * native detection (@supports) isn't available.
   *
   * ```js
   * testAllProps('shapeOutside', 'content-box', true);
   * ```
   */

  function testAllProps(prop, value, skipValueTest) {
    return testPropsAll(prop, undefined, undefined, value, skipValueTest);
  }
  ModernizrProto.testAllProps = testAllProps;

/*!
{
  "name": "CSS Animations",
  "property": "cssanimations",
  "caniuse": "css-animation",
  "polyfills": ["transformie", "csssandpaper"],
  "tags": ["css"],
  "warnings": ["Android < 4 will pass this test, but can only animate a single property at a time"],
  "notes": [{
    "name" : "Article: 'Dispelling the Android CSS animation myths'",
    "href": "https://goo.gl/OGw5Gm"
  }]
}
!*/
/* DOC
Detects whether or not elements can be animated using CSS
*/

  Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true));

/*!
{
  "name": "Background Size",
  "property": "backgroundsize",
  "tags": ["css"],
  "knownBugs": ["This will false positive in Opera Mini - https://github.com/Modernizr/Modernizr/issues/396"],
  "notes": [{
    "name": "Related Issue",
    "href": "https://github.com/Modernizr/Modernizr/issues/396"
  }]
}
!*/

  Modernizr.addTest('backgroundsize', testAllProps('backgroundSize', '100%', true));

/*!
{
  "name": "Border Image",
  "property": "borderimage",
  "caniuse": "border-image",
  "polyfills": ["css3pie"],
   "knownBugs": ["Android < 2.0 is true, but has a broken implementation"],
  "tags": ["css"]
}
!*/

  Modernizr.addTest('borderimage', testAllProps('borderImage', 'url() 1', true));

/*!
{
  "name": "Border Radius",
  "property": "borderradius",
  "caniuse": "border-radius",
  "polyfills": ["css3pie"],
  "tags": ["css"],
  "notes": [{
    "name": "Comprehensive Compat Chart",
    "href": "https://muddledramblings.com/table-of-css3-border-radius-compliance"
  }]
}
!*/

  Modernizr.addTest('borderradius', testAllProps('borderRadius', '0px', true));

/*!
{
  "name": "Box Shadow",
  "property": "boxshadow",
  "caniuse": "css-boxshadow",
  "tags": ["css"],
  "knownBugs": [
    "WebOS false positives on this test.",
    "The Kindle Silk browser false positives"
  ]
}
!*/

  Modernizr.addTest('boxshadow', testAllProps('boxShadow', '1px 1px', true));

/*!
{
  "name": "Flexbox",
  "property": "flexbox",
  "caniuse": "flexbox",
  "tags": ["css"],
  "notes": [{
    "name": "The _new_ flexbox",
    "href": "http://dev.w3.org/csswg/css3-flexbox"
  }],
  "warnings": [
    "A `true` result for this detect does not imply that the `flex-wrap` property is supported; see the `flexwrap` detect."
  ]
}
!*/
/* DOC
Detects support for the Flexible Box Layout model, a.k.a. Flexbox, which allows easy manipulation of layout order and sizing within a container.
*/

  Modernizr.addTest('flexbox', testAllProps('flexBasis', '1px', true));

/*!
{
  "name": "CSS Reflections",
  "caniuse": "css-reflections",
  "property": "cssreflections",
  "tags": ["css"]
}
!*/

  Modernizr.addTest('cssreflections', testAllProps('boxReflect', 'above', true));

/*!
{
  "name": "CSS Transforms",
  "property": "csstransforms",
  "caniuse": "transforms2d",
  "tags": ["css"]
}
!*/

  Modernizr.addTest('csstransforms', function() {
    // Android < 3.0 is buggy, so we sniff and blacklist
    // http://git.io/hHzL7w
    return navigator.userAgent.indexOf('Android 2.') === -1 &&
           testAllProps('transform', 'scale(1)', true);
  });

/*!
{
  "name": "CSS Transforms 3D",
  "property": "csstransforms3d",
  "caniuse": "transforms3d",
  "tags": ["css"],
  "warnings": [
    "Chrome may occassionally fail this test on some systems; more info: https://code.google.com/p/chromium/issues/detail?id=129004"
  ]
}
!*/

  Modernizr.addTest('csstransforms3d', function() {
    var ret = !!testAllProps('perspective', '1px', true);
    var usePrefix = Modernizr._config.usePrefixes;

    // Webkit's 3D transforms are passed off to the browser's own graphics renderer.
    //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
    //   some conditions. As a result, Webkit typically recognizes the syntax but
    //   will sometimes throw a false positive, thus we must do a more thorough check:
    if (ret && (!usePrefix || 'webkitPerspective' in docElement.style)) {
      var mq;
      var defaultStyle = '#modernizr{width:0;height:0}';
      // Use CSS Conditional Rules if available
      if (Modernizr.supports) {
        mq = '@supports (perspective: 1px)';
      } else {
        // Otherwise, Webkit allows this media query to succeed only if the feature is enabled.
        // `@media (transform-3d),(-webkit-transform-3d){ ... }`
        mq = '@media (transform-3d)';
        if (usePrefix) {
          mq += ',(-webkit-transform-3d)';
        }
      }

      mq += '{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}';

      testStyles(defaultStyle + mq, function(elem) {
        ret = elem.offsetWidth === 7 && elem.offsetHeight === 18;
      });
    }

    return ret;
  });

/*!
{
  "name": "CSS Transitions",
  "property": "csstransitions",
  "caniuse": "css-transitions",
  "tags": ["css"]
}
!*/

  Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true));


  // Run each test
  testRunner();

  // Remove the "no-js" class if it exists
  setClasses(classes);

  delete ModernizrProto.addTest;
  delete ModernizrProto.addAsyncTest;

  // Run the things that are supposed to run after the tests
  for (var i = 0; i < Modernizr._q.length; i++) {
    Modernizr._q[i]();
  }

  // Leak Modernizr namespace
  window.Modernizr = Modernizr;


;

})(window, document);;(function($, window, undefined) {
    // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
    // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
 
    // requestAnimationFrame polyfill by Erik Möller
    // fixes from Paul Irish and Tino Zijdel
 
    var lastTime = 0,
        running,
        animate = function (elem) {
            if (running) {
                window.requestAnimationFrame(animate, elem);
                jQuery.fx.tick();
            }
        },
        vendors = ['ms', 'moz', 'webkit', 'o'];
 
    for(var x = 0, len = vendors.length; x < len && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
            || window[vendors[x]+'CancelRequestAnimationFrame'];
    }
 
    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(fn, element) {
            var currTime = new Date().getTime(),
                delta = currTime - lastTime,
                timeToCall = Math.max(0, 16 - delta);
 
            var id = window.setTimeout(function() {
                    fn(currTime + timeToCall);
                },
                timeToCall
            );
 
            lastTime = currTime + timeToCall;
 
            return id;
        };
 
    if (!window.cancelAnimationFrame) {
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
    }
 
    jQuery.fx.timer = function (timer) {
        if (timer() && jQuery.timers.push(timer) && !running) {
            running = true;
            animate(timer.elem);
        }
    };
 
    jQuery.fx.stop = function() {
        running = false;
    };
 
}(jQuery, this));;/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
 * Licensed under the MIT License (LICENSE.txt).
 *
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 * Thanks to: Seamus Leahy for adding deltaX and deltaY
 *
 * Version: 3.0.6
 * 
 * Requires: 1.2.2+
 */

(function($) {

var types = ['DOMMouseScroll', 'mousewheel'];

if ($.event.fixHooks) {
    for ( var i=types.length; i; ) {
        $.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
    }
}

$.event.special.mousewheel = {
    setup: function() {
        if ( this.addEventListener ) {
            for ( var i=types.length; i; ) {
                this.addEventListener( types[--i], handler, false );
            }
        } else {
            this.onmousewheel = handler;
        }
    },
    
    teardown: function() {
        if ( this.removeEventListener ) {
            for ( var i=types.length; i; ) {
                this.removeEventListener( types[--i], handler, false );
            }
        } else {
            this.onmousewheel = null;
        }
    }
};

$.fn.extend({
    mousewheel: function(fn) {
        return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
    },
    
    unmousewheel: function(fn) {
        return this.unbind("mousewheel", fn);
    }
});


function handler(event) {
    var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
    event = $.event.fix(orgEvent);
    event.type = "mousewheel";
    
    // Old school scrollwheel delta
    if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
    if ( orgEvent.detail     ) { delta = -orgEvent.detail/3; }
    
    // New school multidimensional scroll (touchpads) deltas
    deltaY = delta;
    
    // Gecko
    if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
        deltaY = 0;
        deltaX = -1*delta;
    }
    
    // Webkit
    if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
    if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
    
    // Add event and delta to the front of the arguments
    args.unshift(event, delta, deltaX, deltaY);
    
    return ($.event.dispatch || $.event.handle).apply(this, args);
}

})(jQuery);
;/**
 * jQuery iLightBox - Revolutionary Lightbox Plugin
 * http://www.ilightbox.net/
 *
 * @version: 2.2.0 - September 23, 2014
 *
 * @author: Hemn Chawroka
 *          http://www.iprodev.com/
 *
 */
(function($, window, undefined) {

	var extensions = {
			flash: ['swf'],
			image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe'],
			iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'],
			video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v']
		},

		// Global DOM elements
		$win = $(window),
		$doc = $(document),

		// Support indicators
		browser,
		transform,
		gpuAcceleration,
		fullScreenApi = '',
		supportTouch = !!('ontouchstart' in window) && (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)),

		// Events
		// ThemeFusion edit for Avada theme: remove the .iLightBox namespace from click event to avoid different button errors
		clickEvent = supportTouch ? "itap" : "click",
		globalClickEvent = supportTouch ? "itap" : "click",
		touchStartEvent = supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox",
		touchStopEvent = supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox",
		touchMoveEvent = supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox",

		// Math shorthands
		abs = Math.abs,
		sqrt = Math.sqrt,
		round = Math.round,
		max = Math.max,
		min = Math.min,
		floor = Math.floor,
		random = Math.random,

		pluginspages = {
			quicktime: 'http://www.apple.com/quicktime/download',
			flash: 'http://www.adobe.com/go/getflash'
		},

		iLightBox = function(el, options, items, instant) {
			var iL = this;

			iL.options = options,
				iL.selector = el.selector || el,
				iL.context = el.context,
				iL.instant = instant;

			if (items.length < 1) { iL.attachItems(); }
			else { iL.items = items; }

			iL.vars = {
				total: iL.items.length,
				start: 0,
				current: null,
				next: null,
				prev: null,
				BODY: $('body'),
				loadRequests: 0,
				overlay: $('<div class="ilightbox-overlay"></div>'),
				loader: $('<div class="ilightbox-loader"><div></div></div>'),
				toolbar: $('<div class="ilightbox-toolbar"></div>'),
				innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'),
				title: $('<div class="ilightbox-title"></div>'),
				closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'),
				fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'),
				innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'),
				innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'),
				innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'),
				holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
				nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
				prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
				nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'),
				prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
				thumbnails: $('<div class="ilightbox-thumbnails" ondragstart="return false;"><div class="ilightbox-thumbnails-container"><a class="ilightbox-thumbnails-dragger"></a><div class="ilightbox-thumbnails-grid"></div></div></div>'),
				thumbs: false,
				nextLock: false,
				prevLock: false,
				hashLock: false,
				isMobile: false,
				mobileMaxWidth: 980,
				isInFullScreen: false,
				isSwipe: false,
				mouseID: 0,
				cycleID: 0,
				isPaused: 0
			};

			// Hideable elements with mousemove event
			iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton);

			iL.normalizeItems();

			//Check necessary plugins
			iL.availPlugins();

			//Set startFrom
			iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom;

			//If randomStart
			iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom;
			iL.vars.start = iL.options.startFrom;

			if (instant) {  iL.instantCall(); }
			else { iL.patchItemsEvents(); }

			if (iL.options.linkId) {
				iL.hashChangeHandler();
				$win.iLightBoxHashChange(function() {
					iL.hashChangeHandler();
				});
			}

			if (supportTouch) {
				var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig,
					replace = "itap";
				iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace),
					iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace),
					iL.options.social.show = iL.options.social.show.replace(RegExp, replace),
					iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace);
			}

			if (iL.options.controls.arrows) {
				$.extend(iL.options.styles, {
					nextOffsetX: 0,
					prevOffsetX: 0,
					nextOpacity: 0,
					prevOpacity: 0
				});
			}
		};

	//iLightBox helpers
	iLightBox.prototype = {
		showLoader: function() {

			var iL = this;
			iL.vars.loadRequests += 1;
			if (iL.options.path.toLowerCase() == "horizontal") { iL.vars.loader.stop().animate({
				top: '-30px'
			}, iL.options.show.speed, 'easeOutCirc'); }
			else { iL.vars.loader.stop().animate({
				left: '-30px'
			}, iL.options.show.speed, 'easeOutCirc'); }
		},

		hideLoader: function() {
			var iL = this;
			iL.vars.loadRequests -= 1;
			iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests;
			if (iL.options.path.toLowerCase() == "horizontal") {
				if (iL.vars.loadRequests <= 0)  {
						iL.vars.loader.stop().animate({
						top: '-192px'
						}, iL.options.show.speed, 'easeInCirc');
				}
			} else {
				if (iL.vars.loadRequests <= 0) {
						iL.vars.loader.stop().animate({
						left: '-192px'
						}, iL.options.show.speed, 'easeInCirc');
				}
			}
		},

		createUI: function() {
			var iL = this;

			iL.ui = {
				currentElement: iL.vars.holder,
				nextElement: iL.vars.nextPhoto,
				prevElement: iL.vars.prevPhoto,
				currentItem: iL.vars.current,
				nextItem: iL.vars.next,
				prevItem: iL.vars.prev,
				hide: function() {
					iL.closeAction();
				},
				refresh: function() {
					(arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto();
				},
				fullscreen: function() {
					iL.fullScreenAction();
				}
			};
		},

		attachItems: function() {
			var iL = this,
				itemsObject = new Array(),
				items = new Array();

			$(iL.selector, iL.context).each(function() {
				var t = $(this),
					URL = t.attr(iL.options.attr) || null,
					options = t.data("options") && eval("({" + t.data("options") + "})") || {},
					caption = t.data('caption'),
					title = t.data('title'),
					type = t.data('type') || getTypeByExtension(URL);

				items.push({
					URL: URL,
					caption: caption,
					title: title,
					type: type,
					options: options
				});

				if (!iL.instant) { itemsObject.push(t); }
			});

			iL.items = items,
				iL.itemsObject = itemsObject;

			/* Edit by ThemeFusion to fix the total amount of items issue on refresh */
			if( iL.vars ) {
				iL.vars.total = items.length;
			}
		},

		normalizeItems: function() {
			var iL = this,
				newItems = new Array();

			$.each(iL.items, function(key, val) {

				if (typeof val == "string") {
					val = {
						url: val
					};
				}

				var URL = val.url || val.URL || null,
					options = val.options || {},
					caption = val.caption || null,
					title = val.title || null,
					type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL),
					ext = (typeof URL != 'object') ? getExtension(URL) : '';

				options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
				options.videoType = options.videoType || null,
				options.skin = options.skin || iL.options.skin,
				options.width = options.width || null,
				options.height = options.height || null,
				options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true,
				options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true,
				options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons);

				if (type == "video") {
					options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {};

					options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null;
					options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls";
					options.html5video.preload = options.html5video.preload || "metadata";
					options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false;
				}

				if (!options.width || !options.height) {
					// ThemeFusion edit for Avada theme; set width from 1280x700 (100% for iframe) to the theme option values
					if (type == "video") { options.width = js_local_vars.lightbox_video_width, options.height = js_local_vars.lightbox_video_height; }
					else if (type == "iframe") { options.width = js_local_vars.lightbox_video_width, options.height = js_local_vars.lightbox_video_height; }
					else if (type == "flash") { options.width = js_local_vars.lightbox_video_width, options.height = js_local_vars.lightbox_video_height; }
				}

				delete val.url;
				val.index = key;
				val.URL = URL;
				val.caption = caption;
				val.title = title;
				val.type = type;
				val.options = options;
				val.ext = ext;

				newItems.push(val);
			});

			iL.items = newItems;
		},

		instantCall: function() {
			var iL = this,
				key = iL.vars.start;

			iL.vars.current = key;
			iL.vars.next = (iL.items[key + 1]) ? key + 1 : null;
			iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null;

			iL.addContents();
			iL.patchEvents();
		},

		addContents: function() {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				viewport = getViewport(),
				path = opts.path.toLowerCase(),
				recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) {
					return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition);
				}),
				needRecognition = recognizingItems.length > 0;

			if (opts.mobileOptimizer && !opts.innerToolbar) {
				vars.isMobile = viewport.width <= vars.mobileMaxWidth;
			}

			vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity);

			if (opts.linkId) {
				vars.overlay[0].setAttribute('linkid', opts.linkId);
			}

			//Add Toolbar Buttons
			if (opts.controls.toolbar) {
				vars.toolbar.addClass(opts.skin).append(vars.closeButton);
				if (opts.controls.fullscreen) {
					vars.toolbar.append(vars.fullScreenButton);
				}
				if (opts.controls.slideshow) {
					vars.toolbar.append(vars.innerPlayButton);
				}
				if (vars.total > 1) {
					vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton);
				}
			}

			//Append elements to body
			vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto);

			if (!opts.innerToolbar) {
				vars.BODY.append(vars.toolbar);
			}
			if (opts.controls.arrows) {
				vars.BODY.append(vars.nextButton).append(vars.prevButton);
			}
			if (opts.controls.thumbnail && vars.total > 1) {
				vars.BODY.append(vars.thumbnails);
				vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path);
				$('div.ilightbox-thumbnails-grid', vars.thumbnails).empty();
				vars.thumbs = true;
			}

			//Configure loader and arrows
			var loaderCss = (opts.path.toLowerCase() == "horizontal") ? {
				left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2))
			} : {
				top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2))
			};
			vars.loader.addClass(opts.skin).css(loaderCss);
			vars.nextButton.add(vars.prevButton).addClass(opts.skin);
			if (path == "horizontal") {
				vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal');
			}
			// Configure arrow buttons
			vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile');

			if (!opts.infinite) {
				vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
				vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');

				if (vars.current == 0) {
					vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
				}
				if (vars.current >= vars.total - 1) {
					vars.nextButton.add(vars.innerNextButton).addClass('disabled');
				}
			}

			if (opts.show.effect) {
				vars.overlay.stop().fadeIn(opts.show.speed);
				vars.toolbar.stop().fadeIn(opts.show.speed);
			} else {
				vars.overlay.show();
				vars.toolbar.show();
			}

			var length = recognizingItems.length;
			if (needRecognition) {
				iL.showLoader();

				$.each(recognizingItems, function(key, val) {
					var resultFnc = function(result) {
							var key = -1,
								filter = iL.items.filter(function(e, i, arr) {
									if (e.URL == result.url) {
										key = i;
									}

									return e.URL == result.url;
								}),
								self = iL.items[key];

							if (result) {
								$.extend(true, self, {
									URL: result.source,
									type: result.type,
									recognized: true,
									options: {
										html5video: result.html5video,
										width: (result.type == "image") ? 0 : (result.width || self.width),
										height: (result.type == "image") ? 0 : (result.height || self.height),
										thumbnail: self.options.thumbnail || result.thumbnail
									}
								});
							}

							length--;

							if (length == 0) {
								iL.hideLoader();

								vars.dontGenerateThumbs = false;
								iL.generateThumbnails();

								if (opts.show.effect) {
									setTimeout(function() {
										iL.generateBoxes();
									}, opts.show.speed);
								}
								else {
									iL.generateBoxes();
								}
							}
						};

					iL.ogpRecognition(this, resultFnc);
				});
			}
			else {
				if (opts.show.effect) {
					setTimeout(function() {
						iL.generateBoxes();
					}, opts.show.speed);
				}
				else {
					iL.generateBoxes();
				}
			}

			iL.createUI();

			window.iLightBox = {
				close: function() {
					iL.closeAction();
				},
				fullscreen: function() {
					iL.fullScreenAction();
				},
				moveNext: function() {
					iL.moveTo('next');
				},
				movePrev: function() {
					iL.moveTo('prev');
				},
				goTo: function(index) {
					iL.goTo(index);
				},
				refresh: function() {
					iL.refresh();
				},
				reposition: function() {
					(arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto();
				},
				setOption: function(options) {
					iL.setOption(options);
				},
				destroy: function() {
					iL.closeAction();
					iL.dispatchItemsEvents();
				}
			};

			if (opts.linkId) {
				vars.hashLock = true;
				window.location.hash = opts.linkId + '/' + vars.current;
				setTimeout(function() {
					vars.hashLock = false;
				}, 55);
			}

			if (!opts.slideshow.startPaused) {
				iL.resume();
				vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause');
			}

			//Trigger the onOpen callback
			if (typeof iL.options.callback.onOpen == 'function') { iL.options.callback.onOpen.call(iL); }
		},

		loadContent: function(obj, opt, speed) {
			var iL = this,
				holder, item;

			iL.createUI();

			obj.speed = speed || iL.options.effects.loadedFadeSpeed;

			if (opt == 'current') {
				if (!obj.options.mousewheel) { iL.vars.lockWheel = true; }
				else { iL.vars.lockWheel = false; }

				if (!obj.options.swipe) { iL.vars.lockSwipe = true; }
				else { iL.vars.lockSwipe = false; }
			}

			switch (opt) {
				case 'current':
					holder = iL.vars.holder, item = iL.vars.current;
					break;
				case 'next':
					holder = iL.vars.nextPhoto, item = iL.vars.next;
					break;
				case 'prev':
					holder = iL.vars.prevPhoto, item = iL.vars.prev;
					break;
			}

			holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin);
			$('div.ilightbox-inner-toolbar', holder).remove();

			if (obj.title || iL.options.innerToolbar) {
				var innerToolbar = iL.vars.innerToolbar.clone();
				if (obj.title && iL.options.show.title) {
					var title = iL.vars.title.clone();
					title.empty().html(obj.title);
					innerToolbar.append(title);
				}
				if (iL.options.innerToolbar) {
					innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar);
				}
				holder.prepend(innerToolbar);
			}

			iL.loadSwitcher(obj, holder, item, opt);
		},

		loadSwitcher: function(obj, holder, item, opt) {
			var iL = this,
				opts = iL.options,
				api = {
					element: holder,
					position: item
				};

			switch (obj.type) {
				case 'image':
					//Trigger the onBeforeLoad callback
					if (typeof opts.callback.onBeforeLoad == 'function') { opts.callback.onBeforeLoad.call(iL, iL.ui, item); }
					if (typeof obj.options.onBeforeLoad == 'function') { obj.options.onBeforeLoad.call(iL, api); }

					iL.loadImage(obj.URL, function(img) {
						//Trigger the onAfterLoad callback
						if (typeof opts.callback.onAfterLoad == 'function') { opts.callback.onAfterLoad.call(iL, iL.ui, item); }
						if (typeof obj.options.onAfterLoad == 'function') { obj.options.onAfterLoad.call(iL, api); }

						var width = (img) ? img.width : 400,
							height = (img) ? img.height : 200;

						holder.data({
							naturalWidth: width,
							naturalHeight: height
						});
						$('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>');

						//Trigger the onRender callback
						if (typeof opts.callback.onRender == 'function') { opts.callback.onRender.call(iL, iL.ui, item); }
						if (typeof obj.options.onRender == 'function') { obj.options.onRender.call(iL, api); }

						iL.configureHolder(obj, opt, holder);
					});

					break;

				case 'video':
					holder.data({
						naturalWidth: obj.options.width,
						naturalHeight: obj.options.height
					});

					iL.addContent(holder, obj);

					//Trigger the onRender callback
					if (typeof opts.callback.onRender == 'function') { opts.callback.onRender.call(iL, iL.ui, item); }
					if (typeof obj.options.onRender == 'function') { obj.options.onRender.call(iL, api); }

					iL.configureHolder(obj, opt, holder);

					break;

				case 'iframe':
					// ThemeFusion edit for Avada theme: added possibility to add width and height as part of query string for videos
					var $query_array = obj.URL.substring( obj.URL.indexOf( '?' ) + 1 ).split( '&' ),
						$query_object = {};

					for ( var $i = 0; $i < $query_array.length; ++$i ) {
						var $single_query = $query_array[$i].split( '=' );
						if ( $single_query.length != 2 ) continue;

						if ( $single_query[0] == 'w' ) {
							$single_query[0] = 'width';
						}

						if ( $single_query[0] == 'h' ) {
							$single_query[0] = 'height';
						}

						$query_object[$single_query[0]] = decodeURIComponent( $single_query[1].replace( /\+/g, " " ) );
					}
					// End Edit

					iL.showLoader();
					holder.data({
						naturalWidth: ( $query_object['width'] ) ? $query_object['width'] : obj.options.width,
						naturalHeight: ( $query_object['height'] ) ? $query_object['height'] : obj.options.height
					});
					var el = iL.addContent(holder, obj);

					//Trigger the onRender callback
					if (typeof opts.callback.onRender == 'function') { opts.callback.onRender.call(iL, iL.ui, item); }
					if (typeof obj.options.onRender == 'function') { obj.options.onRender.call(iL, api); }

					//Trigger the onBeforeLoad callback
					if (typeof opts.callback.onBeforeLoad == 'function') { opts.callback.onBeforeLoad.call(iL, iL.ui, item); }
					if (typeof obj.options.onBeforeLoad == 'function') { obj.options.onBeforeLoad.call(iL, api); }

					el.bind('load', function() {
						//Trigger the onAfterLoad callback
						if (typeof opts.callback.onAfterLoad == 'function') { opts.callback.onAfterLoad.call(iL, iL.ui, item); }
						if (typeof obj.options.onAfterLoad == 'function') { obj.options.onAfterLoad.call(iL, api); }

						iL.hideLoader();
						iL.configureHolder(obj, opt, holder);
						el.unbind('load');
					});

					break;

				case 'inline':
					var el = $(obj.URL),
						content = iL.addContent(holder, obj),
						images = findImageInElement(holder);

					holder.data({
						naturalWidth: (iL.items[item].options.width || el.outerWidth()),
						naturalHeight: (iL.items[item].options.height || el.outerHeight())
					});
					content.children().eq(0).show();

					//Trigger the onRender callback
					if (typeof opts.callback.onRender == 'function') { opts.callback.onRender.call(iL, iL.ui, item); }
					if (typeof obj.options.onRender == 'function') { obj.options.onRender.call(iL, api); }

					//Trigger the onBeforeLoad callback
					if (typeof opts.callback.onBeforeLoad == 'function') { opts.callback.onBeforeLoad.call(iL, iL.ui, item); }
					if (typeof obj.options.onBeforeLoad == 'function') { obj.options.onBeforeLoad.call(iL, api); }

					iL.loadImage(images, function() {
						//Trigger the onAfterLoad callback
						if (typeof opts.callback.onAfterLoad == 'function') { opts.callback.onAfterLoad.call(iL, iL.ui, item); }
						if (typeof obj.options.onAfterLoad == 'function') { obj.options.onAfterLoad.call(iL, api); }

						iL.configureHolder(obj, opt, holder);
					});

					break;

				case 'flash':
					var el = iL.addContent(holder, obj);

					holder.data({
						naturalWidth: (iL.items[item].options.width || el.outerWidth()),
						naturalHeight: (iL.items[item].options.height || el.outerHeight())
					});

					//Trigger the onRender callback
					if (typeof opts.callback.onRender == 'function') { opts.callback.onRender.call(iL, iL.ui, item); }
					if (typeof obj.options.onRender == 'function') { obj.options.onRender.call(iL, api); }

					iL.configureHolder(obj, opt, holder);

					break;

				case 'ajax':
					var ajax = obj.options.ajax || {};
					//Trigger the onBeforeLoad callback
					if (typeof opts.callback.onBeforeLoad == 'function') { opts.callback.onBeforeLoad.call(iL, iL.ui, item); }
					if (typeof obj.options.onBeforeLoad == 'function') { obj.options.onBeforeLoad.call(iL, api); }

					iL.showLoader();
					$.ajax({
						url: obj.URL || opts.ajaxSetup.url,
						data: ajax.data || null,
						dataType: ajax.dataType || "html",
						type: ajax.type || opts.ajaxSetup.type,
						cache: ajax.cache || opts.ajaxSetup.cache,
						crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain,
						global: ajax.global || opts.ajaxSetup.global,
						ifModified: ajax.ifModified || opts.ajaxSetup.ifModified,
						username: ajax.username || opts.ajaxSetup.username,
						password: ajax.password || opts.ajaxSetup.password,
						beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend,
						complete: ajax.complete || opts.ajaxSetup.complete,
						success: function(data, textStatus, jqXHR) {
							iL.hideLoader();

							var el = $(data),
								container = $('div.ilightbox-container', holder),
								elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')),
								elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')),
								css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? {
									'overflow': 'hidden'
								} : {};

							container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el));
							holder.show().data({
								naturalWidth: (elWidth || container.outerWidth()),
								naturalHeight: (elHeight || container.outerHeight())
							}).hide();

							//Trigger the onRender callback
							if (typeof opts.callback.onRender == 'function') { opts.callback.onRender.call(iL, iL.ui, item); }
							if (typeof obj.options.onRender == 'function') { obj.options.onRender.call(iL, api); }

							var images = findImageInElement(holder);
							iL.loadImage(images, function() {
								//Trigger the onAfterLoad callback
								if (typeof opts.callback.onAfterLoad == 'function') { opts.callback.onAfterLoad.call(iL, iL.ui, item); }
								if (typeof obj.options.onAfterLoad == 'function') { obj.options.onAfterLoad.call(iL, api); }

								iL.configureHolder(obj, opt, holder);
							});

							opts.ajaxSetup.success(data, textStatus, jqXHR);
							if (typeof ajax.success == 'function') { ajax.success(data, textStatus, jqXHR); }
						},
						error: function(jqXHR, textStatus, errorThrown) {
							//Trigger the onAfterLoad callback
							if (typeof opts.callback.onAfterLoad == 'function') { opts.callback.onAfterLoad.call(iL, iL.ui, item); }
							if (typeof obj.options.onAfterLoad == 'function') { obj.options.onAfterLoad.call(iL, api); }f

							iL.hideLoader();
							$('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>');
							iL.configureHolder(obj, opt, holder);

							opts.ajaxSetup.error(jqXHR, textStatus, errorThrown);
							if (typeof ajax.error == 'function') { ajax.error(jqXHR, textStatus, errorThrown); }
						}
					});

					break;

				case 'html':
					var object = obj.URL,
						el
					container = $('div.ilightbox-container', holder);

					if (object[0].nodeName) { el = object.clone(); }
					else {
						var dom = $(object);
						if (dom.selector) { el = $('<div>' + dom + '</div>'); }
						else { el = dom; }
					}

					var elWidth = iL.items[item].options.width || parseInt(el.attr('width')),
						elHeight = iL.items[item].options.height || parseInt(el.attr('height'));

					iL.addContent(holder, obj);

					el.appendTo(document.documentElement).hide();

					//Trigger the onRender callback
					if (typeof opts.callback.onRender == 'function') { opts.callback.onRender.call(iL, iL.ui, item); }
					if (typeof obj.options.onRender == 'function') { obj.options.onRender.call(iL, api); }

					var images = findImageInElement(holder);

					//Trigger the onBeforeLoad callback
					if (typeof opts.callback.onBeforeLoad == 'function') { opts.callback.onBeforeLoad.call(iL, iL.ui, item); }
					if (typeof obj.options.onBeforeLoad == 'function') { obj.options.onBeforeLoad.call(iL, api); }

					iL.loadImage(images, function() {
						//Trigger the onAfterLoad callback
						if (typeof opts.callback.onAfterLoad == 'function') { opts.callback.onAfterLoad.call(iL, iL.ui, item); }
						if (typeof obj.options.onAfterLoad == 'function') { obj.options.onAfterLoad.call(iL, api); }

						holder.show().data({
							naturalWidth: (elWidth || container.outerWidth()),
							naturalHeight: (elHeight || container.outerHeight())
						}).hide();
						el.remove();

						iL.configureHolder(obj, opt, holder);
					});

					break;
			}
		},

		configureHolder: function(obj, opt, holder) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options;

			if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev');

			if (opt == "current") {
				var item = vars.current;
			} else if (opt == "next") {
				var opacity = opts.styles.nextOpacity,
					item = vars.next;
			} else {
				var opacity = opts.styles.prevOpacity,
					item = vars.prev;
			}

			var api = {
				element: holder,
				position: item
			};

			iL.items[item].options.width = iL.items[item].options.width || 0,
				iL.items[item].options.height = iL.items[item].options.height || 0;

			if (opt == "current") {
				if (opts.show.effect) { holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() {
					holder.css(transform, '');
					if (obj.caption) {
						iL.setCaption(obj, holder);
						var caption = $('div.ilightbox-caption', holder),
							percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100);
						if (opts.caption.start & percent <= 50) { caption.fadeIn(opts.effects.fadeSpeed); }
					}

					var social = obj.options.social;
					if (social) {
						iL.setSocial(social, obj.URL, holder);
						if (opts.social.start) { $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed); }
					}

					//Generate thumbnails
					iL.generateThumbnails();

					//Trigger the onShow callback
					if (typeof opts.callback.onShow == 'function') { opts.callback.onShow.call(iL, iL.ui, item); }
					if (typeof obj.options.onShow == 'function') { obj.options.onShow.call(iL, api); }
				});
				} else {
					holder.show();

					//Generate thumbnails
					iL.generateThumbnails();

					//Trigger the onShow callback
					if (typeof opts.callback.onShow == 'function') { opts.callback.onShow.call(iL, iL.ui, item); }
					if (typeof obj.options.onShow == 'function') { obj.options.onShow.call(iL, api); }
				}
			} else {
				if (opts.show.effect) { holder.fadeTo(obj.speed, opacity, function() {
					if (opt == "next") { vars.nextLock = false; }
					else { vars.prevLock = false; }

					//Generate thumbnails
					iL.generateThumbnails();

					//Trigger the onShow callback
					if (typeof opts.callback.onShow == 'function') { opts.callback.onShow.call(iL, iL.ui, item); }
					if (typeof obj.options.onShow == 'function') { obj.options.onShow.call(iL, api); }
				});
				} else {
					holder.css({
						opacity: opacity
					}).show();
					if (opt == "next") { vars.nextLock = false; }
					else { vars.prevLock = false; }

					//Generate thumbnails
					iL.generateThumbnails();

					//Trigger the onShow callback
					if (typeof opts.callback.onShow == 'function') { opts.callback.onShow.call(iL, iL.ui, item); }
					if (typeof obj.options.onShow == 'function') { obj.options.onShow.call(iL, api); }
				}
			}

			setTimeout(function() {
				iL.repositionPhoto();
			}, 0);
		},

		generateBoxes: function() {
			var iL = this,
				vars = iL.vars,
				opts = iL.options;

			if (opts.infinite && vars.total >= 3) {
				if (vars.current == vars.total - 1) { vars.next = 0; }
				if (vars.current == 0) { vars.prev = vars.total - 1; }
			} else { opts.infinite = false; }

			iL.loadContent(iL.items[vars.current], 'current', opts.show.speed);

			if (iL.items[vars.next]) { iL.loadContent(iL.items[vars.next], 'next', opts.show.speed); }
			if (iL.items[vars.prev]) { iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed); }
		},

		generateThumbnails: function() {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				timeOut = null;

			if (vars.thumbs && !iL.vars.dontGenerateThumbs) {
				var thumbnails = vars.thumbnails,
					container = $('div.ilightbox-thumbnails-container', thumbnails),
					grid = $('div.ilightbox-thumbnails-grid', container),
					i = 0;

				grid.removeAttr('style').empty();

				$.each(iL.items, function(key, val) {
					var isActive = (vars.current == key) ? 'ilightbox-active' : '',
						opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity,
						thumb = val.options.thumbnail,
						thumbnail = $('<div class="ilightbox-thumbnail"></div>'),
						icon = $('<div class="ilightbox-thumbnail-icon"></div>');

					thumbnail.css({
						opacity: 0
					}).addClass(isActive);

					if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') {
						icon.addClass('ilightbox-thumbnail-video');
						thumbnail.append(icon);
					} else if (val.options.icon) {
						icon.addClass('ilightbox-thumbnail-' + val.options.icon);
						thumbnail.append(icon);
					}

					if (thumb) { iL.loadImage(thumb, function(img) {
						i++;
						if (img) { thumbnail.data({
							naturalWidth: img.width,
							naturalHeight: img.height
						}).append('<img src="' + thumb + '" border="0" />');
						} else { thumbnail.data({
							naturalWidth: opts.thumbnails.maxWidth,
							naturalHeight: opts.thumbnails.maxHeight
						});
						}

						clearTimeout(timeOut);
						timeOut = setTimeout(function() {
							iL.positionThumbnails(thumbnails, container, grid);
						}, 20);
						setTimeout(function() {
							thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity);
						}, i * 20);
					});
					}

					grid.append(thumbnail);
				});
				iL.vars.dontGenerateThumbs = true;
			}
		},

		positionThumbnails: function(thumbnails, container, grid) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				viewport = getViewport(),
				path = opts.path.toLowerCase();

			if (!thumbnails) { thumbnails = vars.thumbnails; }
			if (!container) { container = $('div.ilightbox-thumbnails-container', thumbnails); }
			if (!grid) { grid = $('div.ilightbox-thumbnails-grid', container); }

			var thumbs = $('.ilightbox-thumbnail', grid),
				widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX,
				heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY,
				gridWidth = (path == 'horizontal') ? 0 : widthAvail,
				gridHeight = (path == 'horizontal') ? heightAvail : 0,
				active = $('.ilightbox-active', grid),
				gridCss = {},
				css = {};

			if (arguments.length < 3) {
				thumbs.css({
					opacity: opts.thumbnails.normalOpacity
				});
				active.css({
					opacity: opts.thumbnails.activeOpacity
				});
			}

			thumbs.each(function(i) {
				var t = $(this),
					data = t.data(),
					width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth;
				height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0;
				dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true);

				t.css({
					width: dims.width,
					height: dims.height
				});
				if (path == 'horizontal') { t.css({
					'float': 'left'
				});
				}

				(path == 'horizontal') ? (
					gridWidth += t.outerWidth()
				) : (
					gridHeight += t.outerHeight()
				);
			});

			gridCss = {
				width: gridWidth,
				height: gridHeight
			};

			grid.css(gridCss);

			gridCss = {};

			var gridOffset = grid.offset(),
				activeOffset = (active.length) ? active.offset() : {
					top: parseInt(heightAvail / 2),
					left: parseInt(widthAvail / 2)
				};

			gridOffset.top = (gridOffset.top - $doc.scrollTop()),
				gridOffset.left = (gridOffset.left - $doc.scrollLeft()),
				activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()),
				activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft());

			(path == 'horizontal') ? (
				gridCss.top = 0,
				gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2))
			) : (
				gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))),
				gridCss.left = 0
			);

			if (arguments.length < 3) { grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc'); }
			else { grid.css(gridCss); }
		},

		loadImage: function(image, callback) {
			if (!$.isArray(image)) { image = [image]; }

			var iL = this,
				length = image.length;

			if (length > 0) {
				iL.showLoader();
				$.each(image, function(index, value) {
					var img = new Image();
					img.onload = function() {
						length -= 1;
						if (length == 0) {
							iL.hideLoader();
							callback(img);
						}
					};
					img.onerror = img.onabort = function() {
						length -= 1;
						if (length == 0) {
							iL.hideLoader();
							callback(false);
						}
					};
					img.src = image[index];
				});
			} else callback(false);
		},

		patchItemsEvents: function() {
			var iL = this,
				vars = iL.vars,
				clickEvent = supportTouch ? "itap.iL" : "click.iL",
				vEvent = supportTouch ? "click.iL" : "itap.iL";

			if (iL.context && iL.selector) {
				var $items = $(iL.selector, iL.context);

				$(iL.context).on(clickEvent, iL.selector, function() {
					var $this = $(this),
						key = $items.index($this);

					vars.current = key;
					vars.next = iL.items[key + 1] ? key + 1 : null;
					vars.prev = iL.items[key - 1] ? key - 1 : null;

					iL.addContents();
					iL.patchEvents();

					return false;
				}).on(vEvent, iL.selector, function() {
					return false;
				});
			} else {
				$.each(iL.itemsObject, function(key, val) {
					val.on(clickEvent, function() {
						vars.current = key;
						vars.next = iL.items[key + 1] ? key + 1 : null;
						vars.prev = iL.items[key - 1] ? key - 1 : null;

						iL.addContents();
						iL.patchEvents();

						return false;
					}).on(vEvent, function() {
						return false;
					});
				});
			}
		},

		dispatchItemsEvents: function() {
			var iL = this,
				vars = iL.vars,
				opts = iL.options;

			if (iL.context && iL.selector) {
				$(iL.context).off('.iL', iL.selector);
			} else {
				$.each(iL.itemsObject, function(key, val) {
					val.off('.iL');
				});
			}
		},

		refresh: function() {
			var iL = this;
			iL.dispatchItemsEvents();
			iL.attachItems();
			iL.normalizeItems();
			iL.patchItemsEvents();
		},

		patchEvents: function() {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				path = opts.path.toLowerCase(),
				holders = $('.ilightbox-holder'),
				fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox',
				durationThreshold = 1000,
				horizontalDistanceThreshold =
				verticalDistanceThreshold = 100,
				buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild];

			$win.bind('resize.iLightBox', function() {
				var viewport = getViewport();

				if (opts.mobileOptimizer && !opts.innerToolbar) { vars.isMobile = viewport.width <= vars.mobileMaxWidth; }
				vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile');

				iL.repositionPhoto(null);
				if (supportTouch) {
					clearTimeout(vars.setTime);
					vars.setTime = setTimeout(function() {
						var scrollTop = getScrollXY().y;
						window.scrollTo(0, scrollTop - 30);
						window.scrollTo(0, scrollTop + 30);
						window.scrollTo(0, scrollTop);
					}, 2000);
				}
				if (vars.thumbs) { iL.positionThumbnails(); }
			}).bind('keydown.iLightBox', function(event) {
				if (opts.controls.keyboard) {
					switch (event.keyCode) {
						case 13:
							if (event.shiftKey && opts.keyboard.shift_enter) { iL.fullScreenAction(); }
							break;
						case 27:
							if (opts.keyboard.esc) { iL.closeAction(); }
							break;
						case 37:
							if (opts.keyboard.left && !vars.lockKey) { iL.moveTo('prev'); }
							break;
						case 38:
							if (opts.keyboard.up && !vars.lockKey) { iL.moveTo('prev'); }
							break;
						case 39:
							if (opts.keyboard.right && !vars.lockKey) { iL.moveTo('next'); }
							break;
						case 40:
							if (opts.keyboard.down && !vars.lockKey) { iL.moveTo('next'); }
							break;
					}
				}
			});

			if (fullScreenApi.supportsFullScreen) { $win.bind(fullscreenEvent, function() {
				iL.doFullscreen();
			});
			}

			var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) {
					return arr.lastIndexOf(e) === i;
				}),
				holderEvents = "";

			$.each(holderEventsArr, function(key, val) {
				if (key != 0) { holderEvents += ' '; }
				holderEvents += val;
			});

			$doc.on(clickEvent, '.ilightbox-overlay', function() {
				if (opts.overlay.blur) { iL.closeAction(); }
			}).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() {
				iL.moveTo('next');
			}).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() {
				iL.moveTo('prev');
			}).on(clickEvent, '.ilightbox-thumbnail', function() {
				var t = $(this),
					thumbs = $('.ilightbox-thumbnail', vars.thumbnails),
					index = thumbs.index(t);

				if (index != vars.current) { iL.goTo(index); }
			}).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) {
				var caption = $('div.ilightbox-caption', vars.holder),
					social = $('div.ilightbox-social', vars.holder),
					fadeSpeed = opts.effects.fadeSpeed;

				if (vars.nextLock || vars.prevLock) {
					if (e.type == opts.caption.show && !caption.is(':visible')) { caption.fadeIn(fadeSpeed); }
					else if (e.type == opts.caption.hide && caption.is(':visible')) { caption.fadeOut(fadeSpeed); }

					if (e.type == opts.social.show && !social.is(':visible')) { social.fadeIn(fadeSpeed); }
					else if (e.type == opts.social.hide && social.is(':visible')) { social.fadeOut(fadeSpeed); }
				} else {
					if (e.type == opts.caption.show && !caption.is(':visible')) { caption.stop().fadeIn(fadeSpeed); }
					else if (e.type == opts.caption.hide && caption.is(':visible')) { caption.stop().fadeOut(fadeSpeed); }

					if (e.type == opts.social.show && !social.is(':visible')) { social.stop().fadeIn(fadeSpeed); }
					else if (e.type == opts.social.hide && social.is(':visible')) { social.stop().fadeOut(fadeSpeed); }
				}
			}).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) {
				if (e.type == 'mouseenter') { vars.lockWheel = true; }
				else { vars.lockWheel = false; }
			}).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function(event) {
				var t = $(this);
				if (t.hasClass('ilightbox-fullscreen')) { iL.fullScreenAction(); }
				else if (t.hasClass('ilightbox-play')) {

					iL.resume();
					t.addClass('ilightbox-pause').removeClass('ilightbox-play');
				} else if (t.hasClass('ilightbox-pause')) {
					iL.pause();
					t.addClass('ilightbox-play').removeClass('ilightbox-pause');
				} else { iL.closeAction(); }
			}).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) {
				// prevent scrolling
				e.preventDefault();
			});

			function mouseMoveHandler(e) {
				if (!vars.isMobile) {
					if (!vars.mouseID) {
						vars.hideableElements.show();
					}

					vars.mouseID = clearTimeout(vars.mouseID);

					if (buttonsArray.indexOf(e.target) === -1) {
						vars.mouseID = setTimeout(function() {
							vars.hideableElements.hide();
							vars.mouseID = clearTimeout(vars.mouseID);
						}, 3000);
					}
				}
			}

			if (opts.controls.arrows && !supportTouch) { $doc.on('mousemove.iLightBox', mouseMoveHandler); }

			if (opts.controls.slideshow && opts.slideshow.pauseOnHover) { $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) {
				if (e.type == 'mouseenter' && vars.cycleID) { iL.pause(); }
				else if (e.type == 'mouseleave' && vars.isPaused) { iL.resume(); }
			});
			}

			var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails');

			if (opts.controls.mousewheel) { switchers.on('mousewheel.iLightBox', function(event, delta) {
				if (!vars.lockWheel) {
					event.preventDefault();
					if (delta < 0) { iL.moveTo('next'); }
					else if (delta > 0) { iL.moveTo('prev'); }
				}
			});
			}

			if (opts.controls.swipe) { holders.on(touchStartEvent, function(event) {
				if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) { return; }

				vars.BODY.addClass('ilightbox-closedhand');

				var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event,
					scrollTop = $doc.scrollTop(),
					scrollLeft = $doc.scrollLeft(),
					offsets = [
						holders.eq(0).offset(),
						holders.eq(1).offset(),
						holders.eq(2).offset()
					],
					offSet = [{
						top: offsets[0].top - scrollTop,
						left: offsets[0].left - scrollLeft
					}, {
						top: offsets[1].top - scrollTop,
						left: offsets[1].left - scrollLeft
					}, {
						top: offsets[2].top - scrollTop,
						left: offsets[2].left - scrollLeft
					}],
					start = {
						time: (new Date()).getTime(),
						coords: [data.pageX - scrollLeft, data.pageY - scrollTop]
					},
					stop;

				function moveEachHandler(i) {
					var t = $(this),
						offset = offSet[i],
						scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])];

					t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px';
				}

				function moveHandler(event) {

					if (!start) { return; }

					var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event;

					stop = {
						time: (new Date()).getTime(),
						coords: [data.pageX - scrollLeft, data.pageY - scrollTop]
					};

					holders.each(moveEachHandler);

					// prevent scrolling
					event.preventDefault();
				}

				function repositionHolders() {
					holders.each(function() {
						var t = $(this),
							offset = t.data('offset') || {
								top: t.offset().top - scrollTop,
								left: t.offset().left - scrollLeft
							},
							top = offset.top,
							left = offset.left;

						t.css(transform, gpuAcceleration).stop().animate({
							top: top,
							left: left
						}, 500, 'easeOutCirc', function() {
							t.css(transform, '');
						});
					});
				}

				holders.bind(touchMoveEvent, moveHandler);
				$doc.one(touchStopEvent, function(event) {
					holders.unbind(touchMoveEvent, moveHandler);

					vars.BODY.removeClass('ilightbox-closedhand');

					if (start && stop) {
						if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) {
							if (start.coords[0] > stop.coords[0]) {
								if (vars.current == vars.total - 1 && !opts.infinite) { repositionHolders(); }
								else {
									vars.isSwipe = true;
									iL.moveTo('next');
								}
							} else {
								if (vars.current == 0 && !opts.infinite) { repositionHolders(); }
								else {
									vars.isSwipe = true;
									iL.moveTo('prev');
								}
							}
						} else if (path == "vertical" && stop.time - start.time < durationThreshold && abs(start.coords[1] - stop.coords[1]) > horizontalDistanceThreshold && abs(start.coords[0] - stop.coords[0]) < verticalDistanceThreshold) {
							if (start.coords[1] > stop.coords[1]) {
								if (vars.current == vars.total - 1 && !opts.infinite) { repositionHolders(); }
								else {
									vars.isSwipe = true;
									iL.moveTo('next');
								}
							} else {
								if (vars.current == 0 && !opts.infinite) { repositionHolders(); }
								else {
									vars.isSwipe = true;
									iL.moveTo('prev');
								}
							}
						} else { repositionHolders(); }
					}
					start = stop = undefined;
				});
			});
			}
		},

		goTo: function(index) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				diff = (index - vars.current);

			if (opts.infinite) {
				if (index == vars.total - 1 && vars.current == 0) { diff = -1; }
				if (vars.current == vars.total - 1 && index == 0) { diff = 1; }
			}

			if (diff == 1) { iL.moveTo('next'); }
			else if (diff == -1) { iL.moveTo('prev'); }
			else {

				if (vars.nextLock || vars.prevLock) { return false; }

				//Trigger the onBeforeChange callback
				if (typeof opts.callback.onBeforeChange == 'function') { opts.callback.onBeforeChange.call(iL, iL.ui); }

				if (opts.linkId) {
					vars.hashLock = true;
					window.location.hash = opts.linkId + '/' + index;
				}

				if (iL.items[index]) {
					if (!iL.items[index].options.mousewheel) { vars.lockWheel = true; }
					else { iL.vars.lockWheel = false; }

					if (!iL.items[index].options.swipe) { vars.lockSwipe = true; }
					else { vars.lockSwipe = false; }
				}

				$.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) {
					val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed);
				});

				vars.current = index;
				vars.next = index + 1;
				vars.prev = index - 1;

				iL.createUI();

				setTimeout(function() {
					iL.generateBoxes();
				}, opts.effects.loadedFadeSpeed + 50);

				$('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active');
				iL.positionThumbnails();

				if (opts.linkId) { setTimeout(function() {
					vars.hashLock = false;
				}, 55);
				}

				// Configure arrow buttons
				if (!opts.infinite) {
					vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');

					if (vars.current == 0) {
						vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
					}
					if (vars.current >= vars.total - 1) {
						vars.nextButton.add(vars.innerNextButton).addClass('disabled');
					}
				}

				// Reset next cycle timeout
				iL.resetCycle();

				//Trigger the onAfterChange callback
				if (typeof opts.callback.onAfterChange == 'function') { opts.callback.onAfterChange.call(iL, iL.ui); }
			}
		},

		moveTo: function(side) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				path = opts.path.toLowerCase(),
				viewport = getViewport(),
				switchSpeed = opts.effects.switchSpeed;

			if (vars.nextLock || vars.prevLock) { return false; }
			else {

				var item = (side == "next") ? vars.next : vars.prev;

				if (opts.linkId) {
					vars.hashLock = true;
					window.location.hash = opts.linkId + '/' + item;
				}

				if (side == "next") {
					if (!iL.items[item]) { return false; }
					var firstHolder = vars.nextPhoto,
						secondHolder = vars.holder,
						lastHolder = vars.prevPhoto,
						firstClass = 'ilightbox-prev',
						secondClass = 'ilightbox-next';
				} else if (side == "prev") {
					if (!iL.items[item]) { return false; }
					var firstHolder = vars.prevPhoto,
						secondHolder = vars.holder,
						lastHolder = vars.nextPhoto,
						firstClass = 'ilightbox-next',
						secondClass = 'ilightbox-prev';
				}

				//Trigger the onBeforeChange callback
				if (typeof opts.callback.onBeforeChange == 'function') {
					opts.callback.onBeforeChange.call(iL, iL.ui);
				}

				(side == "next") ? vars.nextLock = true: vars.prevLock = true;

				var captionFirst = $('div.ilightbox-caption', secondHolder),
					socialFirst = $('div.ilightbox-social', secondHolder);

				if (captionFirst.length) {
					captionFirst.stop().fadeOut(switchSpeed, function() {
						$(this).remove();
					});
				}
				if (socialFirst.length) {
					socialFirst.stop().fadeOut(switchSpeed, function() {
						$(this).remove();
					});
				}

				if (iL.items[item].caption) {
					iL.setCaption(iL.items[item], firstHolder);
					var caption = $('div.ilightbox-caption', firstHolder),
						percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100);
					if (opts.caption.start && percent <= 50) { caption.fadeIn(switchSpeed); }
				}

				var social = iL.items[item].options.social;
				if (social) {
					iL.setSocial(social, iL.items[item].URL, firstHolder);
					if (opts.social.start) { $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed); }
				}

				$.each([firstHolder, secondHolder, lastHolder], function(key, val) {
					val.removeClass('ilightbox-next ilightbox-prev');
				});

				var firstOffset = firstHolder.data('offset'),
					winW = (viewport.width - (opts.styles.pageOffsetX)),
					winH = (viewport.height - (opts.styles.pageOffsetY)),
					width = firstOffset.newDims.width,
					height = firstOffset.newDims.height,
					thumbsOffset = firstOffset.thumbsOffset,
					diff = firstOffset.diff,
					top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)),
					left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2));

				firstHolder.css(transform, gpuAcceleration).animate({
					top: top,
					left: left,
					opacity: 1
				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
					firstHolder.css(transform, '');
				});

				$('div.ilightbox-container', firstHolder).animate({
					width: width,
					height: height
				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc');

				var secondOffset = secondHolder.data('offset'),
					object = secondOffset.object;

				diff = secondOffset.diff;

				width = secondOffset.newDims.width,
					height = secondOffset.newDims.height;

				width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']),
					height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']),
					top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2));

				if (side == 'prev') {
					left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2));
				} else {
					top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)),
						left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2));
				}

				$('div.ilightbox-container', secondHolder).animate({
					width: width,
					height: height
				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc');

				secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({
					top: top,
					left: left,
					opacity: opts.styles.prevOpacity
				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
					secondHolder.css(transform, '');

					$('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active');
					iL.positionThumbnails();

					if (iL.items[item]) {
						if (!iL.items[item].options.mousewheel) { vars.lockWheel = true; }
						else { vars.lockWheel = false; }

						if (!iL.items[item].options.swipe) { vars.lockSwipe = true; }
						else { vars.lockSwipe = false; }
					}

					vars.isSwipe = false;

					if (side == "next") {
						vars.nextPhoto = lastHolder,
							vars.prevPhoto = secondHolder,
							vars.holder = firstHolder;

						vars.nextPhoto.hide();

						vars.next = vars.next + 1,
							vars.prev = vars.current,
							vars.current = vars.current + 1;

						if (opts.infinite) {
							if (vars.current > vars.total - 1) { vars.current = 0; }
							if (vars.current == vars.total - 1) { vars.next = 0; }
							if (vars.current == 0) { vars.prev = vars.total - 1; }
						}

						iL.createUI();

						if (!iL.items[vars.next]) {
							vars.nextLock = false;
						} else {
							iL.loadContent(iL.items[vars.next], 'next');
						}
					} else {
						vars.prevPhoto = lastHolder;
						vars.nextPhoto = secondHolder;
						vars.holder = firstHolder;

						vars.prevPhoto.hide();

						vars.next = vars.current;
						vars.current = vars.prev;
						vars.prev = vars.current - 1;

						if (opts.infinite) {
							if (vars.current == vars.total - 1) { vars.next = 0; }
							if (vars.current == 0) { vars.prev = vars.total - 1; }
						}

						iL.createUI();

						if (!iL.items[vars.prev]) {
							vars.prevLock = false;
						} else {
							iL.loadContent(iL.items[vars.prev], 'prev');
						}
					}

					if (opts.linkId) { setTimeout(function() {
						vars.hashLock = false;
					}, 55);
					}

					// Configure arrow buttons
					if (!opts.infinite) {
						vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');

						if (vars.current == 0) {
							vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
						}

						if (vars.current >= vars.total - 1) {
							vars.nextButton.add(vars.innerNextButton).addClass('disabled');
						}
					}

					iL.repositionPhoto();

					// Reset next cycle timeout
					iL.resetCycle();

					//Trigger the onAfterChange callback
					if (typeof opts.callback.onAfterChange == 'function') {
						opts.callback.onAfterChange.call(iL, iL.ui);
					}
				});

				top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)),
					left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left');

				lastHolder.css(transform, gpuAcceleration).animate({
					top: top,
					left: left,
					opacity: opts.styles.nextOpacity
				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
					lastHolder.css(transform, '');
				}).addClass(secondClass);
			}
		},

		setCaption: function(obj, target) {
			var iL = this,
				caption = $('<div class="ilightbox-caption"></div>');

			if (obj.caption) {
				caption.html(obj.caption);
				$('div.ilightbox-container', target).append(caption);
			}
		},

		normalizeSocial: function(obj, url) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				baseURL = window.location.href;

			$.each(obj, function(key, value) {
				if (!value) {
					return true;
				}
				var item = key.toLowerCase(),
					source, text;

				switch (item) {
					case 'facebook':
						source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}",
							text = "Share on Facebook";
						break;
					case 'twitter':
						source = "http://twitter.com/home?status={URL}",
							text = "Share on Twitter";
						break;
					case 'googleplus':
						source = "https://plus.google.com/share?url={URL}",
							text = "Share on Google+";
						break;
					case 'delicious':
						source = "http://delicious.com/post?url={URL}",
							text = "Share on Delicious";
						break;
					case 'digg':
						source = "http://digg.com/submit?phase=2&url={URL}",
							text = "Share on Digg";
						break;
					case 'reddit':
						source = "http://reddit.com/submit?url={URL}",
							text = "Share on reddit";
						break;
				}

				obj[key] = {
					URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL,
					source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url),
					text: value.text || text || "Share on " + key,
					width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640,
					height: value.height || 360
				};

			});

			return obj;
		},

		setSocial: function(obj, url, target) {
			var iL = this,
				socialBar = $('<div class="ilightbox-social"></div>'),
				buttons = '<ul>';

			obj = iL.normalizeSocial(obj, url);

			$.each(obj, function(key, value) {
				var item = key.toLowerCase(),
					source = value.source.replace(/\{URL\}/g, encodeURIComponent(value.URL).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'));
				buttons += '<li class="' + key + '"><a href="' + source + '" onclick="javascript:window.open(this.href' + ((value.width <= 0 || value.height <= 0) ? '' : ', \'\', \'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=' + value.height + ',width=' + value.width + ',left=40,top=40\'') + ');return false;" title="' + value.text + '" target="_blank"></a></li>';
			});

			buttons += '</ul>';

			socialBar.html(buttons);
			$('div.ilightbox-container', target).append(socialBar);
		},

		fullScreenAction: function() {
			var iL = this,
				vars = iL.vars;

			if (fullScreenApi.supportsFullScreen) {
				if (fullScreenApi.isFullScreen()) { fullScreenApi.cancelFullScreen(document.documentElement); }
				else { fullScreenApi.requestFullScreen(document.documentElement); }
			} else {
				iL.doFullscreen();
			}
		},

		doFullscreen: function() {
			var iL = this,
				vars = iL.vars,
				viewport = getViewport(),
				opts = iL.options;

			if (opts.fullAlone) {
				var currentHolder = vars.holder,
					current = iL.items[vars.current],
					windowWidth = viewport.width,
					windowHeight = viewport.height,
					elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader],
					// ThemeFusion edit for Avada theme: fix fullscreen issues with second slide and nav arrows
					//hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails];
					hideElements = [vars.loader, vars.thumbnails];

				if (!vars.isInFullScreen) {
					vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true;
					vars.overlay.css({
						opacity: 1
					});

					$.each(hideElements, function(i, element) {
						element.hide();
					});

					vars.fullScreenButton.attr('title', opts.text.exitFullscreen);

					if (opts.fullStretchTypes.indexOf(current.type) != -1) { currentHolder.data({
						naturalWidthOld: currentHolder.data('naturalWidth'),
						naturalHeightOld: currentHolder.data('naturalHeight'),
						naturalWidth: windowWidth,
						naturalHeight: windowHeight
					});
					} else {
						var viewport = current.options.fullViewPort || opts.fullViewPort || '',
							newWidth = windowWidth,
							newHeight = windowHeight,
							width = currentHolder.data('naturalWidth'),
							height = currentHolder.data('naturalHeight');

						if (viewport.toLowerCase() == 'fill') {
							newHeight = (newWidth / width) * height;

							if (newHeight < windowHeight) {
								newWidth = (windowHeight / height) * width,
									newHeight = windowHeight;
							}
						} else if (viewport.toLowerCase() == 'fit') {
							var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true);

							newWidth = dims.width,
								newHeight = dims.height;
						} else if (viewport.toLowerCase() == 'stretch') {
							newWidth = newWidth,
								newHeight = newHeight;
						} else {
							var scale = (width > newWidth || height > newHeight) ? true : false,
								dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale);
							newWidth = dims.width,
								newHeight = dims.height;
						}

						currentHolder.data({
							naturalWidthOld: currentHolder.data('naturalWidth'),
							naturalHeightOld: currentHolder.data('naturalHeight'),
							naturalWidth: newWidth,
							naturalHeight: newHeight
						});
					}

					$.each(elements, function(key, val) {
						val.addClass('ilightbox-fullscreen');
					});

					//Trigger the onEnterFullScreen callback
					if (typeof opts.callback.onEnterFullScreen == 'function') { opts.callback.onEnterFullScreen.call(iL, iL.ui); }
				} else {
					vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false;
					vars.overlay.css({
						opacity: iL.options.overlay.opacity
					});

					$.each(hideElements, function(i, element) {
						element.show();
					});

					vars.fullScreenButton.attr('title', opts.text.enterFullscreen);

					currentHolder.data({
						naturalWidth: currentHolder.data('naturalWidthOld'),
						naturalHeight: currentHolder.data('naturalHeightOld'),
						naturalWidthOld: null,
						naturalHeightOld: null
					});

					$.each(elements, function(key, val) {
						val.removeClass('ilightbox-fullscreen');
					});

					//Trigger the onExitFullScreen callback
					if (typeof opts.callback.onExitFullScreen == 'function') { opts.callback.onExitFullScreen.call(iL, iL.ui); }
				}
			} else {
				if (!vars.isInFullScreen) { vars.isInFullScreen = true; }
				else { vars.isInFullScreen = false; }
			}
			iL.repositionPhoto(true);
		},

		closeAction: function() {
			var iL = this,
				vars = iL.vars,
				opts = iL.options;

			$win.unbind('.iLightBox');
			$doc.off('.iLightBox');

			if (vars.isInFullScreen) { fullScreenApi.cancelFullScreen(document.documentElement); }

			$('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox');

			if (opts.hide.effect) { vars.overlay.stop().fadeOut(opts.hide.speed, function() {
				vars.overlay.remove();
				vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox');
			});
			} else {
				vars.overlay.remove();
				vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox');
			}

			var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails];

			$.each(fadeOuts, function(i, element) {
				element.removeAttr('style').remove();
			});

			vars.dontGenerateThumbs = vars.isInFullScreen = false;

			window.iLightBox = null;

			if (opts.linkId) {
				vars.hashLock = true;
				removeHash();
				setTimeout(function() {
					vars.hashLock = false;
				}, 55);
			}

			//Trigger the onHide callback
			if (typeof opts.callback.onHide == 'function') { opts.callback.onHide.call(iL, iL.ui); }
		},

		repositionPhoto: function() {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				path = opts.path.toLowerCase(),
				viewport = getViewport(),
				winWidth = viewport.width,
				winHeight = viewport.height;

			var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()),
				thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)),
				width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)),
				height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)),
				offsetW = (path == 'horizontal') ? parseInt((iL.items[vars.next] || iL.items[vars.prev]) ? ((opts.styles.nextOffsetX + opts.styles.prevOffsetX)) * 2 : (((width / 10) <= 30) ? 30 : (width / 10))) : parseInt(((width / 10) <= 30) ? 30 : (width / 10)) + thumbsOffsetW,
				offsetH = (path == 'horizontal') ? parseInt(((height / 10) <= 30) ? 30 : (height / 10)) + thumbsOffsetH : parseInt((iL.items[vars.next] || iL.items[vars.prev]) ? ((opts.styles.nextOffsetX + opts.styles.prevOffsetX)) * 2 : (((height / 10) <= 30) ? 30 : (height / 10)));

			var elObject = {
				type: 'current',
				width: width,
				height: height,
				item: iL.items[vars.current],
				offsetW: offsetW,
				offsetH: offsetH,
				thumbsOffsetW: thumbsOffsetW,
				thumbsOffsetH: thumbsOffsetH,
				animate: arguments.length,
				holder: vars.holder
			};

			iL.repositionEl(elObject);

			if (iL.items[vars.next]) {
				elObject = $.extend(elObject, {
					type: 'next',
					item: iL.items[vars.next],
					offsetX: opts.styles.nextOffsetX,
					offsetY: opts.styles.nextOffsetY,
					holder: vars.nextPhoto
				});

				iL.repositionEl(elObject);
			}

			if (iL.items[vars.prev]) {
				elObject = $.extend(elObject, {
					type: 'prev',
					item: iL.items[vars.prev],
					offsetX: opts.styles.prevOffsetX,
					offsetY: opts.styles.prevOffsetY,
					holder: vars.prevPhoto
				});

				iL.repositionEl(elObject);
			}

			var loaderCss = (path == "horizontal") ? {
				left: parseInt((width / 2) - (vars.loader.outerWidth() / 2))
			} : {
				top: parseInt((height / 2) - (vars.loader.outerHeight() / 2))
			};
			vars.loader.css(loaderCss);
		},

		repositionEl: function(obj) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				path = opts.path.toLowerCase(),
				widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW),
				heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH),
				itemParent = obj.item,
				item = obj.item.options,
				holder = obj.holder,
				offsetX = obj.offsetX || 0,
				offsetY = obj.offsetY || 0,
				thumbsOffsetW = obj.thumbsOffsetW,
				thumbsOffsetH = obj.thumbsOffsetH;

			if (obj.type == 'current') {
				if (typeof item.width == 'number' && item.width) { widthAvail = ((vars.isInFullScreen && opts.fullAlone) && (opts.fullStretchTypes.indexOf(itemParent.type) != -1 || item.fullViewPort || opts.fullViewPort)) ? widthAvail : ((item.width > widthAvail) ? widthAvail : item.width);
				}
				if (typeof item.height == 'number' && item.height) { heightAvail = ((vars.isInFullScreen && opts.fullAlone) && (opts.fullStretchTypes.indexOf(itemParent.type) != -1 || item.fullViewPort || opts.fullViewPort)) ? heightAvail : ((item.height > heightAvail) ? heightAvail : item.height);
				}
			} else {
				if (typeof item.width == 'number' && item.width) { widthAvail = (item.width > widthAvail) ? widthAvail : item.width; }
				if (typeof item.height == 'number' && item.height) { heightAvail = (item.height > heightAvail) ? heightAvail : item.height; }
			}

			heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight());

			var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'),
				height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight');

			var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? {
					width: width,
					height: height
				} : iL.getNewDimenstions(widthAvail, heightAvail, width, height)),
				newDims = $.extend({}, dims, {});

			if (obj.type == 'prev' || obj.type == 'next') {
				width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)),
				height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale));
			} else {
				width = dims.width,
				height = dims.height;
			}

			var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2),
				heightDiff = parseInt((getPixel(holder, 'padding-top') + getPixel(holder, 'padding-bottom') + getPixel(holder, 'border-top-width') + getPixel(holder, 'border-bottom-width') + $('.ilightbox-inner-toolbar', holder).outerHeight()) / 2);

			switch (obj.type) {
				case 'current':
					var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)),
						left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2));
					break;

				case 'next':
					var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)),
						left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2));
					break;

				case 'prev':
					var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)),
						left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2));
					break;
			}

			holder.data('offset', {
				top: top,
				left: left,
				newDims: newDims,
				diff: {
					W: widthDiff,
					H: heightDiff
				},
				thumbsOffset: {
					W: thumbsOffsetW,
					H: thumbsOffsetH
				},
				object: obj
			});

			if (obj.animate > 0 && opts.effects.reposition) {
				holder.css(transform, gpuAcceleration).stop().animate({
					top: top,
					left: left
				}, opts.effects.repositionSpeed, 'easeOutCirc', function() {
					holder.css(transform, '');
				});
				$('div.ilightbox-container', holder).stop().animate({
					width: width,
					height: height
				}, opts.effects.repositionSpeed, 'easeOutCirc');
				$('div.ilightbox-inner-toolbar', holder).stop().animate({
					width: width
				}, opts.effects.repositionSpeed, 'easeOutCirc', function() {
					$(this).css('overflow', 'visible');
				});
			} else {
				holder.css({
					top: top,
					left: left
				});
				$('div.ilightbox-container', holder).css({
					width: width,
					height: height
				});
				$('div.ilightbox-inner-toolbar', holder).css({
					width: width
				});
			}
		},

		resume: function(priority) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options;

			if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) {
				return;
			}

			vars.isPaused = 0;

			if (vars.cycleID) {
				vars.cycleID = clearTimeout(vars.cycleID);
			}

			vars.cycleID = setTimeout(function() {
				if (vars.current == vars.total - 1) { iL.goTo(0); }
				else { iL.moveTo('next'); }
			}, opts.slideshow.pauseTime);
		},

		pause: function(priority) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options;

			if (priority < vars.isPaused) {
				return;
			}

			vars.isPaused = priority || 100;

			if (vars.cycleID) {
				vars.cycleID = clearTimeout(vars.cycleID);
			}
		},

		resetCycle: function() {
			var iL = this,
				vars = iL.vars,
				opts = iL.options;

			if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) {
				iL.resume();
			}
		},

		getNewDimenstions: function(width, height, width_old, height_old, thumb) {
			var iL = this;

			if (!width) { factor = height / height_old; }
			else if (!height) { factor = width / width_old; }
			else { factor = min(width / width_old, height / height_old); }

			if (!thumb) {
				if (factor > iL.options.maxScale) { factor = iL.options.maxScale; }
				else if (factor < iL.options.minScale) { factor = iL.options.minScale; }
			}

			var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width,
				final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height;

			return {
				width: final_width,
				height: final_height,
				ratio: factor
			};
		},

		setOption: function(options) {
			var iL = this;

			iL.options = $.extend(true, iL.options, options || {});
			iL.refresh();
		},

		availPlugins: function() {
			var iL = this,
				testEl = document.createElement("video");

			iL.plugins = {
				flash: false, // fix for issue #1750 by Avada
				quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false,
				html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')),
				html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')),
				html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')),
				html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, ''))
			};
		},

		addContent: function(element, obj) {
			var iL = this,
				el;

			switch (obj.type) {
				case 'video':
					var HTML5 = false,
						videoType = obj.videoType,
						html5video = obj.options.html5video;

					if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264) {
						obj.ext = 'mp4',
						obj.URL = html5video.h264 || obj.URL;
					} else if (html5video.webm && iL.plugins.html5WebM) {
						obj.ext = 'webm',
						obj.URL = html5video.webm || obj.URL;
					} else if (html5video.ogg && iL.plugins.html5Vorbis) {
						obj.ext = 'ogv',
						obj.URL = html5video.ogg || obj.URL;
					}

					if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) { HTML5 = true, videoType = "video/mp4"; }
					else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) { HTML5 = true, videoType = "video/webm"; }
					else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) { HTML5 = true, videoType = "video/ogg"; }
					else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) { HTML5 = true, videoType = "video/quicktime"; }

					if (HTML5) {
						el = $('<video />', {
							"width": "100%",
							"height": "100%",
							"preload": html5video.preload,
							"autoplay": html5video.autoplay,
							"poster": html5video.poster,
							"controls": html5video.controls
						}).append($('<source />', {
							"src": obj.URL,
							"type": videoType
						}));
					} else {
						if (!iL.plugins.quicktime) { el = $('<span />', {
							"class": "ilightbox-alert",
							html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime')
						});
						} else {

							el = $('<object />', {
								"type": "video/quicktime",
								"pluginspage": pluginspages.quicktime
							}).attr({
								"data": obj.URL,
								"width": "100%",
								"height": "100%"
							}).append($('<param />', {
								"name": "src",
								"value": obj.URL
							})).append($('<param />', {
								"name": "autoplay",
								"value": "false"
							})).append($('<param />', {
								"name": "loop",
								"value": "false"
							})).append($('<param />', {
								"name": "scale",
								"value": "tofit"
							}));

							if (browser.msie) { el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false'); }
						}
					}

					break;

				case 'flash':
					if (!iL.plugins.flash) { el = $('<span />', {
						"class": "ilightbox-alert",
						html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player')
					});
					} else {
						var flashvars = "",
							i = 0;

						if (obj.options.flashvars) { $.each(obj.options.flashvars, function(k, v) {
							if (i != 0) flashvars += "&";
							flashvars += k + "=" + encodeURIComponent(v);
							i++;
						});
						} else { flashvars = null; }

						el = $('<embed />').attr({
							"type": "application/x-shockwave-flash",
							"src": obj.URL,
							"width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%",
							"height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%",
							"quality": "high",
							"bgcolor": "#000000",
							"play": "true",
							"loop": "true",
							"menu": "true",
							"wmode": "transparent",
							"scale": "showall",
							"allowScriptAccess": "always",
							"allowFullScreen": "true",
							"flashvars": flashvars,
							"fullscreen": "yes"
						});
					}

					break;

				case 'iframe':
					// ThemeFusion edit for Avada theme: added possibility to add autoplay and rel as part of query string for videos
					var $query_array = obj.URL.substring( obj.URL.indexOf( '?' ) + 1 ).split( '&' ),
						$query_object = {},
						$query_string = '?';

					for ( var $i = 0; $i < $query_array.length; ++$i ) {
						var $single_query = $query_array[$i].split( '=' );
						if ( $single_query.length != 2 ) continue;

						$query_object[$single_query[0]] = decodeURIComponent( $single_query[1].replace( /\+/g, " " ) );
					}

					$query_string += ( $query_object['autoplay'] !== undefined ) ? '&autoplay=' + $query_object['autoplay'] : '';
					$query_string += ( $query_object['rel'] !== undefined ) ? '&rel=' + $query_object['rel'] : '';

					// ThemeFusion edit for Avada theme: short url support for videos
					if ( obj.URL.indexOf( 'vimeo.com' ) != -1 ) {
						// For vimeo videos, also support urls like http://vimeo.com/8245346
						var $reg_exp = /http(s?):\/\/(www\.)?vimeo.com\/(\d+)/;
						var $match = obj.URL.match( $reg_exp );

						if ( $match ) {
							var $movie = '//player.vimeo.com/video/'+ $match[3] +'?title=0&amp;byline=0&amp;portrait=0' + $query_string;
						} else {
							var $movie = obj.URL;
						}
					} else {
						// For youtube videos, also support urls like http://youtu.be/hsEUBLIJvmE
						var $reg_exp =  /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
						var $match = obj.URL.match( $reg_exp );

						if ( $match ) {
							var $movie = '//www.youtube.com/embed/' + $match[7] + $query_string;
						} else {
							var $movie = obj.URL;
						}
					}


					// End Edit

					el = $('<iframe />').attr({
						"width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%",
						"height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%",
						src: $movie,
						frameborder: 0,
						'hspace': 0,
						'vspace': 0,
						'scrolling': supportTouch ? 'auto' : 'scroll',
						'webkitAllowFullScreen': '',
						'mozallowfullscreen': '',
						'allowFullScreen': ''
					});

					break;

				case 'inline':
					el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true));

					break;

				case 'html':
					var object = obj.URL,
						el;

					if (object[0].nodeName) {
						el = $('<div class="ilightbox-wrapper"></div>').html(object);
					} else {
						var dom = $(obj.URL),
							html = (dom.selector) ? $('<div>' + dom + '</div>') : dom;
						el = $('<div class="ilightbox-wrapper"></div>').html(html);
					}

					break;
			}

			$('div.ilightbox-container', element).empty().html(el);

			// For fixing Chrome about just playing the video for first time
			if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) { setTimeout(function() {
				var src = el[0].currentSrc + '?' + floor(random() * 30000);
				el[0].currentSrc = src;
				el[0].src = src;
			});
			}

			return el;
		},

		ogpRecognition: function(obj, callback) {
			var iL = this,
				url = obj.URL;

			iL.showLoader();
			doAjax(url, function(data) {
				iL.hideLoader();

				if (data) {
					var object = new Object();

					object.length = false,
					object.url = data.url;

					if (data.status == 200) {
						var result = data.results,
							type = result.type,
							source = result.source;

						object.type = type,
						object.html5video = result.html5video || {},
						object.length = true;

						if( result.images ) {
							object.thumbnail = result.images[0];
						}

						if( source ) {

							object.source = source.src,
							object.width = source.width && parseInt(source.width) || 0,
							object.height = source.height && parseInt(source.height) || 0,
							object.thumbnail = source.thumbnail;

							if (source.type == 'application/x-shockwave-flash') { object.type = "flash"; }
							else if (source.type.indexOf("video/") != -1) { object.type = "video"; }
							else if (source.type.indexOf("/html") != -1) { object.type = "iframe"; }
							else if (source.type.indexOf("image/") != -1) { object.type = "image"; }
						}

					} else if (typeof data.response != 'undefined') {
						throw data.response;
					}

					callback.call(this, object.length ? object : false);
				}
			});
		},

		hashChangeHandler: function(url) {
			var iL = this,
				vars = iL.vars,
				opts = iL.options,
				URL = url || window.location.href,
				hash = parseURI(URL).hash,
				split = hash.split('/'),
				index = split[1];

			if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) { return; }

			if (index) {
				var target = split[1] || 0;
				if (iL.items[target]) {
					var overlay = $('.ilightbox-overlay');
					if (overlay.length && overlay.attr('linkid') == opts.linkId) {
						iL.goTo(target);
					} else {
						iL.itemsObject[target].trigger(supportTouch ? 'itap' : 'click');
					}
				} else {
					var overlay = $('.ilightbox-overlay');
					if (overlay.length) { iL.closeAction(); }
				}
			} else {
				var overlay = $('.ilightbox-overlay');
				if (overlay.length) { iL.closeAction(); }
			}
		}
	};

	/**
	 * Parse style to pixels.
	 *
	 * @param {Object}   $element   jQuery object with element.
	 * @param {Property} property   CSS property to get the pixels from.
	 *
	 * @return {Int}
	 */
	function getPixel($element, property) {
		return parseInt($element.css(property), 10) || 0;
	}

	/**
	 * Make sure that number is within the limits.
	 *
	 * @param {Number} number
	 * @param {Number} min
	 * @param {Number} max
	 *
	 * @return {Number}
	 */
	function within(number, min, max) {
		return number < min ? min : number > max ? max : number;
	}

	/**
	 * Get viewport/window size (width and height).
	 *
	 * @return {Object}
	 */
	function getViewport() {
		var e = window,
			a = 'inner';
		if (!('innerWidth' in window)) {
			a = 'client';
			e = document.documentElement || document.body;
		}
		return {
			width: e[a + 'Width'],
			height: e[a + 'Height']
		}
	}

	/**
	 * Remove hash tag from the URL
	 *
	 * @return {Void}
	 */
	function removeHash() {

		// ThemeFusion edit for Avada theme: the original removeHash approach makes old IE versions shake. So we just use a HTML5 browser feature for removal and leave old IEs unaltered
		if ( history && history.pushState ) {
			history.pushState('', document.title, window.location.pathname + window.location.search);
		}

		/*
		var scroll = getScrollXY();

		window.location.hash = "";

		// Restore the scroll offset, should be flicker free
		window.scrollTo(scroll.x, scroll.y);
		*/
	}

	/**
	 * Do the ajax requests with callback.
	 *
	 * @param {String}   url
	 * @param {Function} callback
	 *
	 * @return {Void}
	 */
	function doAjax(url, callback) {
		var url = "http://ilightbox.net/getSource/jsonp.php?url=" + encodeURIComponent(url).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A');
		$.ajax({
			url: url,
			dataType: 'jsonp'
		});

		iLCallback = function(data) {
			callback.call(this, data);
		};
	}

	/**
	 * Find image from DOM elements
	 *
	 * @param {Element} element
	 *
	 * @return {Void}
	 */
	function findImageInElement(element) {
		var elements = $('*', element),
			imagesArr = new Array();

		elements.each(function() {
			var url = "",
				element = this;

			if ($(element).css("background-image") != "none") {
				url = $(element).css("background-image");
			} else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") {
				url = $(element).attr("src");
			}

			if (url.indexOf("gradient") == -1) {
				url = url.replace(/url\(\"/g, "");
				url = url.replace(/url\(/g, "");
				url = url.replace(/\"\)/g, "");
				url = url.replace(/\)/g, "");

				var urls = url.split(",");

				for (var i = 0; i < urls.length; i++) {
					if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) {
						var extra = "";
						if (browser.msie && browser.version < 9) {
							extra = "?" + floor(random() * 3000);
						}
						imagesArr.push(urls[i] + extra);
					}
				}
			}
		});

		return imagesArr;
	}

	/**
	 * Get file extension.
	 *
	 * @param {String} URL
	 *
	 * @return {String}
	 */
	function getExtension(URL) {
		var ext = ( URL ) ? URL.split('.').pop().toLowerCase() : '',
			extra = ext.indexOf('?') !== -1 ? '?' + ext.split('?').pop() : ''; // ThemeFusion edit for Avada theme: added the ? sign in front of the extra string to ensure it works correctly

		return ext.replace(extra, '');
	}

	/**
	 * Get type via extension.
	 *
	 * @param {String} URL
	 *
	 * @return {String}
	 */
	function getTypeByExtension(URL) {
		var type,
			ext = getExtension(URL);

		if (extensions.image.indexOf(ext) !== -1) { type = 'image'; }
		else if (extensions.flash.indexOf(ext) !== -1) { type = 'flash'; }
		else if (extensions.video.indexOf(ext) !== -1) { type = 'video'; }
		else { type = 'iframe'; }

		return type;
	}

	/**
	 * Return value from percent of a number.
	 *
	 * @param {Number} percent
	 * @param {Number} total
	 *
	 * @return {Number}
	 */
	function percentToValue(percent, total) {
		return parseInt((total / 100) * percent);
	}

	/**
	 * A JavaScript equivalent of PHP’s parse_url.
	 *
	 * @param {String} url           The URL to parse.
	 *
	 * @return {Mixed}
	 */
	function parseURI(url) {
		var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
		// authority = '//' + user + ':' + pass '@' + hostname + ':' port
		return (m ? {
			href: m[0] || '',
			protocol: m[1] || '',
			authority: m[2] || '',
			host: m[3] || '',
			hostname: m[4] || '',
			port: m[5] || '',
			pathname: m[6] || '',
			search: m[7] || '',
			hash: m[8] || ''
		} : null);
	}

	/**
	 * Gets the absolute URI.
	 *
	 * @param {String} href     The relative URL.
	 * @param {String} base     The base URL.
	 *
	 * @return {String}         The absolute URL.
	 */
	function absolutizeURI(base, href) { // RFC 3986
		var iL = this;

		function removeDotSegments(input) {
			var output = [];
			input.replace(/^(\.\.?(\/|$))+/, '')
				.replace(/\/(\.(\/|$))+/g, '/')
				.replace(/\/\.\.$/, '/../')
				.replace(/\/?[^\/]*/g, function(p) {
					if (p === '/..') {
						output.pop();
					} else {
						output.push(p);
					}
				});
			return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
		}

		href = parseURI(href || '');
		base = parseURI(base || '');

		return !href || !base ? null : (href.protocol || base.protocol) +
			(href.protocol || href.authority ? href.authority : base.authority) +
			removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
			(href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
			href.hash;
	}

	/**
	 * A JavaScript equivalent of PHP’s version_compare.
	 *
	 * @param {String} v1
	 * @param {String} v2
	 * @param {String} operator
	 *
	 * @return {Boolean}
	 */
	function version_compare(v1, v2, operator) {
		this.php_js = this.php_js || {};
		this.php_js.ENV = this.php_js.ENV || {};
		var i = 0,
			x = 0,
			compare = 0,
			vm = {
				'dev': -6,
				'alpha': -5,
				'a': -5,
				'beta': -4,
				'b': -4,
				'RC': -3,
				'rc': -3,
				'#': -2,
				'p': 1,
				'pl': 1
			},
			prepVersion = function(v) {
				v = ('' + v).replace(/[_\-+]/g, '.');
				v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.');
				return (!v.length ? [-8] : v.split('.'));
			},
			numVersion = function(v) {
				return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
			};
		v1 = prepVersion(v1);
		v2 = prepVersion(v2);
		x = max(v1.length, v2.length);
		for (i = 0; i < x; i++) {
			if (v1[i] == v2[i]) {
				continue;
			}
			v1[i] = numVersion(v1[i]);
			v2[i] = numVersion(v2[i]);
			if (v1[i] < v2[i]) {
				compare = -1;
				break;
			} else if (v1[i] > v2[i]) {
				compare = 1;
				break;
			}
		}
		if (!operator) {
			return compare;
		}

		switch (operator) {
			case '>':
			case 'gt':
				return (compare > 0);
			case '>=':
			case 'ge':
				return (compare >= 0);
			case '<=':
			case 'le':
				return (compare <= 0);
			case '==':
			case '=':
			case 'eq':
				return (compare === 0);
			case '<>':
			case '!=':
			case 'ne':
				return (compare !== 0);
			case '':
			case '<':
			case 'lt':
				return (compare < 0);
			default:
				return null;
		}
	}


	// Begin the iLightBox plugin
	$.fn.iLightBox = function() {

		var args = arguments,
			opt = ($.isPlainObject(args[0])) ? args[0] : args[1],
			items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1];

		if (!opt) { opt = {}; }

		// Default options. Play carefully.
		var options = $.extend(true, {
			attr: 'href',
			path: 'vertical',
			skin: 'dark',
			linkId: false,
			infinite: false,
			startFrom: 0,
			randomStart: false,
			keepAspectRatio: true,
			maxScale: 1,
			minScale: .2,
			innerToolbar: false,
			smartRecognition: false,
			mobileOptimizer: true,
			fullAlone: true,
			fullViewPort: null,
			fullStretchTypes: 'flash, video',
			overlay: {
				blur: true,
				opacity: .85
			},
			controls: {
				arrows: false,
				slideshow: false,
				toolbar: true,
				fullscreen: true,
				thumbnail: true,
				keyboard: true,
				mousewheel: true,
				swipe: true
			},
			keyboard: {
				left: true, // previous
				right: true, // next
				up: true, // previous
				down: true, // next
				esc: true, // close
				shift_enter: true // fullscreen
			},
			show: {
				effect: true,
				speed: 300,
				title: true
			},
			hide: {
				effect: true,
				speed: 300
			},
			caption: {
				start: true,
				show: 'mouseenter',
				hide: 'mouseleave'
			},
			social: {
				start: true,
				show: 'mouseenter',
				hide: 'mouseleave',
				buttons: false
			},
			styles: {
				pageOffsetX: 0,
				pageOffsetY: 0,
				nextOffsetX: 45,
				nextOffsetY: 0,
				nextOpacity: 1,
				nextScale: 1,
				prevOffsetX: 45,
				prevOffsetY: 0,
				prevOpacity: 1,
				prevScale: 1
			},
			thumbnails: {
				maxWidth: 120,
				maxHeight: 80,
				normalOpacity: 1,
				activeOpacity: .6
			},
			effects: {
				reposition: true,
				repositionSpeed: 200,
				switchSpeed: 500,
				loadedFadeSpeed: 180,
				fadeSpeed: 200
			},
			slideshow: {
				pauseTime: 5000,
				pauseOnHover: false,
				startPaused: true
			},
			text: {
				close: "Press Esc to close",
				enterFullscreen: "Enter Fullscreen (Shift+Enter)",
				exitFullscreen: "Exit Fullscreen (Shift+Enter)",
				slideShow: "Slideshow",
				next: "Next",
				previous: "Previous"
			},
			errors: {
				loadImage: "An error occurred when trying to load photo.",
				loadContents: "An error occurred when trying to load contents.",
				missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>."
			},
			ajaxSetup: {
				url: '',
				beforeSend: function(jqXHR, settings) {},
				cache: false,
				complete: function(jqXHR, textStatus) {},
				crossDomain: false,
				error: function(jqXHR, textStatus, errorThrown) {},
				success: function(data, textStatus, jqXHR) {},
				global: true,
				ifModified: false,
				username: null,
				password: null,
				type: 'GET'
			},
			callback: {}
		}, opt);

		var instant = ($.isArray(items) || typeof items == 'string') ? true : false;

		items = $.isArray(items) ? items : new Array();

		if (typeof args[0] == 'string') { items[0] = args[0]; }

		if (version_compare($.fn.jquery, '1.8', '>=')) {
			var iLB = new iLightBox($(this), options, items, instant);
			return {
				close: function() {
					iLB.closeAction();
				},
				fullscreen: function() {
					iLB.fullScreenAction();
				},
				moveNext: function() {
					iLB.moveTo('next');
				},
				movePrev: function() {
					iLB.moveTo('prev');
				},
				goTo: function(index) {
					iLB.goTo(index);
				},
				refresh: function() {
					iLB.refresh();
				},
				reposition: function() {
					(arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto();
				},
				setOption: function(options) {
					iLB.setOption(options);
				},
				destroy: function() {
					iLB.closeAction();
					iLB.dispatchItemsEvents();
				}
			};
		} else {
			throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+";
		}

	};


	$.iLightBox = function() {
		return $.fn.iLightBox(arguments[0], arguments[1]);
	};


	$.extend($.easing, {
		easeInCirc: function(x, t, b, c, d) {
			return -c * (sqrt(1 - (t /= d) * t) - 1) + b;
		},
		easeOutCirc: function(x, t, b, c, d) {
			return c * sqrt(1 - (t = t / d - 1) * t) + b;
		},
		easeInOutCirc: function(x, t, b, c, d) {
			if ((t /= d / 2) < 1) { return -c / 2 * (sqrt(1 - t * t) - 1) + b; }
			return c / 2 * (sqrt(1 - (t -= 2) * t) + 1) + b;
		}
	});

	function getScrollXY() {
		var scrOfX = 0,
			scrOfY = 0;
		if (typeof(window.pageYOffset) == 'number') {
			//Netscape compliant
			scrOfY = window.pageYOffset;
			scrOfX = window.pageXOffset;
		} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
			//DOM compliant
			scrOfY = document.body.scrollTop;
			scrOfX = document.body.scrollLeft;
		} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
			//IE6 standards compliant mode
			scrOfY = document.documentElement.scrollTop;
			scrOfX = document.documentElement.scrollLeft;
		}
		return {
			x: scrOfX,
			y: scrOfY
		};
	}

	(function() {
		// add new event shortcuts
		$.each(("touchstart touchmove touchend " +
			"tap taphold " +
			"swipeleft swiperight " + // ThemeFusion edit for Avada theme: delete "swipe" keyword
			"scrollstart scrollstop").split(" "), function(i, name) {

			$.fn[name] = function(fn) {
				return fn ? this.bind(name, fn) : this.trigger(name);
			};

			// jQuery < 1.8
			if ($.attrFn) {
				$.attrFn[name] = true;
			}
		});

		var tapSettings = {
			startEvent: 'touchstart.iTap',
			endEvent: 'touchend.iTap'
		};

		// tap Event:
		$.event.special.itap = {
			setup: function() {

				var self = this,
					$self = $(this),
					start, stop;

				$self.bind(tapSettings.startEvent, function(event) {
					start = getScrollXY();

					$self.one(tapSettings.endEvent, function(event) {
						stop = getScrollXY();

						var orgEvent = event || window.event;
						event = $.event.fix(orgEvent);
						event.type = "itap";

						if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event);

						start = stop = undefined;
					});
				});
			},

			teardown: function() {
				$(this).unbind(tapSettings.startEvent);
			}
		};
	}());


	//Fullscreen API
	(function() {
		fullScreenApi = {
				supportsFullScreen: false,
				isFullScreen: function() {
					return false;
				},
				requestFullScreen: function() {},
				cancelFullScreen: function() {},
				fullScreenEventName: '',
				prefix: ''
			},
			browserPrefixes = 'webkit moz o ms khtml'.split(' ');

		// check for native support
		if (typeof document.cancelFullScreen != 'undefined') {
			fullScreenApi.supportsFullScreen = true;
		} else {
			// check for fullscreen support by vendor prefix
			for (var i = 0, il = browserPrefixes.length; i < il; i++) {
				fullScreenApi.prefix = browserPrefixes[i];

				if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') {
					fullScreenApi.supportsFullScreen = true;

					break;
				}
			}
		}

		// update methods to do something useful
		if (fullScreenApi.supportsFullScreen) {
			fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';

			fullScreenApi.isFullScreen = function() {
				switch (this.prefix) {
					case '':
						return document.fullScreen;
					case 'webkit':
						return document.webkitIsFullScreen;
					default:
						return document[this.prefix + 'FullScreen'];
				}
			};

			fullScreenApi.requestFullScreen = function(el) {
				return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
			};
			fullScreenApi.cancelFullScreen = function(el) {
				return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
			};
		}
	}());

	// Browser detect
	(function() {
		function uaMatch(ua) {
			ua = ua.toLowerCase();

			var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
				/(webkit)[ \/]([\w.]+)/.exec(ua) ||
				/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
				/(msie) ([\w.]+)/.exec(ua) ||
				ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];

			return {
				browser: match[1] || "",
				version: match[2] || "0"
			};
		}

		var matched = uaMatch(navigator.userAgent);
		browser = {};

		if (matched.browser) {
			browser[matched.browser] = true;
			browser.version = matched.version;
		}

		// Chrome is Webkit, but Webkit is also Safari.
		if (browser.chrome) {
			browser.webkit = true;
		} else if (browser.webkit) {
			browser.safari = true;
		}
	}());

	// Feature detects
	(function() {
		var prefixes = ['', 'webkit', 'moz', 'ms', 'o'];
		var el = document.createElement('div');

		function testProp(prop) {
			for (var p = 0, pl = prefixes.length; p < pl; p++) {
				var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop;
				if (el.style[prefixedProp] !== undefined) {
					return prefixedProp;
				}
			}
		}

		// Global support indicators
		transform = testProp('transform') || '';
		gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : '';
	}());


	/*
		PluginDetect v0.7.9
		www.pinlady.net/PluginDetect/license/
		[ getVersion onWindowLoaded BetterIE ]
		[ Flash QuickTime Shockwave ]
	*/
	var PluginDetect={version:"0.7.9",name:"PluginDetect",handler:function(c,b,a){return function(){c(b,a)}},openTag:"<",isDefined:function(b){return typeof b!="undefined"},isArray:function(b){return(/array/i).test(Object.prototype.toString.call(b))},isFunc:function(b){return typeof b=="function"},isString:function(b){return typeof b=="string"},isNum:function(b){return typeof b=="number"},isStrNum:function(b){return(typeof b=="string"&&(/\d/).test(b))},getNumRegx:/[\d][\d\.\_,-]*/,splitNumRegx:/[\.\_,-]/g,getNum:function(b,c){var d=this,a=d.isStrNum(b)?(d.isDefined(c)?new RegExp(c):d.getNumRegx).exec(b):null;return a?a[0]:null},compareNums:function(h,f,d){var e=this,c,b,a,g=parseInt;if(e.isStrNum(h)&&e.isStrNum(f)){if(e.isDefined(d)&&d.compareNums){return d.compareNums(h,f)}c=h.split(e.splitNumRegx);b=f.split(e.splitNumRegx);for(a=0;a<min(c.length,b.length);a++){if(g(c[a],10)>g(b[a],10)){return 1}if(g(c[a],10)<g(b[a],10)){return -1}}}return 0},formatNum:function(b,c){var d=this,a,e;if(!d.isStrNum(b)){return null}if(!d.isNum(c)){c=4}c--;e=b.replace(/\s/g,"").split(d.splitNumRegx).concat(["0","0","0","0"]);for(a=0;a<4;a++){if(/^(0+)(.+)$/.test(e[a])){e[a]=RegExp.$2}if(a>c||!(/\d/).test(e[a])){e[a]="0"}}return e.slice(0,4).join(",")},$$hasMimeType:function(a){return function(c){if(!a.isIE&&c){var f,e,b,d=a.isArray(c)?c:(a.isString(c)?[c]:[]);for(b=0;b<d.length;b++){if(a.isString(d[b])&&/[^\s]/.test(d[b])){f=navigator.mimeTypes[d[b]];e=f?f.enabledPlugin:0;if(e&&(e.name||e.description)){return f}}}}return null}},findNavPlugin:function(l,e,c){var j=this,h=new RegExp(l,"i"),d=(!j.isDefined(e)||e)?/\d/:0,k=c?new RegExp(c,"i"):0,a=navigator.plugins,g="",f,b,m;for(f=0;f<a.length;f++){m=a[f].description||g;b=a[f].name||g;if((h.test(m)&&(!d||d.test(RegExp.leftContext+RegExp.rightContext)))||(h.test(b)&&(!d||d.test(RegExp.leftContext+RegExp.rightContext)))){if(!k||!(k.test(m)||k.test(b))){return a[f]}}}return null},getMimeEnabledPlugin:function(k,m,c){var e=this,f,b=new RegExp(m,"i"),h="",g=c?new RegExp(c,"i"):0,a,l,d,j=e.isString(k)?[k]:k;for(d=0;d<j.length;d++){if((f=e.hasMimeType(j[d]))&&(f=f.enabledPlugin)){l=f.description||h;a=f.name||h;if(b.test(l)||b.test(a)){if(!g||!(g.test(l)||g.test(a))){return f}}}}return 0},getPluginFileVersion:function(f,b){var h=this,e,d,g,a,c=-1;if(h.OS>2||!f||!f.version||!(e=h.getNum(f.version))){return b}if(!b){return e}e=h.formatNum(e);b=h.formatNum(b);d=b.split(h.splitNumRegx);g=e.split(h.splitNumRegx);for(a=0;a<d.length;a++){if(c>-1&&a>c&&d[a]!="0"){return b}if(g[a]!=d[a]){if(c==-1){c=a}if(d[a]!="0"){return b}}}return e},AXO:window.ActiveXObject,getAXO:function(a){var f=null,d,b=this,c={};try{f=new b.AXO(a)}catch(d){}return f},convertFuncs:function(f){var a,g,d,b=/^[\$][\$]/,c=this;for(a in f){if(b.test(a)){try{g=a.slice(2);if(g.length>0&&!f[g]){f[g]=f[a](f);delete f[a]}}catch(d){}}}},initObj:function(e,b,d){var a,c;if(e){if(e[b[0]]==1||d){for(a=0;a<b.length;a=a+2){e[b[a]]=b[a+1]}}for(a in e){c=e[a];if(c&&c[b[0]]==1){this.initObj(c,b)}}}},initScript:function(){var d=this,a=navigator,h,i=document,l=a.userAgent||"",j=a.vendor||"",b=a.platform||"",k=a.product||"";d.initObj(d,["$",d]);for(h in d.Plugins){if(d.Plugins[h]){d.initObj(d.Plugins[h],["$",d,"$$",d.Plugins[h]],1)}}d.convertFuncs(d);d.OS=100;if(b){var g=["Win",1,"Mac",2,"Linux",3,"FreeBSD",4,"iPhone",21.1,"iPod",21.2,"iPad",21.3,"Win.*CE",22.1,"Win.*Mobile",22.2,"Pocket\\s*PC",22.3,"",100];for(h=g.length-2;h>=0;h=h-2){if(g[h]&&new RegExp(g[h],"i").test(b)){d.OS=g[h+1];break}}};d.head=i.getElementsByTagName("head")[0]||i.getElementsByTagName("body")[0]||i.body||null;d.isIE=new Function("return/*@cc_on!@*/!1")();d.verIE=d.isIE&&(/MSIE\s*(\d+\.?\d*)/i).test(l)?parseFloat(RegExp.$1,10):null;d.verIEfull=null;d.docModeIE=null;if(d.isIE){var f,n,c=document.createElement("div");try{c.style.behavior="url(#default#clientcaps)";d.verIEfull=(c.getComponentVersion("{89820200-ECBD-11CF-8B85-00AA005B4383}","componentid")).replace(/,/g,".")}catch(f){}n=parseFloat(d.verIEfull||"0",10);d.docModeIE=i.documentMode||((/back/i).test(i.compatMode||"")?5:n)||d.verIE;d.verIE=n||d.docModeIE};d.ActiveXEnabled=false;if(d.isIE){var h,m=["Msxml2.XMLHTTP","Msxml2.DOMDocument","Microsoft.XMLDOM","ShockwaveFlash.ShockwaveFlash","TDCCtl.TDCCtl","Shell.UIHelper","Scripting.Dictionary","wmplayer.ocx"];for(h=0;h<m.length;h++){if(d.getAXO(m[h])){d.ActiveXEnabled=true;break}}};d.isGecko=(/Gecko/i).test(k)&&(/Gecko\s*\/\s*\d/i).test(l);d.verGecko=d.isGecko?d.formatNum((/rv\s*\:\s*([\.\,\d]+)/i).test(l)?RegExp.$1:"0.9"):null;d.isChrome=(/Chrome\s*\/\s*(\d[\d\.]*)/i).test(l);d.verChrome=d.isChrome?d.formatNum(RegExp.$1):null;d.isSafari=((/Apple/i).test(j)||(!j&&!d.isChrome))&&(/Safari\s*\/\s*(\d[\d\.]*)/i).test(l);d.verSafari=d.isSafari&&(/Version\s*\/\s*(\d[\d\.]*)/i).test(l)?d.formatNum(RegExp.$1):null;d.isOpera=(/Opera\s*[\/]?\s*(\d+\.?\d*)/i).test(l);d.verOpera=d.isOpera&&((/Version\s*\/\s*(\d+\.?\d*)/i).test(l)||1)?parseFloat(RegExp.$1,10):null;d.addWinEvent("load",d.handler(d.runWLfuncs,d))},init:function(d){var c=this,b,d,a={status:-3,plugin:0};if(!c.isString(d)){return a}if(d.length==1){c.getVersionDelimiter=d;return a}d=d.toLowerCase().replace(/\s/g,"");b=c.Plugins[d];if(!b||!b.getVersion){return a}a.plugin=b;if(!c.isDefined(b.installed)){b.installed=null;b.version=null;b.version0=null;b.getVersionDone=null;b.pluginName=d}c.garbage=false;if(c.isIE&&!c.ActiveXEnabled&&d!=="java"){a.status=-2;return a}a.status=1;return a},fPush:function(b,a){var c=this;if(c.isArray(a)&&(c.isFunc(b)||(c.isArray(b)&&b.length>0&&c.isFunc(b[0])))){a.push(b)}},callArray:function(b){var c=this,a;if(c.isArray(b)){for(a=0;a<b.length;a++){if(b[a]===null){return}c.call(b[a]);b[a]=null}}},call:function(c){var b=this,a=b.isArray(c)?c.length:-1;if(a>0&&b.isFunc(c[0])){c[0](b,a>1?c[1]:0,a>2?c[2]:0,a>3?c[3]:0)}else{if(b.isFunc(c)){c(b)}}},getVersionDelimiter:",",$$getVersion:function(a){return function(g,d,c){var e=a.init(g),f,b,h={};if(e.status<0){return null};f=e.plugin;if(f.getVersionDone!=1){f.getVersion(null,d,c);if(f.getVersionDone===null){f.getVersionDone=1}}a.cleanup();b=(f.version||f.version0);b=b?b.replace(a.splitNumRegx,a.getVersionDelimiter):b;return b}},cleanup:function(){var a=this;if(a.garbage&&a.isDefined(window.CollectGarbage)){window.CollectGarbage()}},isActiveXObject:function(d,b){var f=this,a=false,g,c='<object width="1" height="1" style="display:none" '+d.getCodeBaseVersion(b)+">"+d.HTML+f.openTag+"/object>";if(!f.head){return a}f.head.insertBefore(document.createElement("object"),f.head.firstChild);f.head.firstChild.outerHTML=c;try{f.head.firstChild.classid=d.classID}catch(g){}try{if(f.head.firstChild.object){a=true}}catch(g){}try{if(a&&f.head.firstChild.readyState<4){f.garbage=true}}catch(g){}f.head.removeChild(f.head.firstChild);return a},codebaseSearch:function(f,b){var c=this;if(!c.ActiveXEnabled||!f){return null}if(f.BIfuncs&&f.BIfuncs.length&&f.BIfuncs[f.BIfuncs.length-1]!==null){c.callArray(f.BIfuncs)}var d,o=f.SEARCH,k={};if(c.isStrNum(b)){if(o.match&&o.min&&c.compareNums(b,o.min)<=0){return true}if(o.match&&o.max&&c.compareNums(b,o.max)>=0){return false}d=c.isActiveXObject(f,b);if(d&&(!o.min||c.compareNums(b,o.min)>0)){o.min=b}if(!d&&(!o.max||c.compareNums(b,o.max)<0)){o.max=b}return d};var e=[0,0,0,0],l=[].concat(o.digits),a=o.min?1:0,j,i,h,g,m,n=function(p,r){var q=[].concat(e);q[p]=r;return c.isActiveXObject(f,q.join(","))};if(o.max){g=o.max.split(c.splitNumRegx);for(j=0;j<g.length;j++){g[j]=parseInt(g[j],10)}if(g[0]<l[0]){l[0]=g[0]}}if(o.min){m=o.min.split(c.splitNumRegx);for(j=0;j<m.length;j++){m[j]=parseInt(m[j],10)}if(m[0]>e[0]){e[0]=m[0]}}if(m&&g){for(j=1;j<m.length;j++){if(m[j-1]!=g[j-1]){break}if(g[j]<l[j]){l[j]=g[j]}if(m[j]>e[j]){e[j]=m[j]}}}if(o.max){for(j=1;j<l.length;j++){if(g[j]>0&&l[j]==0&&l[j-1]<o.digits[j-1]){l[j-1]+=1;break}}};for(j=0;j<l.length;j++){h={};for(i=0;i<20;i++){if(l[j]-e[j]<1){break}d=round((l[j]+e[j])/2);if(h["a"+d]){break}h["a"+d]=1;if(n(j,d)){e[j]=d;a=1}else{l[j]=d}}l[j]=e[j];if(!a&&n(j,e[j])){a=1};if(!a){break}};return a?e.join(","):null},addWinEvent:function(d,c){var e=this,a=window,b;if(e.isFunc(c)){if(a.addEventListener){a.addEventListener(d,c,false)}else{if(a.attachEvent){a.attachEvent("on"+d,c)}else{b=a["on"+d];a["on"+d]=e.winHandler(c,b)}}}},winHandler:function(d,c){return function(){d();if(typeof c=="function"){c()}}},WLfuncs0:[],WLfuncs:[],runWLfuncs:function(a){var b={};a.winLoaded=true;a.callArray(a.WLfuncs0);a.callArray(a.WLfuncs);if(a.onDoneEmptyDiv){a.onDoneEmptyDiv()}},winLoaded:false,$$onWindowLoaded:function(a){return function(b){if(a.winLoaded){a.call(b)}else{a.fPush(b,a.WLfuncs)}}},div:null,divID:"plugindetect",divWidth:50,pluginSize:1,emptyDiv:function(){var d=this,b,h,c,a,f,g;if(d.div&&d.div.childNodes){for(b=d.div.childNodes.length-1;b>=0;b--){c=d.div.childNodes[b];if(c&&c.childNodes){for(h=c.childNodes.length-1;h>=0;h--){g=c.childNodes[h];try{c.removeChild(g)}catch(f){}}}if(c){try{d.div.removeChild(c)}catch(f){}}}}if(!d.div){a=document.getElementById(d.divID);if(a){d.div=a}}if(d.div&&d.div.parentNode){try{d.div.parentNode.removeChild(d.div)}catch(f){}d.div=null}},DONEfuncs:[],onDoneEmptyDiv:function(){var c=this,a,b;if(!c.winLoaded){return}if(c.WLfuncs&&c.WLfuncs.length&&c.WLfuncs[c.WLfuncs.length-1]!==null){return}for(a in c){b=c[a];if(b&&b.funcs){if(b.OTF==3){return}if(b.funcs.length&&b.funcs[b.funcs.length-1]!==null){return}}}for(a=0;a<c.DONEfuncs.length;a++){c.callArray(c.DONEfuncs)}c.emptyDiv()},getWidth:function(c){if(c){var a=c.scrollWidth||c.offsetWidth,b=this;if(b.isNum(a)){return a}}return -1},getTagStatus:function(m,g,a,b){var c=this,f,k=m.span,l=c.getWidth(k),h=a.span,j=c.getWidth(h),d=g.span,i=c.getWidth(d);if(!k||!h||!d||!c.getDOMobj(m)){return -2}if(j<i||l<0||j<0||i<0||i<=c.pluginSize||c.pluginSize<1){return 0}if(l>=i){return -1}try{if(l==c.pluginSize&&(!c.isIE||c.getDOMobj(m).readyState==4)){if(!m.winLoaded&&c.winLoaded){return 1}if(m.winLoaded&&c.isNum(b)){if(!c.isNum(m.count)){m.count=b}if(b-m.count>=10){return 1}}}}catch(f){}return 0},getDOMobj:function(g,a){var f,d=this,c=g?g.span:0,b=c&&c.firstChild?1:0;try{if(b&&a){d.div.focus()}}catch(f){}return b?c.firstChild:null},setStyle:function(b,g){var f=b.style,a,d,c=this;if(f&&g){for(a=0;a<g.length;a=a+2){try{f[g[a]]=g[a+1]}catch(d){}}}},insertDivInBody:function(i,g){var f,c=this,h="pd33993399",b=null,d=g?window.top.document:window.document,a=d.getElementsByTagName("body")[0]||d.body;if(!a){try{d.write('<div id="'+h+'">.'+c.openTag+"/div>");b=d.getElementById(h)}catch(f){}}a=d.getElementsByTagName("body")[0]||d.body;if(a){a.insertBefore(i,a.firstChild);if(b){a.removeChild(b)}}},insertHTML:function(f,b,g,a,k){var l,m=document,j=this,p,o=m.createElement("span"),n,i;var c=["outlineStyle","none","borderStyle","none","padding","0px","margin","0px","visibility","visible"];var h="outline-style:none;border-style:none;padding:0px;margin:0px;visibility:visible;";if(!j.isDefined(a)){a=""}if(j.isString(f)&&(/[^\s]/).test(f)){f=f.toLowerCase().replace(/\s/g,"");p=j.openTag+f+' width="'+j.pluginSize+'" height="'+j.pluginSize+'" ';p+='style="'+h+'display:inline;" ';for(n=0;n<b.length;n=n+2){if(/[^\s]/.test(b[n+1])){p+=b[n]+'="'+b[n+1]+'" '}}p+=">";for(n=0;n<g.length;n=n+2){if(/[^\s]/.test(g[n+1])){p+=j.openTag+'param name="'+g[n]+'" value="'+g[n+1]+'" />'}}p+=a+j.openTag+"/"+f+">"}else{p=a}if(!j.div){i=m.getElementById(j.divID);if(i){j.div=i}else{j.div=m.createElement("div");j.div.id=j.divID}j.setStyle(j.div,c.concat(["width",j.divWidth+"px","height",(j.pluginSize+3)+"px","fontSize",(j.pluginSize+3)+"px","lineHeight",(j.pluginSize+3)+"px","verticalAlign","baseline","display","block"]));if(!i){j.setStyle(j.div,["position","absolute","right","0px","top","0px"]);j.insertDivInBody(j.div)}}if(j.div&&j.div.parentNode){j.setStyle(o,c.concat(["fontSize",(j.pluginSize+3)+"px","lineHeight",(j.pluginSize+3)+"px","verticalAlign","baseline","display","inline"]));try{o.innerHTML=p}catch(l){};try{j.div.appendChild(o)}catch(l){};return{span:o,winLoaded:j.winLoaded,tagName:f,outerHTML:p}}return{span:null,winLoaded:j.winLoaded,tagName:"",outerHTML:p}},Plugins:{quicktime:{mimeType:["video/quicktime","application/x-quicktimeplayer","image/x-macpaint","image/x-quicktime"],progID:"QuickTimeCheckObject.QuickTimeCheck.1",progID0:"QuickTime.QuickTime",classID:"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B",minIEver:7,HTML:'<param name="src" value="" /><param name="controller" value="false" />',getCodeBaseVersion:function(a){return'codebase="#version='+a+'"'},SEARCH:{min:0,max:0,match:0,digits:[16,128,128,0]},getVersion:function(c){var f=this,d=f.$,a=null,e=null,b;if(!d.isIE){if(d.hasMimeType(f.mimeType)){e=d.OS!=3?d.findNavPlugin("QuickTime.*Plug-?in",0):null;if(e&&e.name){a=d.getNum(e.name)}}}else{if(d.isStrNum(c)){b=c.split(d.splitNumRegx);if(b.length>3&&parseInt(b[3],10)>0){b[3]="9999"}c=b.join(",")}if(d.isStrNum(c)&&d.verIE>=f.minIEver&&f.canUseIsMin()>0){f.installed=f.isMin(c);f.getVersionDone=0;return}f.getVersionDone=1;if(!a&&d.verIE>=f.minIEver){a=f.CDBASE2VER(d.codebaseSearch(f))}if(!a){e=d.getAXO(f.progID);if(e&&e.QuickTimeVersion){a=e.QuickTimeVersion.toString(16);a=parseInt(a.charAt(0),16)+"."+parseInt(a.charAt(1),16)+"."+parseInt(a.charAt(2),16)}}}f.installed=a?1:(e?0:-1);f.version=d.formatNum(a,3)},cdbaseUpper:["7,60,0,0","0,0,0,0"],cdbaseLower:["7,50,0,0",null],cdbase2ver:[function(c,b){var a=b.split(c.$.splitNumRegx);return[a[0],a[1].charAt(0),a[1].charAt(1),a[2]].join(",")},null],CDBASE2VER:function(f){var e=this,c=e.$,b,a=e.cdbaseUpper,d=e.cdbaseLower;if(f){f=c.formatNum(f);for(b=0;b<a.length;b++){if(a[b]&&c.compareNums(f,a[b])<0&&d[b]&&c.compareNums(f,d[b])>=0&&e.cdbase2ver[b]){return e.cdbase2ver[b](e,f)}}}return f},canUseIsMin:function(){var f=this,d=f.$,b,c=f.canUseIsMin,a=f.cdbaseUpper,e=f.cdbaseLower;if(!c.value){c.value=-1;for(b=0;b<a.length;b++){if(a[b]&&d.codebaseSearch(f,a[b])){c.value=1;break}if(e[b]&&d.codebaseSearch(f,e[b])){c.value=-1;break}}}f.SEARCH.match=c.value==1?1:0;return c.value},isMin:function(c){var b=this,a=b.$;return a.codebaseSearch(b,c)?0.7:-1}},flash:{mimeType:"application/x-shockwave-flash",progID:"ShockwaveFlash.ShockwaveFlash",classID:"clsid:D27CDB6E-AE6D-11CF-96B8-444553540000",getVersion:function(){var b=function(i){if(!i){return null}var e=/[\d][\d\,\.\s]*[rRdD]{0,1}[\d\,]*/.exec(i);return e?e[0].replace(/[rRdD\.]/g,",").replace(/\s/g,""):null};var j=this,g=j.$,k,h,l=null,c=null,a=null,f,m,d;if(!g.isIE){m=g.hasMimeType(j.mimeType);if(m){f=g.getDOMobj(g.insertHTML("object",["type",j.mimeType],[],"",j));try{l=g.getNum(f.GetVariable("$version"))}catch(k){}}if(!l){d=m?m.enabledPlugin:null;if(d&&d.description){l=b(d.description)}if(l){l=g.getPluginFileVersion(d,l)}}}else{for(h=15;h>2;h--){c=g.getAXO(j.progID+"."+h);if(c){a=h.toString();break}}if(!c){c=g.getAXO(j.progID)}if(a=="6"){try{c.AllowScriptAccess="always"}catch(k){return"6,0,21,0"}}try{l=b(c.GetVariable("$version"))}catch(k){}if(!l&&a){l=a}}j.installed=l?1:-1;j.version=g.formatNum(l);return true}},shockwave:{mimeType:"application/x-director",progID:"SWCtl.SWCtl",classID:"clsid:166B1BCA-3F9C-11CF-8075-444553540000",getVersion:function(){var a=null,b=null,g,f,d=this,c=d.$;if(!c.isIE){f=c.findNavPlugin("Shockwave\\s*for\\s*Director");if(f&&f.description&&c.hasMimeType(d.mimeType)){a=c.getNum(f.description)}if(a){a=c.getPluginFileVersion(f,a)}}else{try{b=c.getAXO(d.progID).ShockwaveVersion("")}catch(g){}if(c.isString(b)&&b.length>0){a=c.getNum(b)}else{if(c.getAXO(d.progID+".8")){a="8"}else{if(c.getAXO(d.progID+".7")){a="7"}else{if(c.getAXO(d.progID+".1")){a="6"}}}}}d.installed=a?1:-1;d.version=c.formatNum(a)}},zz:0}};PluginDetect.initScript();

	var gArgCountErr='The "%%" function requires an even number of arguments.\nArguments should be in the form "atttributeName", "attributeValue", ...',gTagAttrs=null,gQTGeneratorVersion=1;function AC_QuickTimeVersion(){return gQTGeneratorVersion}function _QTComplain(a,b){b=b.replace("%%",a);alert(b)}function _QTAddAttribute(a,b,c){var d;d=gTagAttrs[a+b];null==d&&(d=gTagAttrs[b]);return null!=d?(0==b.indexOf(a)&&null==c&&(c=b.substring(a.length)),null==c&&(c=b),c+'="'+d+'" '):""}function _QTAddObjectAttr(a,b){if(0==a.indexOf("emb#"))return"";0==a.indexOf("obj#")&&null==b&&(b=a.substring(4));return _QTAddAttribute("obj#",a,b)}function _QTAddEmbedAttr(a,b){if(0==a.indexOf("obj#"))return"";0==a.indexOf("emb#")&&null==b&&(b=a.substring(4));return _QTAddAttribute("emb#",a,b)}function _QTAddObjectParam(a,b){var c,d="",e=b?" />":">";-1==a.indexOf("emb#")&&(c=gTagAttrs["obj#"+a],null==c&&(c=gTagAttrs[a]),0==a.indexOf("obj#")&&(a=a.substring(4)),null!=c&&(d='  <param name="'+a+'" value="'+c+'"'+e+"\n"));return d}function _QTDeleteTagAttrs(){for(var a=0;a<arguments.length;a++){var b=arguments[a];delete gTagAttrs[b];delete gTagAttrs["emb#"+b];delete gTagAttrs["obj#"+b]}}function _QTGenerate(a,b,c){if(4>c.length||0!=c.length%2)return _QTComplain(a,gArgCountErr),"";gTagAttrs=[];gTagAttrs.src=c[0];gTagAttrs.width=c[1];gTagAttrs.height=c[2];gTagAttrs.classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B";gTagAttrs.pluginspage="http://www.apple.com/quicktime/download/";a=c[3];if(null==a||""==a)a="6,0,2,0";gTagAttrs.codebase="http://www.apple.com/qtactivex/qtplugin.cab#version="+a;for(var d,e=4;e<c.length;e+=2)d=c[e].toLowerCase(),a=c[e+1],"name"==d||"id"==d?gTagAttrs.name=a:gTagAttrs[d]=a;c="<object "+_QTAddObjectAttr("classid")+_QTAddObjectAttr("width")+_QTAddObjectAttr("height")+_QTAddObjectAttr("codebase")+_QTAddObjectAttr("name","id")+_QTAddObjectAttr("tabindex")+_QTAddObjectAttr("hspace")+_QTAddObjectAttr("vspace")+_QTAddObjectAttr("border")+_QTAddObjectAttr("align")+_QTAddObjectAttr("class")+_QTAddObjectAttr("title")+_QTAddObjectAttr("accesskey")+_QTAddObjectAttr("noexternaldata")+">\n"+_QTAddObjectParam("src",b);e="  <embed "+_QTAddEmbedAttr("src")+_QTAddEmbedAttr("width")+_QTAddEmbedAttr("height")+_QTAddEmbedAttr("pluginspage")+_QTAddEmbedAttr("name")+_QTAddEmbedAttr("align")+_QTAddEmbedAttr("tabindex");_QTDeleteTagAttrs("src","width","height","pluginspage","classid","codebase","name","tabindex","hspace","vspace","border","align","noexternaldata","class","title","accesskey");for(d in gTagAttrs)a=gTagAttrs[d],null!=a&&(e+=_QTAddEmbedAttr(d),c+=_QTAddObjectParam(d,b));return c+e+"> </embed>\n</object>"}function QT_GenerateOBJECTText(){return _QTGenerate("QT_GenerateOBJECTText",!1,arguments)};


	/*
		jQuery hashchange event v1.3
		https://github.com/cowboy/jquery-hashchange
		Copyright (c) 2010 "Cowboy" Ben Alman
		Dual licensed under the MIT and GPL licenses.
	*/
	(function(){function e(a){a=a||location.href;return"#"+a.replace(/^[^#]*#?(.*)$/,"$1")}var k=document,b,f=$.event.special,p=k.documentMode,m="oniLightBoxHashChange"in window&&(void 0===p||7<p);$.fn.iLightBoxHashChange=function(a){return a?this.bind("iLightBoxHashChange",a):this.trigger("iLightBoxHashChange")};$.fn.iLightBoxHashChange.delay=50;f.iLightBoxHashChange=$.extend(f.iLightBoxHashChange,{setup:function(){if(m)return!1;$(b.start)},teardown:function(){if(m)return!1;$(b.stop)}});b=function(){function a(){var c=
	e(),d=f(l);c!==l?(n(l=c,d),$(window).trigger("iLightBoxHashChange")):d!==l&&(location.href=location.href.replace(/#.*/,"")+d);g=setTimeout(a,$.fn.iLightBoxHashChange.delay)}var h={},g,l=e(),b=function(c){return c},n=b,f=b;h.start=function(){g||a()};h.stop=function(){g&&clearTimeout(g);g=void 0};browser.msie&&!m&&function(){var c,d;h.start=function(){c||(d=(d=$.fn.iLightBoxHashChange.src)&&d+e(),c=$('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){d||n(e());a()}).attr("src",d||
	"javascript:0").insertAfter("body")[0].contentWindow,k.onpropertychange=function(){try{"title"===event.propertyName&&(c.document.title=k.title)}catch(a){}})};h.stop=b;f=function(){return e(c.location.href)};n=function(a,d){var b=c.document,e=$.fn.iLightBoxHashChange.domain;a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})();

	if (!Array.prototype.filter) {
		Array.prototype.filter = function(fun /*, thisp */ ) {
			"use strict";

			if (this == null)
				throw new TypeError();

			var t = Object(this);
			var len = t.length >>> 0;
			if (typeof fun != "function")
				throw new TypeError();

			var res = [];
			var thisp = arguments[1];
			for (var i = 0; i < len; i++) {
				if (i in t) {
					var val = t[i]; // in case fun mutates this
					if (fun.call(thisp, val, i, t))
						res.push(val);
				}
			}

			return res;
		};
	}

	if (!Array.prototype.indexOf) {
		Array.prototype.indexOf = function(searchElement, fromIndex) {
			var k;

			if (this == null) {
				throw new TypeError('"this" is null or not defined');
			}

			var O = Object(this);

			var len = O.length >>> 0;

			if (len === 0) {
				return -1;
			}

			var n = +fromIndex || 0;

			if (abs(n) === Infinity) {
				n = 0;
			}

			if (n >= len) {
				return -1;
			}

			k = max(n >= 0 ? n : len - abs(n), 0);

			while (k < len) {
				var kValue;
				if (k in O && O[k] === searchElement) {
					return k;
				}
				k++;
			}
			return -1;
		};
	}

	if (!Array.prototype.lastIndexOf) {
		Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) {
			"use strict";

			if (this == null)
				throw new TypeError();

			var t = Object(this);
			var len = t.length >>> 0;
			if (len === 0)
				return -1;

			var n = len;
			if (arguments.length > 1) {
				n = Number(arguments[1]);
				if (n != n)
					n = 0;
				else if (n != 0 && n != (1 / 0) && n != -(1 / 0))
					n = (n > 0 || -1) * floor(abs(n));
			}

			var k = n >= 0 ? min(n, len - 1) : len - abs(n);

			for (; k >= 0; k--) {
				if (k in t && t[k] === searchElement)
					return k;
			}
			return -1;
		};
	}
})(jQuery, this);
;/*******************************************
 Avada Lightbox
 *
 * @package		Avada
 * @author		ThemeFusion
 * @link		http://theme-fusion.com
 * @copyright	ThemeFusion
********************************************/

"use strict";

var $avada_lightbox = {};
var $il_instances	= [];
/**
* [initialize_lightbox manipulate pretty photo content]
*/
$avada_lightbox.initialize_lightbox = function() {

	if( Number( js_local_vars.status_lightbox ) == 1 ) {

		// For old prettyPhoto instances initialize caption and titles
		$avada_lightbox.set_title_and_caption();

		//activate lightbox now
		$avada_lightbox.activate_lightbox();
	};
};
/**
* [activate_lightbox activate lightbox]
*/
$avada_lightbox.activate_lightbox = function( $wrapper ) {

	// Default value for optional $gallery variable
	if ( typeof $wrapper === 'undefined' ) {
    	$wrapper = jQuery( 'body' );
  	}

	//create galleries group
	var $groups_arr = [];

	$wrapper.find( '[data-rel^="prettyPhoto["], [rel^="prettyPhoto["], [data-rel^="iLightbox["], [rel^="iLightbox["]' ).each( function () {
		var $image_formats = ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'svg', 'mp4', 'ogg', 'webm' ],
			$image_formats_mask = 0,
			$href = jQuery( this ).attr( 'href' );

		// Fix for #1738
		if( typeof $href == 'undefined' ) {
			$href = '';
		}

		// Loop through the image extensions array to see if we have an image link
		for ( var $i = 0; $i < $image_formats.length; $i++ ) {
			$image_formats_mask += String( $href ).toLowerCase().indexOf( '.' + $image_formats[$i] );
		}

		// Check for Vimeo URL
		var $reg_exp = /http(s?):\/\/(www\.)?vimeo.com\/(\d+)/;
		var $match = $href.match( $reg_exp );
		if ( $match ) {
			$image_formats_mask = 1;
		}

		// Check for Youtube URL
		$reg_exp =  /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
		$match = $href.match( $reg_exp );
		if ( $match ) {
			$image_formats_mask = 1;
		}

		// If no image extension was found add the no lightbox class
		if ( $image_formats_mask == -13 ) {
			jQuery( this ).addClass( 'fusion-no-lightbox' )
		}

		if ( ! jQuery( this ).hasClass( 'fusion-no-lightbox' ) ) {
			var $data_rel = this.getAttribute("data-rel");
			if( $data_rel != null ) {
				jQuery.inArray( $data_rel, $groups_arr ) === -1 && $groups_arr.push( $data_rel );
			}

			var $rel = this.getAttribute("data-rel");
			if( $rel != null ) {

				// For WP galleries make sure each has its own lightbox gallery
				if ( jQuery ( this ).parents( '.gallery' ).length ) {
					$rel = $rel.replace( 'postimages', jQuery ( this ).parents( '.gallery' ).attr( 'id' ) );
					jQuery( this ).attr( 'data-rel', $rel );
				}

				jQuery.inArray( $rel, $groups_arr ) === -1 && $groups_arr.push( $rel );
			}
		}
	});

	// Special setup for jetpack tiled gallery
	var $tiled_gallery_counter = 1;
	$wrapper.find( '.tiled-gallery' ).each( function() {
		jQuery( this ).find( '.tiled-gallery-item > a' ).each( function() {
			var $data_rel = this.getAttribute( 'data-rel' );
			if ( $data_rel == null ) {
				$data_rel = 'iLightbox[tiled-gallery-' + $tiled_gallery_counter + ']';
				jQuery( this ).attr( 'data-rel', $data_rel );
			}

			jQuery.inArray( $data_rel, $groups_arr ) === -1 && $groups_arr.push( $data_rel );
		});

		$tiled_gallery_counter++;
	});


	// Activate lightbox for galleries
	jQuery.each( $groups_arr, function ( $i, $group_name ) {
		// For groups with only one single image, disable the slideshow play button
		if ( jQuery( '[data-rel="' + $group_name + '"], [rel="' + $group_name + '"]' ).length == 1 ) {
			$il_instances.push( jQuery( '[data-rel="' + $group_name + '"], [rel="' + $group_name + '"]' ).iLightBox( $avada_lightbox.prepare_options( $group_name, false ) ) );
		} else {
			$il_instances.push( jQuery( '[data-rel="' + $group_name + '"], [rel="' + $group_name + '"]' ).iLightBox( $avada_lightbox.prepare_options( $group_name ) ) );
		}
	});

	// Activate lightbox for single instances
	$wrapper.find( "a[rel='prettyPhoto'], a[data-rel='prettyPhoto'], a[rel='iLightbox'], a[data-rel='iLightbox']" ).each( function() {
		$il_instances.push( jQuery( this ).iLightBox( $avada_lightbox.prepare_options( 'single' ) ) );
	});

	// Activate lightbox for single lightbox links
	$wrapper.find( '#lightbox-link, .lightbox-link, .fusion-lightbox-link' ).each( function() {
		$il_instances.push( jQuery( this ).iLightBox( $avada_lightbox.prepare_options( 'single' ) ) );
	});

	//activate lightbox for images within the post content
	if( Boolean( Number( js_local_vars.lightbox_post_images ) ) ) {
		$wrapper.find( '.type-post .post-content a, #posts-container .post .post-content a, .fusion-blog-shortcode .post .post-content a' ).has( 'img' ).each(
			function() {
				// Make sure the lightbox is only used for image links and not for links to external pages
				var $image_formats = ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'svg', 'mp4', 'ogg', 'webm' ],
					$image_formats_mask = 0;

				// Loop through the image extensions array to see if we have an image link
				for ( var $i = 0; $i < $image_formats.length; $i++ ) {
					$image_formats_mask += String( jQuery( this ).attr( 'href' ) ).toLowerCase().indexOf( '.' + $image_formats[$i] );
				}

				// If no image extension was found add the no lightbox class
				if ( $image_formats_mask == -13 ) {
					jQuery( this ).addClass( 'fusion-no-lightbox' )
				}

				if( String( jQuery( this ).attr( 'rel' ) ).indexOf( 'prettyPhoto' ) === -1 && String( jQuery( this ).attr( 'data-rel' ) ).indexOf( 'prettyPhoto' ) === -1 && String( jQuery( this ).attr( 'rel' ) ).indexOf( 'iLightbox' ) === -1 && String( jQuery( this ).attr( 'data-rel' ) ).indexOf( 'iLightbox' ) === -1 && ! jQuery( this ).hasClass( 'fusion-no-lightbox' ) ) {
					jQuery( this ).attr( 'data-caption', jQuery( this ).parent().find('p.wp-caption-text').text() );
					$il_instances.push( jQuery( this ).iLightBox( $avada_lightbox.prepare_options( 'post' ) ) );
				}
			}
		);
	}
};

/**
* [set_title_and_caption For old prettyPhoto instances initialize caption and titles]
*/
$avada_lightbox.set_title_and_caption = function(){
	jQuery( "a[rel^='prettyPhoto'], a[data-rel^='prettyPhoto']" ).each(function( index ) {
		if ( ! jQuery( this ).attr( 'data-caption' ) ) {

			if ( ! jQuery( this ).attr( 'title' ) ) {
				jQuery( this ).attr( 'data-caption', jQuery( this ).parents( '.gallery-item' ).find( '.gallery-caption' ).text() );
			} else {
				jQuery( this ).attr( 'data-caption', jQuery( this ).attr( 'title' ) );
			}
		}

		if ( ! jQuery( this ).attr( 'data-title' ) ) {
			jQuery( this ).attr( 'data-title', jQuery( this ).find( 'img' ).attr( 'alt' ) );
		}
	});

	jQuery( "a[rel^='iLightbox'], a[data-rel^='iLightbox']" ).each(function( index ) {
		if ( ! jQuery( this ).attr( 'data-caption' ) ) {
			jQuery( this ).attr( 'data-caption', jQuery( this ).parents( '.gallery-item' ).find( '.gallery-caption' ).text() );
		}
	});
};

/**
* [prepare_options set data for page options]
*/
$avada_lightbox.prepare_options = function( $link_id, $gallery ){

	// Default value for optional $gallery variable
	if ( typeof $gallery === 'undefined' ) {
    	$gallery = Boolean( Number( js_local_vars.lightbox_gallery  ) );
  	}

	var $show_speed = {Fast:100, Slow:800, Normal:400};
	var $autoplay	= {1:false, 0:true};

	var $ilightbox_args = {
		skin: js_local_vars.lightbox_skin,
		smartRecognition: false,
		minScale: 0.075,
		show: {
			title: Boolean( Number( js_local_vars.lightbox_title ) ),
			speed: $show_speed[js_local_vars.lightbox_animation_speed],
		},
		path: js_local_vars.lightbox_path,
		controls: {
			slideshow: $gallery,
			arrows: Boolean( Number( js_local_vars.lightbox_arrows ) )
		},
		slideshow: {
			pauseTime: js_local_vars.lightbox_slideshow_speed,
			pauseOnHover: false,
			startPaused: $autoplay[Number( js_local_vars.lightbox_autoplay )]
		},
		overlay: {
			opacity: js_local_vars.lightbox_opacity
		},
		caption: {
			start: Boolean( Number( js_local_vars.lightbox_desc ) ),
			show: '',
			hide: ''
		},
		isMobile: true
	};

	//for social sharing
	if( Boolean( Number( js_local_vars.lightbox_social ) ) ) {

		$ilightbox_args.social = {
			buttons: {
				facebook: true,
				twitter: true,
				googleplus: true,
				reddit: true,
				digg: true,
				delicious: true
			}
		};
	}

	//for deep linking
	if( Boolean( Number( js_local_vars.lightbox_deeplinking ) ) ) {
		$ilightbox_args.linkId = $link_id;
	}

	return $ilightbox_args;
};
/**
* [refresh_instance A function to refresh all items and rebind all elements.]
*/
$avada_lightbox.refresh_lightbox = function( ) {

	$avada_lightbox.set_title_and_caption();

	jQuery.each( $il_instances, function( $key, $value ) {
		if( $value.hasOwnProperty( 'refresh' ) ) {
			$value.refresh();
		};
	});
};

// lightbox initialization for dynamically loaded content
jQuery( document ).ajaxComplete( function() {
	$avada_lightbox.refresh_lightbox();
});

jQuery(window).load(function() {
	//initialize lightbox
	$avada_lightbox.initialize_lightbox();
});
;jQuery(window).load(function() {
    // Avada dropdown styles
    if ( Number( js_local_vars.avada_styles_dropdowns ) == 1 ) {

		jQuery( '.woocommerce-billing-fields, .woocommerce-shipping-fields' ).addClass( 'avada-select' );

        if ( jQuery( '.woocommerce.widget_product_categories select' ).length ) {
            jQuery( '.woocommerce.widget_product_categories select' ).wrap( '<p class="avada-select-parent"></p>' ).after( '<div class="select-arrow">&#xe61f;</div>' );
        }

        jQuery( '.cart-collaterals select#calc_shipping_country, .widget_layered_nav select' ).wrap( '<p class="avada-select-parent"></p>' ).after( '<div class="select-arrow">&#xe61f;</div>' );
        jQuery( '.cart-collaterals select#calc_shipping_state' ).after( '<div class="select-arrow">&#xe61f;</div>' );

        setTimeout(
            function() {
                // Billing address - Only add styling if woocommerce enhanced country selects are disabled
                if ( ! jQuery( '#billing_country_field .chosen-container' ).length && ! jQuery( '#billing_country_field .select2-container' ).length ) {
                    // Wrap the country select
                    jQuery( '#billing_country_field select.country_select' ).wrap( '<p class="avada-select-parent"></p>' ).after( '<span class="select-arrow">&#xe61f;</span>' );

                    // If there is a state select for the initially selected country, wrap it
                    if ( jQuery( '#billing_state_field select.state_select' ).length && ! jQuery( '#billing_state_field .chosen-container' ).length && ! jQuery( '#billing_state_field .select2-container' ).length ) {
                        jQuery( '#billing_state_field' ).addClass( 'avada-select-parent' ).append( '<div class="select-arrow">&#xe61f;</div>' );
                    }

                    // When the country is changed
                    jQuery( "#billing_country" ).change(
                        function() {
                            // Timeout is needed that woocommerce js can kick in first
                            setTimeout(
                                function() {
                                    // If the new country has no state field at all or if it is just an input, undo custom styles
                                    if ( jQuery( '#billing_state_field input#billing_state' ).length || jQuery( '#billing_state_field' ).is( ':hidden' ) ) {
                                        jQuery( '#billing_state_field .select-arrow' ).remove();
                                        jQuery( '#billing_state_field' ).removeClass( 'avada-select-parent' );
                                    }

                                    // If the new country has a state select
                                    if ( jQuery( '#billing_state_field select.state_select' ).length ) {
                                        // Add the correct wrapper class (always needed due to woocommerce classes reset)
                                        jQuery( '#billing_state_field' ).addClass( 'avada-select-parent' );

                                        // If the last country wasn't already having a state select, add the arrow container and calculate dimensions
                                        if ( !jQuery( '#billing_state_field .select-arrow' ).length ) {
                                            jQuery( '#billing_state_field' ).append( '<div class="select-arrow">&#xe61f;</div>' );

                                            calc_select_arrow_dimensions();
                                        }
                                    }
                                }, 1
                            );
                        }
                    );
                }

                // Shipping address - Only add styling if woocommerce enhanced country selects are disabled
                if ( !jQuery( '#shipping_country_field .chosen-container' ).length && !jQuery( '#shipping_country_field .select2-container' ).length ) {
                    jQuery( '#shipping_country_field select.country_select' ).wrap( '<p class="avada-select-parent"></p>' ).after( '<span class="select-arrow">&#xe61f;</span>' );

                    // If there is a state select for the initially selected country, wrap it
                    if ( jQuery( '#shipping_state_field select.state_select' ).length ) {
                        jQuery( '#shipping_state_field' ).addClass( 'avada-select-parent' ).append( '<div class="select-arrow">&#xe61f;</div>' );
                    }

                    jQuery( "#shipping_country" ).change(
                        function() {
                            // Timeout is needed that woocommerce js can kick in first
                            setTimeout(
                                function() {
                                    // If the new country has no state field at all or if it is just an input, undo custom styles
                                    if ( jQuery( '#shipping_state_field input#shipping_state' ).length || jQuery( '#shipping_state_field' ).is( ':hidden' ) ) {
                                        jQuery( '#shipping_state_field .select-arrow' ).remove();
                                        jQuery( '#shipping_state_field' ).removeClass( 'avada-select-parent' );
                                    }

                                    // If the new country has a state select
                                    if ( jQuery( '#shipping_state_field select.state_select' ).length ) {
                                        // Add the correct wrapper class (always needed due to woocommerce classes reset)
                                        jQuery( '#shipping_state_field' ).addClass( 'avada-select-parent' );

                                        // If the last country wasn't already having a state select, add the arrow container and calculate dimensions
                                        if ( !jQuery( '#shipping_state_field .select-arrow' ).length ) {
                                            jQuery( '#shipping_state_field' ).append( '<div class="select-arrow">&#xe61f;</div>' );

                                            calc_select_arrow_dimensions();
                                        }
                                    }
                                }, 1
                            );
                        }
                    );
                }
            }, 1
        );

		jQuery( '#calc_shipping_country' ).change(
			function() {
				// Timeout is needed that woocommerce js can kick in first
				setTimeout(
					function() {
						if ( jQuery( '.avada-shipping-calculator-form select#calc_shipping_state').length && ! jQuery( '.avada-shipping-calculator-form #calc_shipping_state' ).parent().find( '.select-arrow' ).length ) {
							jQuery( '.avada-shipping-calculator-form select#calc_shipping_state').after( '<div class="select-arrow">&#xe61f;</div>' );
						}

						if ( jQuery( '.avada-shipping-calculator-form input#calc_shipping_state' ).length ) {
							jQuery( '.avada-shipping-calculator-form #calc_shipping_state' ).parent().children( '.select-arrow' ).remove();
						}

						calc_select_arrow_dimensions();
					}, 1
				);
			}
		);

        // wrap variation forms select and add arrow
        jQuery( 'table.variations select, .variations-table select, .product-addon select' ).wrap( '<div class="avada-select-parent"></div>' );
        jQuery( '<div class="select-arrow">&#xe61f;</div>' ).appendTo( 'table.variations .avada-select-parent, .variations-table .avada-select-parent, .product-addon .avada-select-parent' );

        // wrap cf7 select and add arrow
        jQuery( '.wpcf7-select:not([multiple])' ).wrap( '<div class="wpcf7-select-parent"></div>' );
        jQuery( '<div class="select-arrow">&#xe61f;</div>' ).appendTo( '.wpcf7-select-parent' );

        // wrap gravity forms select and add arrow
		wrap_gravity_selects();

        // wrap woo and bbpress select and add arrow
        jQuery( '#bbp_stick_topic_select, #bbp_topic_status_select, #bbp_forum_id, #bbp_destination_topic, #wpfc_sermon_sorting select' ).wrap( '<div class="avada-select-parent"></div>' ).after( '<div class="select-arrow">&#xe61f;</div>' );

        jQuery( '.variations_form select' ).change(
            function() {
                if ( jQuery( '.product #slider' ).length ) {
                    jQuery( '.product #slider' ).flexslider( 0 );
                }
            }
        );

        // wrap category and archive widget dropdowns
        jQuery( '.widget_categories select, .widget_archive select ' ).css( 'width', '100%' );
        jQuery( '.widget_categories select, .widget_archive select ' ).wrap( '<div class="avada-select-parent"></div>' ).after( '<div class="select-arrow">&#xe61f;</div>' );
    }

    // set heights of select arrows correctly
   	calc_select_arrow_dimensions();

   	setTimeout( function() {
		calc_select_arrow_dimensions();
	}, 100 );
});

function wrap_gravity_selects() {
	jQuery( '.gform_wrapper select:not([multiple])' ).each(
		function() {
			var current_select = jQuery( this );

			setTimeout(
				function() {
					if ( !current_select.siblings( '.chosen-container' ).length ) {
						var select_width = current_select.css( 'width' );
						current_select.wrap( '<div class="gravity-select-parent"></div>' );
						current_select.parent().width( select_width );
						current_select.css( 'cssText', "width: 100% !important;" );
						jQuery( '<div class="select-arrow">&#xe61f;</div>' ).appendTo( current_select.parent( '.gravity-select-parent' ) );

						calc_select_arrow_dimensions();
					}
				}, 150
			);
		}
	);
}

// Wrap gravity forms select and add arrow
function calc_select_arrow_dimensions() {
	jQuery( '.avada-select-parent .select-arrow, .gravity-select-parent .select-arrow, .wpcf7-select-parent .select-arrow' ).filter( ':visible' ).each( function() {
		if( jQuery( this ).prev().innerHeight() > 0 ) {
			jQuery( this ).css( {
				height: jQuery( this ).prev().innerHeight(),
				width: jQuery( this ).prev().innerHeight(),
				'line-height': jQuery( this ).prev().innerHeight() + 'px'
			});
		}
	});
}

// Unwrap gravity selects that get a chzn field appended on the fly
jQuery(document).bind('gform_post_conditional_logic', function(){
	var select = jQuery('.gform_wrapper select');
	jQuery(select).each(function() {
		if(jQuery(this).hasClass('chzn-done') && jQuery(this).parent().hasClass('gravity-select-parent')) {
			jQuery(this).parent().find('.select-arrow').remove();
			jQuery(this).unwrap('<div class="gravity-select-parent"></div>');
		}
	});
});

// Setup a recursive function to handle gform multipart form selects
function recursive_gform_submission_handler() {
	if ( jQuery( '.gform_wrapper' ).find( 'form' ).attr( 'target' ) && jQuery( '.gform_wrapper' ).find( 'form' ).attr( 'target' ).indexOf( 'gform_ajax_frame' ) > -1 ) {
		jQuery( '.gform_wrapper' ).find( 'form' ).submit( function( event ) {
			setTimeout(
				function() {
					wrap_gravity_selects();
					calc_select_arrow_dimensions();
					recursive_gform_submission_handler();
				},
			800 );
		});
	}
}
recursive_gform_submission_handler();


;jQuery( document ).ready(
    function() {
        function nice_scroll_init() {
            jQuery( 'html' ).niceScroll(
                {
                    background: '#555',
                    scrollspeed: 60,
                    mousescrollstep: 40,
                    cursorwidth: 9,
                    cursorborder: '0px',
                    cursorcolor: '#303030',
                    cursorborderradius: 8,
                    preservenativescrolling: true,
                    cursoropacitymax: 1,
                    cursoropacitymin: 1,
                    autohidemode: false,
                    zindex: 999999,
                    horizrailenabled: false
                }
            );

            if( jQuery( 'html' ).getNiceScroll().length ) {
                jQuery( 'html' ).addClass( 'no-overflow-y' );
            } else {
                jQuery( 'html' ).removeClass( 'no-overflow-y' );   
            }
        }

        var $smooth_active = js_local_vars.smooth_scrolling,
        	$smooth_cache = ( $smooth_active == 1 ) ? true : false;

		setTimeout ( function() {
	        if ( $smooth_active == 1 && ! Modernizr.mq( 'screen and (max-width: ' + ( 800 + parseInt( js_local_vars.side_header_width ) ) +  'px)' ) && jQuery( 'body' ).outerHeight( true ) > jQuery( window ).height() && ! navigator.userAgent.match( /(Android|iPod|iPhone|iPad|IEMobile|Opera Mini)/ ) ) {
	            nice_scroll_init();
			} else {
                jQuery( 'html' ).removeClass( 'no-overflow-y' );   
            }
		}, 50 );


        jQuery( window ).resize( function() {
            var $smooth_active = js_local_vars.smooth_scrolling,
            	$smooth_cache = ( $smooth_active == 1 ) ? true : false;

            if ( $smooth_active == 1 && ! Modernizr.mq( 'screen and (max-width: ' + ( 800 + parseInt( js_local_vars.side_header_width ) ) +  'px)' ) && jQuery( 'body' ).outerHeight( true ) > jQuery( window ).height() && ! navigator.userAgent.match( /(Android|iPod|iPhone|iPad|IEMobile|Opera Mini)/ ) ) {
                nice_scroll_init();
            } else {
                jQuery( 'html' ).getNiceScroll().remove();
                jQuery( 'html' ).removeClass( 'no-overflow-y' );
                jQuery( 'html' ).css( 'overflow-y', 'auto' );
                jQuery( '#ascrail2000' ).css( 'opacity', '1' );
            }
        });
    }
);
;jQuery(window).load(function() {
    jQuery( '.bbp-template-notice' ).each(
        function() {
            if ( jQuery( this ).hasClass( 'info' ) ) {
                jQuery( this ).attr( 'class', 'fusion-alert alert notice alert-dismissable alert-info alert-shadow' );
            } else {
                jQuery( this ).attr(
                    'class', 'fusion-alert alert notice alert-dismissable alert-warning alert-shadow'
                );
            }
            jQuery( this ).children( 'tt' ).contents().unwrap();
            jQuery( this ).children( 'p' ).contents().unwrap();
            jQuery( this ).prepend( '<button class="close toggle-alert" aria-hidden="true" data-dismiss="alert" type="button">&times;</button><span class="alert-icon"><i class="fa fa-lg fa-lg fa-cog"></i></span>' );

            jQuery( this ).children( '.close' ).click(
                function( e ) {
                    e.preventDefault();

                    jQuery( this ).parent().slideUp();
                }
            );
        }
    );

    jQuery( '.bbp-login-form' ).each(
        function() {
            jQuery( this ).children( 'tt' ).contents().unwrap();
        }
    );
});;jQuery( document ).ready( function() {

	// Disable the navigation top and bottom lines, when there is no prev and next nav
	if( ! jQuery.trim( jQuery( '.tribe-events-nav-previous' ).html() ).length && ! jQuery.trim( jQuery( '.tribe-events-nav-next' ).html() ).length ) {
		jQuery( '.tribe-events-sub-nav' ).parent().hide();
	}

	jQuery( '.fusion-tribe-has-featured-image' ).each(function() {
		var height = jQuery(this).parent().height();
		jQuery(this).find('.tribe-events-event-image').css('height', height);
	});

	jQuery( window ).on( 'resize', function() {
		jQuery( '.fusion-tribe-has-featured-image' ).each(function() {
			jQuery(this).find('.tribe-events-event-image').css('height', 'auto');
			var height = jQuery(this).parent().height();
			jQuery(this).find('.tribe-events-event-image').css('height', height);
		});
	});
});

jQuery( window ).load(function() {
	// Equal Heights Elements
	jQuery( '.fusion-events-shortcode' ).each( function() {
		jQuery( this ).find('.fusion-events-meta' ).equalHeights();
	});

	jQuery( window ).on( 'resize', function() {
		jQuery( '.fusion-events-shortcode' ).each( function() {
			jQuery( this ).find( '.fusion-events-meta' ).equalHeights();
		});
	});
});

jQuery( document ).ajaxComplete( function( event, request, settings ) {
	jQuery( '.fusion-tribe-has-featured-image' ).each(function() {
		var height = jQuery(this).parent().height();
		jQuery(this).find('.tribe-events-event-image').css('height', height);
	});

	jQuery( this ).find( '.post' ).each(function() {
		jQuery( this ).find( '.fusion-post-slideshow' ).flexslider();
		jQuery( this ).find( '.full-video, .video-shortcode, .wooslider .slide-content' ).fitVids();
	});

	// Fade in new posts when all images are loaded, then relayout isotope
	var $posts_container = jQuery( '#tribe-events .fusion-blog-layout-grid' );
	var $posts = $posts_container.find( '.post' );
	$posts_container.css( 'height', $posts_container.height() );
	$posts.hide();
	imagesLoaded( $posts, function() {

		$posts_container.css( 'height', '' );
		$posts.fadeIn();

		// Relayout isotope
		$posts_container.isotope();
		jQuery( window ).trigger( 'resize' );

		// Refresh the scrollspy script for one page layouts
		jQuery( '[data-spy="scroll"]' ).each( function () {
			  var $spy = jQuery( this ).scrollspy( 'refresh' );
		});
	});

});
;/**
 * WooCommerce Quanity buttons add-back
 */
function avadaAddWoocommerceQuantityBoxes( $parent ) {
	var $quantityBoxes = jQuery( 'div.quantity:not(.buttons_added), td.quantity:not(.buttons_added)' ).find( '.qty' );

	if ( $quantityBoxes && $quantityBoxes.prop( 'type' ) != 'date' ) {

		// Add plus and minus boxes
		$quantityBoxes.parent().addClass( 'buttons_added' ).append( '<input type="button" value="+" class="plus" />' ).prepend( '<input type="button" value="-" class="minus" />' );

		// Target quantity inputs on product pages
		jQuery( 'input.qty:not(.product-quantity input.qty)' ).each( function() {
				var $min = parseFloat( jQuery( this ).attr( 'min' ) );

				if ( $min && $min > 0 && parseFloat( jQuery( this ).val() ) < $min ) {
					jQuery( this ).val( $min );
				}
		});

		jQuery( '.plus, .minus' ).unbind( 'click' );

		jQuery( '.plus, .minus' ).on( 'click', function() {

				// Get values
				var $quantityBox = jQuery( this ).parent().find( '.qty' ),
					$currentQuantity = parseFloat( $quantityBox.val() ),
					$maxQuantity = parseFloat( $quantityBox.attr( 'max' ) ),
					$minQuantity = parseFloat( $quantityBox.attr( 'min' ) ),
					$step = $quantityBox.attr( 'step' );

				// Fallback default values
				if ( ! $currentQuantity || '' === $currentQuantity  || 'NaN' === $currentQuantity ) {
					$currentQuantity = 0;
				}
				if ( '' === $maxQuantity || 'NaN' === $maxQuantity ) {
					$maxQuantity = '';
				}

				if ( '' === $minQuantity || 'NaN' === $minQuantity ) {
					$minQuantity = 0;
				}
				if ( 'any' === $step || '' === $step  || undefined === $step || 'NaN' === parseFloat( $step )  ) {
					$step = 1;
				}

				// Change the value
				if ( jQuery( this ).is( '.plus' ) ) {

					if ( $maxQuantity && ( $maxQuantity == $currentQuantity || $currentQuantity > $maxQuantity ) ) {
						$quantityBox.val( $maxQuantity );
					} else {
						$quantityBox.val( $currentQuantity + parseFloat( $step ) );
					}

				} else {

					if ( $minQuantity && ( $minQuantity == $currentQuantity || $currentQuantity < $minQuantity ) ) {
						$quantityBox.val( $minQuantity );
					} else if ( $currentQuantity > 0 ) {
						$quantityBox.val( $currentQuantity - parseFloat( $step ) );
					}

				}

				// Trigger change event
				$quantityBox.trigger( 'change' );
			}
		);
	}
}

function fusionResizeCrossfadeImages( $parent ) {
	var $parent_height = $parent.height();

	$parent.find( 'img' ).each(
		function() {
			$img_height = jQuery( this ).height();

			if ( $img_height < $parent_height ) {
				jQuery( this ).css( 'margin-top', ( ( $parent_height - $img_height ) / 2 )  + "px" );
			}
		}
	);
}

function fusion_resize_crossfade_images_container( $container ) {
	var $biggest_height = 0;

	$container.find( 'img' ).each(
		function() {
			$img_height = jQuery( this ).height();

			if ( $img_height > $biggest_height ) {
				$biggest_height = $img_height;
			}
		}
	);

	$container.css( 'height', $biggest_height );
}

function fusion_calc_woocommerce_tabs_layout( $tab_selector ) {
	jQuery( $tab_selector ).each( function() {
		var $menu_width = jQuery( this ).parent().width();
		var $menu_items = jQuery( this ).find( 'li' ).length;
		var $mod = $menu_width % $menu_items;
		var $item_width = ( $menu_width - $mod ) / $menu_items;
		var $last_item_width = $menu_width - $item_width * ( $menu_items - 1 );

		jQuery( this ).css( 'width', $menu_width + 'px' );
		jQuery( this ).find( 'li' ).css( 'width', $item_width + 'px' );
		jQuery( this ).find( 'li:last' ).css( 'width', $last_item_width + 'px' ).addClass( 'no-border-right' );
	});
};

// Resize crossfade images and square to be the largest image and also vertically centered
jQuery( window ).load( function() {
	jQuery( '.variations_form' ).find( '.variations .single_variation_wrap .woocommerce-variation-description' ).remove();

	jQuery( window ).resize(
		function() {
			jQuery( '.crossfade-images' ).each(
				function() {
					fusion_resize_crossfade_images_container( jQuery( this ) );
					fusionResizeCrossfadeImages( jQuery( this ) );
				}
			);
		}
	);

	jQuery( '.crossfade-images' ).each(
		function() {
			fusion_resize_crossfade_images_container( jQuery( this ) );
			fusionResizeCrossfadeImages( jQuery( this ) );
		}
	);

	// Make the onsale badge also work on products without image
	jQuery( '.product-images' ).each(
		function() {
			if ( ! jQuery( this ).find( 'img' ).length && jQuery( this ).find( '.onsale' ).length ) {
				jQuery( this ).css( 'min-height', '45px' );
			}
		}
	);

	jQuery( '.woocommerce .images #carousel a' ).click( function(e) {
		e.preventDefault();
	});

	// Make sure the variation image is also changed in the thumbs carousel and for lightbox
	jQuery( '.variations_form' ).on( 'change', '.variations select', function( event ) {
		var $variations_form = jQuery( this ).parents( '.variations_form' );

		// Timeout needed to get updated image src attribute
		setTimeout( function() {
			var $slider_first_image = jQuery( '.images' ).find( '#slider img:eq(0)' ),
				$slider_first_image_parent_link = $slider_first_image.parent(),
				$slider_first_image_src = $slider_first_image.attr( 'src' ),
				$thumbs_first_image = jQuery( '.images' ).find( '#carousel img:eq(0)' );

			if ( $slider_first_image_parent_link && $slider_first_image_parent_link.attr( 'href' ) ) {
				$slider_first_image_src = $slider_first_image_parent_link.attr( 'href' );
			}

			$slider_first_image.parent().attr( 'href', $slider_first_image_src );
			$slider_first_image.removeAttr( 'sizes' );
			$slider_first_image.removeAttr( 'srcset' );

			// Refresh the lightbox
			$avada_lightbox.refresh_lightbox();

			$thumbs_first_image.attr( 'src', $slider_first_image_src );
			$thumbs_first_image.removeAttr( 'sizes' );
			$thumbs_first_image.removeAttr( 'srcset' );

			var $slider = jQuery( '.images #slider' ).data( 'flexslider' );
			if ( $slider ) {
				$slider.resize();
			}

			var $slider = jQuery( '.images #carousel' ).data( 'flexslider' );
			if ( $slider ) {
				$slider.resize();
			}

			//$variations_form.find( '.variations .single_variation_wrap .woocommerce-variation-description' ).remove();

		}, 1 );

		setTimeout( function() {
			$avada_lightbox.refresh_lightbox();

			var $slider = jQuery( '.images #slider' ).data( 'flexslider' );
			if ( $slider ) {
				$slider.resize();
			}
		}, 500 );

		setTimeout( function() {
			$avada_lightbox.refresh_lightbox();
		}, 1500 );
	});
});

jQuery( document ).ready( function() {
	avadaAddWoocommerceQuantityBoxes();

	jQuery( '.fusion-update-cart' ).on( 'click', function(e) {
		e.preventDefault();
		jQuery( '.cart .actions > .button' ).trigger( 'click' );
	});

	jQuery( '.fusion-apply-coupon' ).on( 'click', function(e) {
		e.preventDefault();
		jQuery( '.cart .actions .coupon #coupon_code' ).val( jQuery( '#avada_coupon_code' ).val() );
		jQuery( '.cart .actions .coupon .button' ).trigger( 'click' );
	});

	jQuery( '.product-type-variable .variations_form > .single_variation_wrap .woocommerce-variation-price' ).remove();
	jQuery( '.product-type-variable .variations_form > .single_variation_wrap .woocommerce-variation-availability' ).remove();

	jQuery( 'body' ).on( 'click', '.add_to_cart_button', function(e) {
		var $add_to_cart_button = jQuery( this );

		$add_to_cart_button.closest( '.product, li' ).find( '.cart-loading' ).find( 'i' ).removeClass( 'fusion-icon-check-square-o' ).addClass( 'fusion-icon-spinner' );
		$add_to_cart_button.closest( '.product, li' ).find( '.cart-loading' ).fadeIn();
		setTimeout( function(){
			$add_to_cart_button.closest( '.product, li' ).find( '.cart-loading' ).find( 'i' ).hide().removeClass( 'fusion-icon-spinner' ).addClass( 'fusion-icon-check-square-o' ).fadeIn();
			jQuery( $add_to_cart_button ).parents( '.fusion-clean-product-image-wrapper, li' ).addClass( 'fusion-item-in-cart' );
		}, 2000 );
	});

	jQuery('li').mouseenter(function() {
		if(jQuery(this).find('.cart-loading').find('i').hasClass('fusion-icon-check-square-o')) {
			jQuery(this).find('.cart-loading').fadeIn();
		}
	}).mouseleave(function() {
		if(jQuery(this).find('.cart-loading').find('i').hasClass('fusion-icon-check-square-o')) {
			jQuery(this).find('.cart-loading').fadeOut();
		}
	});

	jQuery('.catalog-ordering .orderby .current-li a').html(jQuery('.catalog-ordering .orderby ul li.current a').html());
	jQuery('.catalog-ordering .sort-count .current-li a').html(jQuery('.catalog-ordering .sort-count ul li.current a').html());
	jQuery('.woocommerce .shop_table .variation dd').after('<br />');
	jQuery('.woocommerce .avada-myaccount-data th.order-actions').text(js_local_vars.order_actions);

	jQuery('body.rtl .avada-myaccount-data .my_account_orders .order-status').each( function() {
		jQuery( this ).css( 'text-align', 'right' );
	});

	jQuery('.woocommerce input').each(function() {
		if(!jQuery(this).has('#coupon_code')) {
			var name = jQuery(this).attr('id');
			jQuery(this).attr('placeholder', jQuery(this).parent().find('label[for='+name+']').text());
		}
	});

	if(jQuery('.woocommerce #reviews #comments .comment_container .comment-text').length ) {
		jQuery('.woocommerce #reviews #comments .comment_container').append('<div class="clear"></div>');
	}

	var $title_sep = js_local_vars.title_style_type.split( ' ' ),
		$title_sep_class_string = '',
		$title_main_sep_class_string = '',
		$headinging_orientation = 'title-heading-left';

	for ( var i = 0; i < $title_sep.length; i++ ) {
		$title_sep_class_string += ' sep-' + $title_sep[i];
	}

	if ( $title_sep_class_string.indexOf( 'underline' ) > -1 ) {
		$title_main_sep_class_string = $title_sep_class_string;
	}

	if ( jQuery( 'body' ).hasClass( 'rtl' ) ) {
		$headinging_orientation = 'title-heading-right';
	}

	jQuery('.woocommerce.single-product .related.products > h2' ).each( function() {
		var $related_heading = jQuery( this ).replaceWith( function () {
		    return '<div class="fusion-title title' + $title_sep_class_string + '"><h3 class="' + $headinging_orientation + '">' + jQuery( this ).html() + '</h3><div class="title-sep-container"><div class="title-sep' + $title_sep_class_string + ' "></div></div></div>';
		});
	});

	jQuery('.woocommerce.single-product .upsells.products > h2').each( function() {
		var $related_heading = jQuery( this ).replaceWith( function () {
		    return '<div class="fusion-title title' + $title_sep_class_string + '"><h3 class="' + $headinging_orientation + '">' + jQuery( this ).html() + '</h3><div class="title-sep-container"><div class="title-sep' + $title_sep_class_string + ' "></div></div></div>';
		});
	});

	jQuery('.woocommerce-tabs #comments > h2').each( function() {
		var $comments_heading = jQuery( this ).replaceWith( function () {
		    return '<h3>' + jQuery( this ).html() + '</h3>';
		});
	});


	if ( jQuery( 'body .sidebar' ).css( 'display' ) == 'block' ) {
		fusion_calc_woocommerce_tabs_layout( '.woocommerce-tabs .tabs-horizontal' );
	}

	jQuery('.sidebar .products,.fusion-footer-widget-area .products,#slidingbar-area .products').each(function() {
		jQuery(this).removeClass('products-4');
		jQuery(this).removeClass('products-3');
		jQuery(this).removeClass('products-2');
		jQuery(this).addClass('products-1');
	});

	jQuery('.products-6 li, .products-5 li, .products-4 li, .products-3 li, .products-3 li').removeClass('last');

	// Woocommerce nested products plugin support
	jQuery( '.subcategory-products' ).each( function() {
		jQuery( this ).addClass( 'products-' + js_local_vars.woocommerce_shop_page_columns );
	});

	jQuery('.woocommerce-tabs ul.tabs li a').unbind( 'click' );
	jQuery('body').on( 'click', '.woocommerce-tabs > ul.tabs li a', function(){

		var tab = jQuery( this );
		var tabs_wrapper = tab.closest( '.woocommerce-tabs' );

		jQuery( 'ul.tabs li', tabs_wrapper ).removeClass( 'active' );
		jQuery( '> div.panel', tabs_wrapper ).hide();
		jQuery( 'div' + tab.attr( 'href' ), tabs_wrapper ).show();
		tab.parent().addClass( 'active' );

		return false;
	});

	jQuery( '.woocommerce-checkout-nav a,.continue-checkout' ).on( 'click', function(e) {
		var $admin_bar_height = ( jQuery( '#wpadminbar' ).length ) ? jQuery( '#wpadminbar' ).height() : 0,
			$header_div_children = jQuery( '.fusion-header-wrapper').find( 'div' ),
			$sticky_header_height = 0;

		$header_div_children.each( function() {
			if ( jQuery( this ).css( 'position' ) == 'fixed' ) {
				$sticky_header_height = jQuery( this ).height();
			}
		});

		e.preventDefault();
		jQuery( '.avada-checkout-error' ).parent().remove();

		if ( ! jQuery( '.woocommerce .avada-checkout' ).find( '.woocommerce-invalid' ).is( ':visible' ) ) {
			var $data_name = jQuery( this ).attr( 'data-name' ),
				$name = $data_name;

			if ( $data_name == 'order_review' ) {
				$name = '#' + $data_name;
			} else {
				$name = '.' + $data_name;
			}

			jQuery( 'form.checkout .col-1, form.checkout .col-2, form.checkout #order_review_heading, form.checkout #order_review' ).hide();

			jQuery( 'form.checkout' ).find( $name ).fadeIn();
			if( $name == 'order_review' ) {
				jQuery( 'form.checkout' ).find( '#order_review_heading ').fadeIn();
			}

			jQuery( '.woocommerce-checkout-nav li' ).removeClass( 'is-active' );
			jQuery( '.woocommerce-checkout-nav' ).find( '[data-name=' + $data_name + ']' ).parent().addClass( 'is-active' );

			if ( jQuery( this ).hasClass( 'continue-checkout' ) && jQuery( window ).scrollTop() > 0 ) {
				if ( jQuery( '.woo-tabs-horizontal' ).length ) {
					var $scrollAnchor = jQuery( '.woocommerce-checkout-nav' );
				} else {
					var $scrollAnchor = jQuery( '.woocommerce-content-box.avada-checkout' );
				}

				jQuery( 'html, body' ).animate( {scrollTop: $scrollAnchor.offset().top - $admin_bar_height - $sticky_header_height }, 500 );
			}
		} else {
			jQuery( '.woocommerce .avada-checkout .woocommerce-checkout' ).prepend( '<ul class="woocommerce-error"><li class="avada-checkout-error">' + js_local_vars.woocommerce_checkout_error + '</li><ul>' );

			jQuery( 'html, body' ).animate( {scrollTop: jQuery( '.woocommerce-error' ).offset().top - $admin_bar_height - $sticky_header_height }, 500 );
		}

		// set heights of select arrows correctly
		calc_select_arrow_dimensions();
	});

	// Ship to a different address toggle
	jQuery( 'body' ).on( 'click', 'input[name=ship_to_different_address]',
		function() {
			if ( jQuery ( this ).is( ':checked' ) ) {
				setTimeout( function() {
					// set heights of select arrows correctly
					calc_select_arrow_dimensions();
				}, 1 );
			}
		}
	);

	/**
	 * WooCommerce pre 2.6 compatibility
	 */

	 // My account page error check
	 if ( jQuery( '.avada_myaccount_user' ).length && jQuery( '.woocommerce-error' ).length && ! jQuery( '.avada-myaccount-nav.avada-woocommerce-pre26' ).find( '.active' ).children().hasClass( 'address' ) ) {
		 jQuery( '.avada-myaccount-nav.avada-woocommerce-pre26' ).find( '.is-active' ).removeClass( 'is-active' );
		 jQuery( '.avada-myaccount-nav.avada-woocommerce-pre26' ).find( '.account' ).parent().addClass( 'is-active' );
	 }

	 var avada_myaccount_active = jQuery('.avada-myaccount-nav.avada-woocommerce-pre26').find('.is-active a');

	 if(avada_myaccount_active.hasClass('address') ) {
		 jQuery('.avada-myaccount-data .edit_address_heading').fadeIn();
	 } else {
		 jQuery('.avada-myaccount-data h2:nth-of-type(1)').fadeIn();
	 }

	 if(avada_myaccount_active.hasClass('downloads') ) {
		 jQuery('.avada-myaccount-data .digital-downloads').fadeIn();
	 } else if(avada_myaccount_active.hasClass('orders') ) {
		 jQuery('.avada-myaccount-data .my_account_orders').fadeIn();
	 } else if(avada_myaccount_active.hasClass('address') ) {
		 jQuery('.avada-myaccount-data .myaccount_address, .avada-myaccount-data .address').fadeIn();
	 } else if(avada_myaccount_active ) {
		 jQuery('.avada-myaccount-data .edit-account-form, .avada-myaccount-data .edit-account-heading').fadeIn();
		 jQuery('.avada-myaccount-data h2:nth-of-type(1)').hide();
	 }


	jQuery( '.avada-myaccount-nav.avada-woocommerce-pre26 a' ).on( 'click', function(e) {
		e.preventDefault();

		jQuery('.avada-myaccount-data h2, .avada-myaccount-data .digital-downloads, .avada-myaccount-data .my_account_orders, .avada-myaccount-data .myaccount_address, .avada-myaccount-data .address, .avada-myaccount-data .edit-account-heading, .avada-myaccount-data .edit-account-form').hide();

		if(jQuery(this).hasClass('downloads') ) {
			jQuery('.avada-myaccount-data h2:nth-of-type(1), .avada-myaccount-data .digital-downloads').fadeIn();
		} else if(jQuery(this).hasClass('orders') ) {

			if( jQuery(this).parents('.avada-myaccount-nav').find('.downloads').length ) {
				heading = jQuery('.avada-myaccount-data h2:nth-of-type(2)');
			} else {
				heading = jQuery('.avada-myaccount-data h2:nth-of-type(1)');
			}

			heading.fadeIn();
			jQuery('.avada-myaccount-data .my_account_orders').fadeIn();
		} else if(jQuery(this).hasClass('address') ) {

			if( jQuery(this).parents('.avada-myaccount-nav').find('.downloads').length && jQuery(this).parents('.avada-myaccount-nav').find('.orders').length ) {
				heading = jQuery('.avada-myaccount-data h2:nth-of-type(3)');
			} else if( jQuery(this).parents('.avada-myaccount-nav').find('.downloads').length || jQuery(this).parents('.avada-myaccount-nav').find('.orders').length ) {
				heading = jQuery('.avada-myaccount-data h2:nth-of-type(2)');
			} else {
				heading = jQuery('.avada-myaccount-data h2:nth-of-type(1)');
			}

			heading.fadeIn();
			jQuery('.avada-myaccount-data .myaccount_address, .avada-myaccount-data .address').fadeIn();
		} else if(jQuery(this).hasClass('account') ) {
			jQuery('.avada-myaccount-data .edit-account-heading, .avada-myaccount-data .edit-account-form').fadeIn();
		}

		jQuery('.avada-myaccount-nav li').removeClass('is-active');
		jQuery(this).parent().addClass('is-active');
	});
});

// Reintalize scripts after ajax
jQuery( document ).ajaxComplete( function() {
	avadaAddWoocommerceQuantityBoxes();

	jQuery( '.fusion-update-cart' ).unbind( 'click' );
	jQuery( '.fusion-update-cart' ).on( 'click', function(e) {
		e.preventDefault();
		jQuery( '.cart .actions > .button' ).trigger( 'click' );
	});
});;/**
 * requestAnimationFrame polyfill
 *
 * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
 * http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
 * requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
 * requestAnimationFrame polyfill under MIT license
 */
( function( global ) {
    ( function() {
        if ( global.requestAnimationFrame ) {
            return;
        }

        if ( global.webkitRequestAnimationFrame ) { // Chrome <= 23, Safari <= 6.1, Blackberry 10
            global.requestAnimationFrame = global[ 'webkitRequestAnimationFrame' ];
            global.cancelAnimationFrame = global[ 'webkitCancelAnimationFrame' ] || global[ 'webkitCancelRequestAnimationFrame' ];
        }

        // IE <= 9, Android <= 4.3, very old/rare browsers

        var lastTime = 0;
        global.requestAnimationFrame = function( callback ) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
            var id = global.setTimeout( function() {
                callback( currTime + timeToCall );
            }, timeToCall );

            lastTime = currTime + timeToCall;

            return id; // return the id for cancellation capabilities

        };

        global.cancelAnimationFrame = function( id ) {
            clearTimeout( id );
        };

    } )();

    if ( typeof define === 'function' ) {
        define( function() {
            return global.requestAnimationFrame;
        } );

    }
} )( window );



// Don't re-initialize our variables since that can delete existing values
if ( typeof _fusionImageParallaxImages === 'undefined' ) {
    var _fusionImageParallaxImages = [];
    var _fusionScrollTop;
    var _fusionWindowHeight;
    var _fusionScrollLeft;
    var _fusionWindowWidth;
}

(function( $, window, document, undefined ) {
    // Create the defaults once
    var pluginName = "fusionImageParallax",
        defaults = {
            direction: 'up', // fixed
            mobileenabled: false,
            mobiledevice: false,
            width: '',
            height: '',
            align: 'center',
            opacity: '1',
            velocity: '.3',
            image: '', // The background image to use, if empty, the current background image is used
            target: '', // The element to apply the parallax to
            repeat: false,
            loopScroll: '',
            loopScrollTime: '2',
            removeOrig: false,
            complete: function() {
            }
        };

    // The actual plugin constructor
    function Plugin( element, options ) {
        this.element = element;
        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.settings = $.extend( {}, defaults, options );

		// ThemeFusion edit for Avada theme: making background position work
		var $bg_position = this.settings.align.split( ' ' );
		this.settings.xpos = $bg_position[0];

		if ( $bg_position.length == 2 ) {
			this.settings.ypos = $bg_position[1];
		} else {
			this.settings.ypos = 'center';
		}

        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    // Avoid Plugin.prototype conflicts
    $.extend(
        Plugin.prototype, {
            init: function() {
                // Place initialization logic here
                // You already have access to the DOM element and
                // the options via the instance, e.g. this.element
                // and this.settings
                // you can add more functions like the one below and
                // call them like so: this.yourOtherFunction(this.element, this.settings).
                // console.log("xD");

                // $(window).bind( 'parallax', function() {
                // self.fusionImageParallax();
                // });

                // If there is no target, use the element as the target
                if ( this.settings.target === '' ) {
                    this.settings.target = $( this.element );
                }

                // If there is no image given, use the background image if there is one
                if ( this.settings.image === '' ) {
                    //if ( typeof $(this.element).css('backgroundImage') !== 'undefined' && $(this.element).css('backgroundImage').toLowerCase() !== 'none' && $(this.element).css('backgroundImage') !== '' )
                    if ( typeof $( this.element ).css( 'backgroundImage' ) !== 'undefined' && $( this.element ).css( 'backgroundImage' ) !== '' ) {
                        this.settings.image = $( this.element ).css( 'backgroundImage' ).replace( /url\(|\)|"|'/g, '' );
                    }
                }

                _fusionImageParallaxImages.push( this );

                this.setup();

                this.settings.complete();

                this.containerWidth = 0;
                this.containerHeight = 0;
            },


            setup: function() {
                if ( this.settings.removeOrig !== false ) {
                    $( this.element ).remove();
                }
/*
				// On Mobile, set fixed to up
                if ( this.isMobile() ) {
                     if ( this.settings.direction == 'fixed' ) {
						 this.settings.direction = 'up';
						 this.settings.original_direction = 'fixed';
					 }
                } else {
					if ( this.settings.original_direction == 'fixed' ) {
						this.settings.direction = 'fixed';
						this.settings.target.find( '.parallax-inner' ).remove();
					}
				}
*/
                this.resizeParallaxBackground();
            },


            doParallax: function() {
/*
				// On Mobile, set fixed to up
                if ( this.isMobile() ) {
                     if ( this.settings.direction == 'fixed' ) {
						 this.settings.direction = 'up';
						 this.settings.original_direction = 'fixed';
					 }
                } else {
					if ( this.settings.original_direction == 'fixed' ) {
						this.settings.direction = 'fixed';
						this.settings.target.find( '.parallax-inner' ).remove();
					}
				}
*/

                var $target = this.settings.target.find( '.parallax-inner' );

                // if it's a mobile device and not told to activate on mobile, stop.
                if ( this.settings.mobiledevice && !this.settings.mobileenabled ) {

                    $target.css( {
						'width': '100%',
						'top': '0',
						'left': '0',
						'right': '0',
						'height': 'auto',
						'min-height': $target.parent().outerHeight() + 'px'
					});

                    return;
                }

                // check if the container is in the view
                if ( !this.isInView() ) {
                    return;
                }

                // Assert a minimum of 150 pixels of height globally. Prevents the illusion of parallaxes not rendering at all in empty fields.
                $target.css(
                    {
                        minHeight: '150px'
                    }
                );

                // Retrigger a resize if the container's size suddenly changed
                var w = this.settings.target.width() + parseInt( this.settings.target.css( 'paddingRight' ) ) + parseInt( this.settings.target.css( 'paddingLeft' ) );
                var h = this.settings.target.height() + parseInt( this.settings.target.css( 'paddingTop' ) ) + parseInt( this.settings.target.css( 'paddingBottom' ) );
                if ( this.containerWidth !== 0 && this.containerHeight !== 0 && ( w !== this.containerWidth || h !== this.containerHeight ) ) {
                    this.resizeParallaxBackground();
                }
                this.containerWidth = w;
                this.containerHeight = h;

                // If we don't have anything to scroll, stop
                if ( typeof $target === 'undefined' || $target.length === 0 ) {
                    return;
                }

                // compute for the parallax amount
                var percentageScroll = (_fusionScrollTop - this.scrollTopMin) / (this.scrollTopMax - this.scrollTopMin);
                var dist = this.moveMax * percentageScroll;

				if ( this.settings.direction === 'down' ) {
					dist *= 1.25;
				}

                // change direction
                if ( this.settings.direction == 'left' || this.settings.direction == 'up' ) {
                    dist *= -1;
                }

                // IE9 check, IE9 doesn't support 3d transforms, so fallback to 2d translate
                var translateHori = 'translate3d(';
                var translateHoriSuffix = 'px, -2px, 0px)';
                var translateVert = 'translate3d(0px, ';
                var translateVertSuffix = 'px, 0px)';
                if ( typeof _fusionParallaxIE9 !== 'undefined' ) {
                    translateHori = 'translate(';
                    translateHoriSuffix = 'px, 0px)';
                    translateVert = 'translate(0px, ';
                    translateVertSuffix = 'px)';
                }

                if ( $target.css( 'background-repeat' ) == "no-repeat" ) {
                    if ( this.settings.direction == 'down' && dist < 0 ) {
                        dist = 0;
                    } else if ( this.settings.direction == 'up' && dist > 0 ) {
                        dist = 0;
                    }  else if ( this.settings.direction == 'right' && dist < 0 ) {
                        dist = 0;
                    }  else if ( this.settings.direction == 'left' && dist > 0 ) {
                        dist = 0;
                    }
                }

                // Apply the parallax transforms
                // Use GPU here, use transition to force hardware acceleration
                if ( this.settings.direction === 'fixed' ) {
                 	// For fixed direction, mimic the position of the scroll since doing a position: fixed
                 	// inside an overflow: hidden doesn't work in Firefox
/*
                 	$target.css({
                 		top: -this.settings.target.offset().top,
                 		webkitTransition: 'webkitTransform 1ms linear',
                 		mozTransition: 'mozTransform 1ms linear',
                 		msTransition: 'msTransform 1ms linear',
                 		oTransition: 'oTransform 1ms linear',
                 		transition: 'transform 1ms linear',
                 		webkitTransform: translateVert + _fusionScrollTop + translateVertSuffix,
                 		mozTransform: translateVert + _fusionScrollTop + translateVertSuffix,
                 		msTransform: translateVert + _fusionScrollTop + translateVertSuffix,
                 		oTransform: translateVert + _fusionScrollTop + translateVertSuffix,
                 		transform: translateVert + _fusionScrollTop + translateVertSuffix
                	});
*/
                }
                else if ( this.settings.direction === 'left' || this.settings.direction === 'right' ) {
                    $target.css(
                        {
                            webkitTransform: translateHori + dist + translateHoriSuffix,
                            mozTransform: translateHori + dist + translateHoriSuffix,
                            msTransform: translateHori + dist + translateHoriSuffix,
                            oTransform: translateHori + dist + translateHoriSuffix,
                            transform: translateHori + dist + translateHoriSuffix
                        }
                    );
                }
                else {
                    $target.css(
                        {
                            webkitTransform: translateVert + dist + translateVertSuffix,
                            mozTransform: translateVert + dist + translateVertSuffix,
                            msTransform: translateVert + dist + translateVertSuffix,
                            oTransform: translateVert + dist + translateVertSuffix,
                            transform: translateVert + dist + translateVertSuffix
                        }
                    );
                }
            },


            // Checks whether the container with the parallax is inside our viewport
            isInView: function() {
                var $target = this.settings.target;

                if ( typeof $target === 'undefined' || $target.length === 0 ) {
                    return;
                }

                var elemTop = $target.offset().top;
                var elemHeight = $target.height() + parseInt( $target.css( 'paddingTop' ) ) + parseInt( $target.css( 'paddingBottom' ) );

                if ( elemTop + elemHeight < _fusionScrollTop || _fusionScrollTop + _fusionWindowHeight < elemTop ) {
                    return false;
                }

                return true;
            },

            // Resizes the parallax to match the container size
            resizeParallaxBackground: function() {
                var $target = this.settings.target;
                if ( typeof $target === 'undefined' || $target.length === 0 ) {
                    return;
                }


                // Repeat the background
                var isRepeat = this.settings.repeat === 'true' || this.settings.repeat === true || this.settings.repeat === 1;


                /*
                 * None, do not apply any parallax at all.
                 */

                if ( this.settings.direction === 'none' ) {

                    // Stretch the image to fit the entire window
                    var w = $target.width() + parseInt( $target.css( 'paddingRight' ) ) + parseInt( $target.css( 'paddingLeft' ) );

                    // Compute position
                    var position = $target.offset().left;
                    if ( this.settings.align === 'center' ) {
                        position = '50% 50%';
                    }
                    else if ( this.settings.align === 'left' ) {
                        position = '0% 50%';
                    }
                    else if ( this.settings.align === 'right' ) {
                        position = '100% 50%';
                    }
                    else if ( this.settings.align === 'top' ) {
                        position = '50% 0%';
                    }
                    else if ( this.settings.align === 'bottom' ) {
                        position = '50% 100%';
                    }

                    $target.css(
                        {
                            opacity: Math.abs( parseFloat( this.settings.opacity ) / 100 ),
                            backgroundSize: 'cover',
                            backgroundAttachment: 'scroll',
                            backgroundPosition: position,
                            backgroundRepeat: 'no-repeat'
                        }
                    );
                    if ( this.settings.image !== '' && this.settings.image !== 'none' ) {
                        $target.css(
                            {
                                opacity: Math.abs( parseFloat( this.settings.opacity ) / 100 ),
                                backgroundImage: 'url(' + this.settings.image + ')'
                            }
                        );
                    }

                    /*
                     * Fixed, just stretch to fill up the entire container
                     */
                } else if ( this.settings.direction === 'fixed' ) {

					$target.css({
						backgroundAttachment: 'fixed',
						backgroundRepeat: 'repeat'
					});

					if ( this.settings.image !== '' && this.settings.image !== 'none' ) {
						$target.attr( 'style', 'background-image: url(' + this.settings.image + ') !important;' + $target.attr('style') );
					}
/*
                     // Stretch the image to fit the entire window
					var w = $target.width() + parseInt( $target.css( 'paddingRight' ) ) + parseInt( $target.css( 'paddingLeft' ) );
					var h = _fusionWindowHeight;

                 	if ( this.isMobile ) {
						h += 70;
						w = h / _fusionWindowHeight * w;
					}

                    if ( $target.find( '.parallax-inner' ).length < 1 ) {
                        $target.prepend( '<div class="parallax-inner"></div>' );
                    }

					// Apply the required styles
					$target.css({
						position: 'relative',
						overflow: 'hidden',
						zIndex: 1,
						'background-image': 'none' // ThemeFusion edit for Avada theme: fxing background-image duplication
					})
					.attr('style', $target.attr('style'))
					.find('.parallax-inner').css({
						pointerEvents: 'none',
						width: w,
						height: h,
						position: 'absolute',
						zIndex: -1,
						top: - this.settings.target.offset().top,
						left: 0,
						backgroundPosition: this.settings.xpos + ' ' + this.settings.ypos, // ThemeFusion edit for Avada theme: fxing bg position
						backgroundAttachment: 'scroll',
						backgroundRepeat: isRepeat ? 'repeat' : 'no-repeat',
						backgroundSize: 'cover' // ThemeFusion edit for Avada theme: make the bg image stretch over all container width
					});

					if ( this.settings.image !== '' && this.settings.image !== 'none' ) {
						$target.find('.parallax-inner').css({
							opacity: Math.abs( parseFloat ( this.settings.opacity ) / 100 ),
							backgroundImage: 'url(' + this.settings.image + ')'
						});
					}
*/

                    /*
                     * Left & right parallax - Stretch the image to fit the height & extend the sides
                     */


                } else if ( this.settings.direction === 'left' || this.settings.direction === 'right' ) {

                    // Stretch the image to fit the entire window
                    var w = $target.width() + parseInt( $target.css( 'paddingRight' ) ) + parseInt( $target.css( 'paddingLeft' ) );
                    var h = $target.height() + 4 + parseInt( $target.css( 'paddingTop' ) ) + parseInt( $target.css( 'paddingBottom' ) );

                    var origW = w;
                    w += 400 * Math.abs( parseFloat( this.settings.velocity ) );

                    // Compute left position
                    var left = 0;
                    if ( this.settings.direction === 'right' ) {
                        left -= w - origW;
                    }

                    if ( $target.find( '.parallax-inner' ).length < 1 ) {
                        $target.prepend( '<div class="parallax-inner"></div>' );
                    }

                    // Apply the required styles
                    $target.css(
                        {
                            position: 'relative',
                            overflow: 'hidden',
                            zIndex: 1,
                            'background-image': 'none' // ThemeFusion edit for Avada theme: fxing background-image duplication
                        }
                    )
                        .attr( 'style', $target.attr( 'style' ) )
                        .find( '.parallax-inner' ).css(
                        {
                            pointerEvents: 'none',
                            width: w,
                            height: h,
                            position: 'absolute',
                            zIndex: -1,
                            top: 0,
                            left: left,
                            opacity: Math.abs( parseFloat( this.settings.opacity ) / 100 ),
                            backgroundPosition: isRepeat ? '0 0 ' : this.settings.xpos + ' ' + this.settings.ypos, // ThemeFusion edit for Avada theme: fxing bg position
                            backgroundRepeat: isRepeat ? 'repeat' : 'no-repeat',
                            backgroundSize: isRepeat ? 'auto' : 'cover' // ThemeFusion edit for Avada theme: make the bg image stretch over all container width
                        }
                    );

                    if ( this.settings.image !== '' && this.settings.image !== 'none' ) {
                        $target.find( '.parallax-inner' ).css(
                            {
                                opacity: Math.abs( parseFloat( this.settings.opacity ) / 100 ),
                                backgroundImage: 'url(' + this.settings.image + ')',
                            	// ThemeFusion edit for Avada theme: IE 8 background-size: cover filter
                            	'filter': ( jQuery( '.ua-ie-8' ).length && ! isRepeat ) ? "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.settings.image + "', sizingMethod='scale')" : '',
								'-ms-filter': ( jQuery( '.ua-ie-8' ).length && ! isRepeat ) ? "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.settings.image + "', sizingMethod='scale')" : ''
                            }
                        );
                    }

                    // Compute for the positions to save cycles
                    var scrollTopMin = 0;
                    if ( $target.offset().top > _fusionWindowHeight ) {
                        scrollTopMin = $target.offset().top - _fusionWindowHeight;
                    }
                    var scrollTopMax = $target.offset().top + $target.height() + parseInt( $target.css( 'paddingTop' ) ) + parseInt( $target.css( 'paddingBottom' ) );

                    this.moveMax = w - origW;
                    this.scrollTopMin = scrollTopMin;
                    this.scrollTopMax = scrollTopMax;


                    /*
                     * Up & down parallax - Stretch the image to fit the width & extend vertically
                     */


                } else { // Up or down
					// We have to add a bit more to DOWN since the page is scrolling as well,
					// or else it will not be visible
					var heightCompensate = 900;
					var heightCompensate = jQuery( window ).height();

					/*
					if ( this.settings.direction === 'down' ) {
						heightCompensate *= 1.2;
					}
					*/

					// Stretch the image to fit the entire window
					var w = $target.width() + parseInt( $target.css( 'paddingRight' ) ) + parseInt( $target.css( 'paddingLeft' ) );
					var h = $target.height() + parseInt( $target.css( 'paddingTop' ) ) + parseInt( $target.css( 'paddingBottom' ) );
					var origH = h;
					h += heightCompensate * Math.abs( parseFloat(this.settings.velocity) );

                    // Compute top position
                    var top = 0;
                    if ( this.settings.direction === 'down' ) {
                    	top -= h - origH;
                    }

                    if ( $target.find( '.parallax-inner' ).length < 1 ) {
                        $target.prepend( '<div class="parallax-inner"></div>' );
                    }

                    // Apply the required styles
                    $target.css(
                        {
                            position: 'relative',
                            overflow: 'hidden',
                            zIndex: 1,
                            'background-image': 'none' // ThemeFusion edit for Avada theme: fxing background-image duplication
                        }
                    )
                        .attr( 'style', $target.attr( 'style' ) )
                        .find( '.parallax-inner' ).css(
                        {
                            pointerEvents: 'none',
                            width: w,
                            height: h,
                            position: 'absolute',
                            zIndex: -1,
                            top: top,
                            left: 0,
                            opacity: Math.abs( parseFloat( this.settings.opacity ) / 100 ),
                            backgroundPosition: isRepeat ? '0 0 ' : this.settings.xpos + ' ' + this.settings.ypos, // ThemeFusion edit for Avada theme: fxing bg position
                            backgroundRepeat: isRepeat ? 'repeat' : 'no-repeat',
                            backgroundSize: isRepeat ? 'auto' : 'cover' // ThemeFusion edit for Avada theme: make the bg image stretch over all container width
                        }
                    );

                    if ( this.settings.image !== '' && this.settings.image !== 'none' ) {
                        $target.find( '.parallax-inner' ).css(
                            {
                                opacity: Math.abs( parseFloat( this.settings.opacity ) / 100 ),
                                backgroundImage: 'url(' + this.settings.image + ')',
                            	// ThemeFusion edit for Avada theme: IE 8 background-size: cover filter
                            	'filter': ( jQuery( '.ua-ie-8' ).length && ! isRepeat ) ? "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.settings.image + "', sizingMethod='scale')" : '',
								'-ms-filter': ( jQuery( '.ua-ie-8' ).length && ! isRepeat ) ? "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.settings.image + "', sizingMethod='scale')" : ''
                            }
                        );
                    }

                    // Compute for the positions to save cycles
                    var scrollTopMin = 0;
                    if ( $target.offset().top > _fusionWindowHeight ) {
                        scrollTopMin = $target.offset().top - _fusionWindowHeight;
                    }
                    var scrollTopMax = $target.offset().top + $target.height() + parseInt( $target.css( 'paddingTop' ) ) + parseInt( $target.css( 'paddingBottom' ) );

                    this.moveMax = h - origH;
                    this.scrollTopMin = scrollTopMin;
                    this.scrollTopMax = scrollTopMax;
                }
            },

			// ThemeFusion edit for Avada theme: completely new mobile check
			isMobile: function() {
				return ( jQuery(window).width() <= 800 ) || // small screen sizes
						Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait)' ) ||
						Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape)' ) ||
					( window.screen.width <= 1000 && window.devicePixelRatio > 1 ); // device size estimate
			} ,
        }
    );


    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function( options ) {
        this.each(
            function() {
                if ( !$.data( this, "plugin_" + pluginName ) ) {
                    $.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
                }
            }
        );

        // chain jQuery functions
        return this;
    };


})( jQuery, window, document );


function _fusionRefreshScroll() {
    var $ = jQuery;
    _fusionScrollTop = window.pageYOffset;//$(window).scrollTop();
    _fusionScrollLeft = window.pageXOffset;//$(window).scrollLeft();
}

function _fusionParallaxAll() {
    _fusionRefreshScroll();
    for ( var i = 0; i < _fusionImageParallaxImages.length; i++ ) {
        _fusionImageParallaxImages[i].doParallax();
    }
}

// ThemeFusion edit for Avada theme: moved function out of ready event
function _fusionRefreshWindow() {
	_fusionScrollTop = window.pageYOffset;//$(window).scrollTop();
	_fusionWindowHeight = jQuery( window ).height();
	_fusionScrollLeft = window.pageXOffset;//$(window).scrollLeft();
	_fusionWindowWidth = jQuery( window ).width();
}

jQuery( document ).ready(
    function( $ ) {
        "use strict";

        $( window ).on(
            'scroll touchmove touchstart touchend gesturechange', function( e ) {
                requestAnimationFrame( _fusionParallaxAll );
            }
        );

        function mobileParallaxAll() {
            _fusionRefreshScroll();
            for ( var i = 0; i < _fusionImageParallaxImages.length; i++ ) {
                _fusionImageParallaxImages[i].doParallax();
            }
            requestAnimationFrame( mobileParallaxAll );
        }


        if ( ( Modernizr.touch && jQuery( window ).width() <= 1024 ) || // touch device estimate
            ( window.screen.width <= 1281 && window.devicePixelRatio > 1 ) ) { // device size estimate
            requestAnimationFrame( mobileParallaxAll );
        }

        // When the browser resizes, fix parallax size
        // Some browsers do not work if this is not performed after 1ms
        $( window ).on(
            'resize', function() {
                setTimeout(
                    function() {
                        var $ = jQuery;
                        _fusionRefreshWindow();
                        $.each(
                            _fusionImageParallaxImages, function( i, parallax ) {
                                parallax.resizeParallaxBackground();
                            }
                        );
                    }, 1
                );
            }
        );

        // setTimeout( parallaxAll, 1 );
        setTimeout(
            function() {
                var $ = jQuery;
                _fusionRefreshWindow();
                $.each(
                    _fusionImageParallaxImages, function( i, parallax ) {
                        parallax.resizeParallaxBackground();
                    }
                );
            }, 1
        );

        // setTimeout( parallaxAll, 100 );
        setTimeout(
            function() {
                var $ = jQuery;
                _fusionRefreshWindow();
                $.each(
                    _fusionImageParallaxImages, function( i, parallax ) {
                        parallax.resizeParallaxBackground();
                    }
                );
            }, 100
        );
    }
);

// ThemeFusion edit for Avada theme: needed if FusionSlider is present to recalc the dimensions
jQuery( window ).load( function() {
	// setTimeout( parallaxAll, 1 );
	setTimeout(
		function() {
			var $ = jQuery;
			_fusionRefreshWindow();
			$.each(
				_fusionImageParallaxImages, function( i, parallax ) {
					parallax.resizeParallaxBackground();
				}
			);
		}, 1
	);

	// setTimeout( parallaxAll, 1000 );
	setTimeout(
		function() {
			var $ = jQuery;
			_fusionRefreshWindow();
			$.each(
				_fusionImageParallaxImages, function( i, parallax ) {
					parallax.resizeParallaxBackground();
				}
			);
		}, 1000
	);
});

// @codekit-prepend "fusion-parallax.js"
// @codekit-append "fusion-video-bg.js"

jQuery( document ).ready( function( $ ) {
    "use strict";

    /*
     * Remove video background in mobile devices.
     */

    // Remove the video for mobile devices
    function _isMobile() {
        return ( Modernizr.touch && jQuery(window).width() <= 1000 ) || // touch device estimate
            ( window.screen.width <= 1281 && window.devicePixelRatio > 1 ); // device size estimate
    }

    if ( _isMobile() ) {
        $( '.fusion-bg-parallax.video > div' ).remove();
    }

    // Hide the placeholder
    $('.fusion-bg-parallax').next().addClass('bg-parallax-parent');
    $('.fusion-bg-parallax').attr('style', '').css('display', 'none');



    /*
     * Initialize the image parallax
     */

    $( '.fusion-bg-parallax' ).each(function() {
        $(this).fusionImageParallax({
            image: $(this).data('bg-image'),
            direction: $(this).data('direction'),
            mobileenabled: $(this).data('mobile-enabled'),
            mobiledevice: _isMobile(),
            opacity: $(this).data('opacity'),
            width: $(this).data('bg-width'),
            height: $(this).data('bg-height'),
            velocity: $(this).data('velocity'),
            align: $(this).data('bg-align'),
            repeat: $(this).data('bg-repeat'),
            target: $(this).next(),
            complete: function() {
            }
        });
    });

	// ThemeFusion edit for Avada theme: remove IE 8 background-size: cover filter for all others
	if ( ! jQuery( '.ua-ie-8' ).length ) {
		$( '.fusion-parallax-fixed' ).each( function() {
			$( this ).css({
				'filter': '',
				'-ms-filter': '',
			});
		});
	}



    /*
     * Initialize the video background
     */

    // This is currently performed in the bg-video.js script FIXME


});
;/**
 * These are in charge of initializing YouTube
 */

var $youtubeBGVideos = {};


function _fbRowGetAllElementsWithAttribute( attribute ) {
	var matchingElements = [];
	var allElements = document.getElementsByTagName( '*' );
	for ( var i = 0, n = allElements.length; i < n; i++ ) {
		if ( allElements[i].getAttribute( attribute ) && ! jQuery( allElements[i] ).parents( '.tfs-slider' ).length ) {
			// Element exists with attribute. Add to array.
			matchingElements.push( allElements[i] );
		}
	}
	return matchingElements;
}

//
//function _fbRowOnPlayerReady( event ) {
//
//    var player = event.target;
//
//    player.playVideo();
//    if ( player.isMute ) {
//        player.mute();
//    }
//
//    //jQuery( player.a ).parent().css( 'position', 'relative' );
//
//    //if ( jQuery( player.a ).parent().data( 'loop' ) ) {
//    //    player.loopInterval = setInterval(
//    //        function() {
//    //            if ( typeof player.loopTimeout !== 'undefined' ) {
//    //                clearTimeout( player.loopTimeout );
//    //            }
//    //
//    //            var loopAdjustment = 0;
//    //            if ( typeof jQuery( player.a ).parent().attr( 'data-loop-adjustment' ) !== 'undefined' &&
//    //                jQuery( player.a ).parent().attr( 'data-loop-adjustment' ) !== '' &&
//    //                jQuery( player.a ).parent().attr( 'data-loop-adjustment' ) !== '0' ) {
//    //                loopAdjustment = parseInt( jQuery( player.a ).parent().attr( 'data-loop-adjustment' ) );
//    //            }
//    //
//    //
//    //            player.loopTimeout = setTimeout(
//    //                function() {
//    //                    player.seekTo( 0 );
//    //                }, player.getDuration() * 1000 - player.getCurrentTime() * 1000 - 60 - loopAdjustment
//    //            );
//    //        }, 400
//    //    );
//    //}
//    player.loopInterval = setInterval(function() {
//        if ( typeof player.loopTimeout !== 'undefined' ) {
//            clearTimeout( player.loopTimeout );
//        }
//
//        var loopAdjustment = 0;
//        if ( typeof jQuery(player.a).parent().attr('data-loop-adjustment') !== 'undefined' &&
//            jQuery(player.a).parent().attr('data-loop-adjustment') !== '' &&
//            jQuery(player.a).parent().attr('data-loop-adjustment') !== '0' ) {
//            loopAdjustment = parseInt( jQuery(player.a).parent().attr('data-loop-adjustment') );
//        }
//
//
//        player.loopTimeout = setTimeout(function() {
//            player.seekTo(0);
//        }, player.getDuration() * 1000 - player.getCurrentTime() * 1000 - 60 - loopAdjustment );
//    }, 400);
//}
//
//function clearThisTimeout( player ) {
//
//    console.log('clearThisTimeout');
//
//    if ( !jQuery( player.getIframe() ).parent().data( 'loop' ) ) {
//        player.pauseVideo();
//        return;
//    }
//    player.seekTo( 0 );
//    event.target.trackTime = trackPlaytime( event.target );
//}
//
//function checkTime( player ) {
//
//    if ( typeof player.customLoop !== 'undefined' ) {
//        return;
//    }
//
//    clearTimeout( player.customLoop );
//
//    var $timeLeft = ( player.getDuration() - player.getCurrentTime() ) * 1000 - 500;
//    player.customLoop = setTimeout(
//        function() {
//            clearThisTimeout( player );
//        }, $timeLeft
//    );
//}
//
//function trackPlaytime( player ) {
//
//    var $timeLeft = ( player.getDuration() - player.getCurrentTime() ) * 1000 - 500;
//    console.log("trackPlaytime"+$timeLeft);
//    if ( $timeLeft <= 0 ) {
//        window.clearInterval( player.trackTime );
//        clearThisTimeout( player );
//    }
//};
//
//function _fbRowOnPlayerStateChange( event ) {
//
//    if ( event.data === YT.PlayerState.PLAYING ) {
//        jQuery( event.target.getIframe() ).parent().css( 'visibility', 'visible' );
//        if ( event.target.trackTime === 'undefined' ) {
//            console.log('here');
//            event.target.trackTime =  window.setInterval( function() {
//                trackPlaytime( event.target );
//            }, 100 );
//        }
//    }
//
//    //if (event.data === 0 && jQuery( event.target.getIframe() ).parent().data( 'loop' ) ) { // video ended and repeat option is set true
//    //    event.target.seekTo( 0 ); // restart
//    //}
//    //
//    //console.log(YT.PlayerState);
//    //console.log(event.data);
//    //
//    //if ( event.data === YT.PlayerState.ENDED ) {
//    //    clearThisTimeout( event.target );
//    //} else if ( event.data === YT.PlayerState.PLAYING ) {
//    //
//    //    jQuery( event.target.getIframe() ).parent().css( 'visibility', 'visible' );
//    //    setTimeout(
//    //        function() {
//    //            checkTime( event.target );
//    //        }, 500
//    //    );
//    //}
//}


function _fbRowOnPlayerReady( event ) {
	var player = event.target;
	player.playVideo();
	if ( player.isMute ) {
		player.mute();
	}

	var prevCurrTime = player.getCurrentTime();
	var timeLastCall = +new Date() / 1000;
	var currTime = 0;
	var firstRun = true;

	player.loopInterval = setInterval(
		function() {
			if ( typeof player.loopTimeout !== 'undefined' ) {
				clearTimeout( player.loopTimeout );
			}

			if ( prevCurrTime == player.getCurrentTime() ) {
				currTime = prevCurrTime + ( +new Date() / 1000 - timeLastCall );
			} else {
				currTime = player.getCurrentTime();
				timeLastCall = +new Date() / 1000;
			}
			prevCurrTime = player.getCurrentTime();

			if ( currTime + ( firstRun ? 0.45 : 0.21 ) >= player.getDuration() ) {
				player.pauseVideo();
				player.seekTo( 0 );
				player.playVideo();
				firstRun = false;
			}
		}, 150
	);
}

function _fbRowOnPlayerStateChange( event ) {
	if ( event.data === YT.PlayerState.ENDED ) {
		if ( typeof event.target.loopTimeout !== 'undefined' ) {
			clearTimeout( event.target.loopTimeout );
		}
		event.target.seekTo( 0 );

		// Make the video visible when we start playing
	} else if ( event.data === YT.PlayerState.PLAYING ) {
		jQuery( event.target.getIframe() ).parent().css( 'visibility', 'visible' );
	}
}


function resizeVideo( $wrapper ) {
	var $videoContainer = $wrapper.parent();

	if ( $videoContainer.find( 'iframe' ).width() === null ) {
		setTimeout(
			function() {
				resizeVideo( $wrapper );
			}, 500
		);
		return;
	}

	var $videoWrapper = $wrapper;

	$videoWrapper.css(
		{
			width: 'auto',
			height: 'auto',
			left: 'auto',
			top: 'auto'
		}
	);

	$videoWrapper.css( 'position', 'absolute' );

	var vidWidth = $videoContainer.find( 'iframe' ).width();
	var vidHeight = $videoContainer.find( 'iframe' ).height();
	var containerWidth = $videoContainer.width();
	var containerHeight = $videoContainer.height();
	var containerPaddingLeft = parseInt( $videoContainer.css( 'padding-left' ) );
	var containerPaddingRight = parseInt( $videoContainer.css( 'padding-right' ) );

	if( jQuery( '.width-100' ).length >= 1 ) {
		if( containerPaddingRight > 0 ) {
			containerWidth += containerPaddingRight;
		}

		if( containerPaddingLeft > 0 ) {
			containerWidth += containerPaddingLeft;
		}
	}

	var finalWidth;
	var finalHeight;
	var deltaWidth;
	var deltaHeight;

	var aspectRatio = '16:9';
	if ( typeof $wrapper.attr( 'data-video-aspect-ratio' ) !== 'undefined' ) {
		if ( $wrapper.attr( 'data-video-aspect-ratio' ).indexOf( ':' ) !== -1 ) {
			aspectRatio = $wrapper.attr( 'data-video-aspect-ratio' ).split( ':' );
			aspectRatio[0] = parseFloat( aspectRatio[0] );
			aspectRatio[1] = parseFloat( aspectRatio[1] );
		}
	}


	finalHeight = containerHeight;
	finalWidth = aspectRatio[0] / aspectRatio[1] * containerHeight;

	deltaWidth = ( aspectRatio[0] / aspectRatio[1] * containerHeight ) - containerWidth;
	deltaHeight = ( containerWidth * aspectRatio[1] ) / aspectRatio[0] - containerHeight;

	if ( finalWidth >= containerWidth && finalHeight >= containerHeight ) {
		height = containerHeight;
		width = aspectRatio[0] / aspectRatio[1] * containerHeight
	} else {
		width = containerWidth;
		height = ( containerWidth * aspectRatio[1] ) / aspectRatio[0];
	}

	if( jQuery( '.width-100' ).length >= 1 ) {
		if( containerPaddingRight > 0 ) {
			width += containerPaddingRight;
		}

		if( containerPaddingLeft > 0 ) {
			width += containerPaddingLeft;
		}

		height = ( width * aspectRatio[1] ) / aspectRatio[0];
	}

	marginTop = -( height - containerHeight ) / 2;
	marginLeft = -( width - containerWidth ) / 2;

	if ( $videoContainer.find( '.fusion-video-cover' ).length < 1 ) {
		var $parent = $videoContainer.find( 'iframe' ).parent();
		$parent.prepend( '<div class="fusion-video-cover">&nbsp;</div>' );
	}
	// No YouTube right click stuff!
	$videoContainer.find( '.fusion-video-cover' ).css(
		{
			'z-index': 0,
			'width': width,
			'height': height,
			'position': 'absolute'
		}
	);
	$videoContainer.find( 'iframe' ).parent().css(
		{
			'marginLeft': marginLeft,
			'marginTop': marginTop
		}
	);

	$videoContainer.find( 'iframe' ).css(
		{
			'width': width,
			'height': height,
			'z-index': -1
		}
	);

}

function onYouTubeIframeAPIReady() {
	var videos = _fbRowGetAllElementsWithAttribute( 'data-youtube-video-id' );

	for ( var i = 0; i < videos.length; i++ ) {
		var videoID = videos[i].getAttribute( 'data-youtube-video-id' );

		// Get the elementID for the placeholder where we'll put in the video
		var elemID = '';
		for ( var k = 0; k < videos[i].childNodes.length; k++ ) {
			if ( /div/i.test( videos[i].childNodes[k].tagName ) ) {
				elemID = videos[i].childNodes[k].getAttribute( 'id' );
				break;
			}
		}
		if ( elemID === '' ) {
			continue;
		}

		var player = new YT.Player(
			elemID, {
				height: 'auto',
				width: 'auto',
				videoId: videoID,
				playerVars: {
					autohide: 1,
					autoplay: 1,
					fs: 0,
					showinfo: 0,
					modestBranding: 1,
					start: 0,
					controls: 0,
					//listType:'playlist',
					//list: videoID,
					rel: 0,
					disablekb: 1,
					iv_load_policy: 3,
					wmode: 'transparent'
				},
				events: {
					'onReady': _fbRowOnPlayerReady,
					'onStateChange': _fbRowOnPlayerStateChange
				}
			}
		);

		if( videos[i].getAttribute( 'data-mute' ) === 'yes' ) {
			player.isMute = true;
		} else {
			player.isMute = false;
		}

		// Force YT video to load in HD
		if ( videos[i].getAttribute( 'data-youtube-video-id' ) === 'true' ) {
			player.setPlaybackQuality( 'hd720' );
		}

		// Videos in Windows 7 IE do not fire onStateChange events so the videos do not play.
		// This is a fallback to make those work
		setTimeout(
			function() {
				jQuery( '#' + elemID ).css( 'visibility', 'visible' );
			}, 500
		);
	}
}


/**
 * Set up both YouTube and Vimeo videos
 */


jQuery( document ).ready(
	function( $ ) {

		/*
		 * Disable showing/rendering the parallax in the VC's frontend editor
		 */
		if ( $( 'body' ).hasClass( 'vc_editor' ) ) {
			return;
		}
		$( '.bg-parallax.video, .fusion-bg-parallax.video' ).each(
			function() {
				$( this ).prependTo( $( this ).next().addClass( 'video' ) );
				$( this ).css(
					{
						opacity: Math.abs( parseFloat( $( this ).attr( 'data-opacity' ) ) / 100 )
					}
				);
			}
		);

		var $videoContainer = $( '[data-youtube-video-id], [data-vimeo-video-id]' ).parent();
		$videoContainer.css( 'overflow', 'hidden' );

		$( '[data-youtube-video-id], [data-vimeo-video-id]' ).each(
			function() {
				var $this = $( this );
				setTimeout(
					function() {
						resizeVideo( $this );
					}, 100
				);
			}
		);

		$( '[data-youtube-video-id], [data-vimeo-video-id]' ).each(
			function() {
				var $this = $( this );
				setTimeout(
					function() {
						resizeVideo( $this );
					}, 1000
				);
			}
		);

		$( window ).resize(
			function() {
				$( '[data-youtube-video-id], [data-vimeo-video-id]' ).each(
					function() {
						var $this = $( this );
						setTimeout(
							function() {
								resizeVideo( $this );
							}, 2
						);
					}
				);
			}
		);

		/**
		 * Called once a vimeo player is loaded and ready to receive
		 * commands. You can add events and make api calls only after this
		 * function has been called.
		 */
		function vimeoReady( player_id ) {

			// Keep a reference to Froogaloop for this player
			var container = document.getElementById( player_id ).parentElement,
				froogaloop = $f( player_id );

			if ( jQuery( container ).data( 'mute' ) == 'yes' ) {
				froogaloop.api( 'setVolume', '0' );
			}

			if ( jQuery( container ).data( 'mute' ) == 'no' ) {
				froogaloop.api( 'setVolume', '1' );
			}

			froogaloop.addEvent(
				'playProgress', function onPlayProgress( data, id ) {
					jQuery( container ).css( 'visibility', 'visible' );
				}
			);

		}

		var $vimeos = $( '[data-vimeo-video-id]' );
		if ( $vimeos.length > 0 ) {
			var $protocol = 'http:';
			if ( js_local_vars.is_ssl== 'true' ) {
				$protocol = 'https:';
			}

			$.getScript( $protocol + "//a.vimeocdn.com/js/froogaloop2.min.js?97273-1352487961" ).done(
				function( script, textStatus ) {
					var vimeoPlayers = document.querySelectorAll( 'iframe' ),
						player;

					for ( var i = 0, length = vimeoPlayers.length; i < length; i++ ) {
						player = vimeoPlayers[i];
						if ( jQuery( 'html' ).hasClass( 'ua-ie-11' ) ) {
							jQuery( player ).parent().css( 'visibility', 'visible' );
						}
						$f( player ).addEvent( 'ready', vimeoReady );
					}
				}
			);
		}


		/**
		 * Utility function for adding an event. Handles the inconsistencies
		 * between the W3C method for adding events (addEventListener) and
		 * IE's (attachEvent).
		 */
		function addEvent( element, eventName, callback ) {
			if ( element.addEventListener ) {
				element.addEventListener( eventName, callback, false );
			}
			else {
				element.attachEvent( 'on' + eventName, callback );
			}
		}

		//
		//player.addEvent('ready', function() {
		//    // mute
		//    if ( $this.attr( 'data-mute' ) === 'true' ) {
		//        player.api( 'setVolume', 0 );
		//    }
		//});

		/*
		 player.addEvent('ready', function() {
		 console.log('here');
		 // mute
		 if ( $this.attr('data-mute') === 'true' ) {
		 player.api( 'setVolume', 0 );
		 }

		 // show the video after the player is loaded
		 player.addEvent('playProgress', function onPlayProgress(data, id) {
		 jQuery('#' + id).parent().css('visibility', 'visible');
		 });
		 });
		 */

		// When the player is ready, add listeners for pause, finish, and playProgress
	}
);

jQuery( window ).load(
	function() {
		jQuery( '[data-youtube-video-id], [data-vimeo-video-id]' ).each(
			function() {
				var $this = jQuery( this );
				setTimeout(
					function() {
						resizeVideo( $this );
					}, 500
				);
			}
		);
	}
);

;jQuery( document ).ready(function() {

	'use strict';

	// position dropdown menu correctly
	jQuery.fn.fusion_position_menu_dropdown = function( variables ) {

			if( ( js_local_vars.header_position === 'Top' && ! jQuery( 'body.rtl' ).length ) || js_local_vars.header_position === 'Left'  ) {
				return 	jQuery( this ).children( '.sub-menu' ).each( function() {

					// reset attributes
					jQuery( this ).removeAttr( 'style' );
					jQuery( this ).show();
					jQuery( this ).removeData( 'shifted' );

					var submenu = jQuery( this );

					if( submenu.length ) {
						var submenu_position = submenu.offset(),
							submenu_left = submenu_position.left,
							submenu_top = submenu_position.top,
							submenu_height = submenu.height(),
							submenu_width = submenu.outerWidth(),
							submenu_bottom_edge = submenu_top + submenu_height,
							submenu_right_edge = submenu_left + submenu_width,
							browser_bottom_edge = jQuery( window ).height(),
							browser_right_edge = jQuery( window ).width(),
							admin_bar_height,
							submenu_new_top_pos;

						if(	jQuery( '#wpadminbar' ).length ) {
							admin_bar_height = jQuery( '#wpadminbar' ).height();
						} else {
							admin_bar_height = 0;
						}

						if( jQuery( '#side-header' ).length ) {
							var side_header_top = jQuery( '#side-header' ).offset().top - admin_bar_height;
						}

						// current submenu goes beyond browser's right edge
						if( submenu_right_edge > browser_right_edge ) {

							//if there are 2 or more submenu parents position this submenu below last one
							if( submenu.parent().parent( '.sub-menu' ).parent().parent( '.sub-menu' ).length ) {
								submenu.css({
									'left': '0',
									'top': submenu.parent().parent( '.sub-menu' ).height()
								});

							// first or second level submenu
							} else {
								// first level submenu
								if( ! submenu.parent().parent( '.sub-menu' ).length ) {
									submenu.css( 'left', ( -1 ) * submenu_width + submenu.parent().width() );

								// second level submenu
								} else {
									submenu.css({
										'left': ( -1 ) * submenu_width
									});
								}
							}

							submenu.data( 'shifted', 1 );
						// parent submenu had to be shifted
						} else if( submenu.parent().parent( '.sub-menu' ).length ) {
							if( submenu.parent().parent( '.sub-menu' ).data( 'shifted' ) ) {
								submenu.css( 'left', ( -1 ) * submenu_width );
								submenu.data( 'shifted', 1 );
							}
						}

						// Calculate dropdown vertical position on side header.
						if( js_local_vars.header_position !== 'Top' && submenu_bottom_edge > side_header_top + browser_bottom_edge && jQuery( window ).height() >= jQuery( '.side-header-wrapper' ).height() ) {
							if( submenu_height < browser_bottom_edge  ) {
								submenu_new_top_pos = ( -1 ) * ( submenu_bottom_edge - side_header_top - browser_bottom_edge + 20 );
							} else {
								submenu_new_top_pos = ( -1 ) * ( submenu_top - admin_bar_height );
							}
							submenu.css( 'top', submenu_new_top_pos );
						}
					}
				});
			} else {
				return 	jQuery( this ).children( '.sub-menu' ).each( function() {

					// reset attributes
					jQuery( this ).removeAttr( 'style' );
					jQuery( this ).removeData( 'shifted' );

					var submenu = jQuery( this );

					if( submenu.length ) {
						var submenu_position = submenu.offset(),
							submenu_left_edge = submenu_position.left,
							submenu_top = submenu_position.top,
							submenu_height = submenu.height(),
							submenu_width = submenu.outerWidth(),
							submenu_bottom_edge = submenu_top + submenu_height,
							browser_bottom_edge = jQuery( window ).height();

						if(	jQuery( '#wpadminbar' ).length ) {
							var admin_bar_height = jQuery( '#wpadminbar' ).height();
						} else {
							var admin_bar_height = 0;
						}

						if( jQuery( '#side-header' ).length ) {
							var side_header_top = jQuery( '#side-header' ).offset().top - admin_bar_height;
						}

						// current submenu goes beyond browser's left edge
						if( submenu_left_edge < 0 ) {
							//if there are 2 or more submenu parents position this submenu below last one
							if( submenu.parent().parent( '.sub-menu' ).parent().parent( '.sub-menu' ).length ) {
								if( js_local_vars.header_position == 'Right' ) {
									submenu.css({
										'left': '0',
										'top': submenu.parent().parent( '.sub-menu' ).height()
									});
								} else {
									submenu.css({
										'right': '0',
										'top': submenu.parent().parent( '.sub-menu' ).height()
									});
								}
							// first or second level submenu
							} else {
								// first level submenu
								if( ! submenu.parent().parent( '.sub-menu' ).length ) {
									submenu.css( 'right', ( -1 ) * submenu_width + submenu.parent().width() );

								// second level submenu
								} else {
									submenu.css({
										'right': ( -1 ) * submenu_width
									});
								}
							}

							submenu.data( 'shifted', 1 );
						// parent submenu had to be shifted
						} else if( submenu.parent().parent( '.sub-menu' ).length ) {
							if( submenu.parent().parent( '.sub-menu' ).data( 'shifted' ) ) {
								submenu.css( 'right', ( -1 ) * submenu_width );
							}
						}

						// Calculate dropdown vertical position on side header
						if( js_local_vars.header_position != 'Top' && submenu_bottom_edge > side_header_top + browser_bottom_edge && jQuery( window ).height() >= jQuery( '.side-header-wrapper' ).height() ) {
							if( submenu_height < browser_bottom_edge  ) {
								var submenu_new_top_pos = ( -1 ) * ( submenu_bottom_edge - side_header_top - browser_bottom_edge + 20 );
							} else {
								var submenu_new_top_pos = ( -1 ) * ( submenu_top - admin_bar_height );
							}
							submenu.css( 'top', submenu_new_top_pos );
						}
					}
				});
			}
	};

	// Recursive function for positioning menu items correctly on load
	jQuery.fn.walk_through_menu_items = function() {
		jQuery( this ).fusion_position_menu_dropdown();

		if( jQuery( this ).find( '.sub-menu' ).length ) {
			jQuery( this ).find( '.sub-menu li' ).walk_through_menu_items();
		} else {
			return;
		}
	};

	// Position the cart dropdown vertically on side-header layouts
	jQuery.fn.position_cart_dropdown = function() {
		if( js_local_vars.header_position != 'Top' ) {
			jQuery( this ).each( function() {
				jQuery( this ).css( 'top', '' );

				var cart_dropdown = jQuery( this ),
					cart_dropdown_top = cart_dropdown.offset().top,
					cart_dropdown_height = cart_dropdown.height(),
					cart_dropdown_bottom_edge = cart_dropdown_top + cart_dropdown_height,
					admin_bar_height = ( jQuery( '#wpadminbar' ).length ) ? jQuery( '#wpadminbar' ).height() : 0,
					side_header_top = jQuery( '#side-header' ).offset().top - admin_bar_height,
					browser_bottom_edge = jQuery( window ).height();

				if( cart_dropdown_bottom_edge > side_header_top + browser_bottom_edge && jQuery( window ).height() >= jQuery( '.side-header-wrapper' ).height() ) {
					if( cart_dropdown_height < browser_bottom_edge ) {
						var cart_dropdown_new_top_pos = ( -1 ) * ( cart_dropdown_bottom_edge - side_header_top - browser_bottom_edge + 20 );
					} else {
						var cart_dropdown_new_top_pos = ( -1 ) * ( cart_dropdown_top - admin_bar_height );
					}

					cart_dropdown.css( 'top', cart_dropdown_new_top_pos );
				}
			});
		}
	};

	// Position the search form vertically on side-header layouts
	jQuery.fn.position_menu_search_form = function() {
		if( js_local_vars.header_position != 'Top' ) {
			jQuery( this ).each( function() {
				jQuery( this ).css( 'top', '' );

				var search_form = jQuery( this ),
					search_form_top = search_form.offset().top,
					search_form_height = search_form.outerHeight(),
					search_form_bottom_edge = search_form_top + search_form_height,
					admin_bar_height = ( jQuery( '#wpadminbar' ).length ) ? jQuery( '#wpadminbar' ).height() : 0,
					side_header_top = jQuery( '#side-header' ).offset().top - admin_bar_height,
					browser_bottom_edge = jQuery( window ).height();

				if( search_form_bottom_edge > side_header_top + browser_bottom_edge && jQuery( window ).height() >= jQuery( '.side-header-wrapper' ).height() ) {
					var search_form_new_top_pos = ( -1 ) * ( search_form_bottom_edge - side_header_top - browser_bottom_edge + 20 );

					search_form.css( 'top', search_form_new_top_pos );
				}
			});
		}
	};

	// position mega menu correctly
	jQuery.fn.fusion_position_megamenu = function( variables ) {
		// side header left handling
		if( jQuery( '.side-header-left' ).length ) {
			return this.each( function() {
				jQuery( this ).children( 'li' ).each( function() {
					var li_item = jQuery( this ),
						megamenu_wrapper = li_item.find( '.fusion-megamenu-wrapper' );

					if( megamenu_wrapper.length ) {
						megamenu_wrapper.removeAttr( 'style' );

						var megamenu_wrapper_left = jQuery( '#side-header' ).outerWidth() - 1,
							megamenu_wrapper_top = megamenu_wrapper.offset().top,
							megamenu_wrapper_height = megamenu_wrapper.height(),
							megamenu_bottom_edge = megamenu_wrapper_top + megamenu_wrapper_height,
							admin_bar_height = ( jQuery( '#wpadminbar' ).length ) ? jQuery( '#wpadminbar' ).height() : 0,
							side_header_top = jQuery( '#side-header' ).offset().top - admin_bar_height,
							browser_bottom_edge = jQuery( window ).height();

						if( ! jQuery( 'body.rtl' ).length ) {
							megamenu_wrapper.css( 'left', megamenu_wrapper_left );
						} else {
							megamenu_wrapper.css({ 'left': megamenu_wrapper_left, 'right': 'auto' });
						}

						if( megamenu_bottom_edge > side_header_top + browser_bottom_edge && jQuery( window ).height() >= jQuery( '.side-header-wrapper' ).height() ) {
							if( megamenu_wrapper_height < browser_bottom_edge ) {
								var megamenu_wrapper_new_top_pos = ( -1 ) * ( megamenu_bottom_edge - side_header_top - browser_bottom_edge + 20 );
							} else {
								var megamenu_wrapper_new_top_pos = ( -1 ) * ( megamenu_wrapper_top - admin_bar_height );
							}

							megamenu_wrapper.css( 'top', megamenu_wrapper_new_top_pos );
						}
					}
				});
			});
		}

		// side header right handling
		if( jQuery( '.side-header-right' ).length ) {
			return this.each( function() {
				jQuery( this ).children( 'li' ).each( function() {
					var li_item = jQuery( this ),
						megamenu_wrapper = li_item.find( '.fusion-megamenu-wrapper' );

					if( megamenu_wrapper.length ) {
						megamenu_wrapper.removeAttr( 'style' );

						var megamenu_wrapper_left = ( -1 ) * megamenu_wrapper.outerWidth(),
							megamenu_wrapper_top = megamenu_wrapper.offset().top,
							megamenu_wrapper_height = megamenu_wrapper.height(),
							megamenu_bottom_edge = megamenu_wrapper_top + megamenu_wrapper_height,
							admin_bar_height = ( jQuery( '#wpadminbar' ).length ) ? jQuery( '#wpadminbar' ).height() : 0,
							side_header_top = jQuery( '#side-header' ).offset().top - admin_bar_height,
							browser_bottom_edge = jQuery( window ).height();

						if( ! jQuery( 'body.rtl' ).length ) {
							megamenu_wrapper.css( 'left', megamenu_wrapper_left );
						} else {
							megamenu_wrapper.css({ 'left': megamenu_wrapper_left, 'right': 'auto' });
						}

						if( megamenu_bottom_edge > side_header_top + browser_bottom_edge && jQuery( window ).height() >= jQuery( '.side-header-wrapper' ).height()) {
							if( megamenu_wrapper_height < browser_bottom_edge ) {
								var megamenu_wrapper_new_top_pos = ( -1 ) * ( megamenu_bottom_edge - side_header_top - browser_bottom_edge + 20 );
							} else {
								var megamenu_wrapper_new_top_pos = ( -1 ) * ( megamenu_wrapper_top - admin_bar_height );
							}

							megamenu_wrapper.css( 'top', megamenu_wrapper_new_top_pos );
						}
					}
				});
			});
		}

		// top header handling
		var reference_elem = '';
		if( jQuery( '.fusion-header-v4' ).length ) {
			reference_elem = jQuery( this ).parent( '.fusion-main-menu' ).parent();
		} else {
			reference_elem = jQuery( this ).parent( '.fusion-main-menu' );
		}

		if( jQuery( this ).parent( '.fusion-main-menu' ).length ) {

			var main_nav_container = reference_elem,
				main_nav_container_position = main_nav_container.offset(),
				main_nav_container_width = main_nav_container.width(),
				main_nav_container_left_edge = main_nav_container_position.left,
				main_nav_container_right_edge = main_nav_container_left_edge + main_nav_container_width;

			if( ! jQuery( 'body.rtl' ).length ) {
				return this.each( function() {

					jQuery( this ).children( 'li' ).each( function() {
						var li_item = jQuery( this ),
							li_item_position = li_item.offset(),
							megamenu_wrapper = li_item.find( '.fusion-megamenu-wrapper' ),
							megamenu_wrapper_width = megamenu_wrapper.outerWidth(),
							megamenu_wrapper_position = 0;

						// check if there is a megamenu
						if( megamenu_wrapper.length ) {
							megamenu_wrapper.removeAttr( 'style' );

							// set megamenu max width
							var reference_avada_row;

							if( jQuery( '.fusion-secondary-main-menu' ).length ) {
								reference_avada_row = jQuery( '.fusion-header-wrapper .fusion-secondary-main-menu .fusion-row' );
							} else {
								reference_avada_row = jQuery( '.fusion-header-wrapper .fusion-row' );
							}

							if( megamenu_wrapper.hasClass( 'col-span-12' ) && ( reference_avada_row.width() < megamenu_wrapper.data( 'maxwidth' ) ) ) {
								megamenu_wrapper.css( 'width', reference_avada_row.width() );
							} else {
								megamenu_wrapper.removeAttr( 'style' );
							}

							// reset the megmenu width after resizing the menu
							megamenu_wrapper_width = megamenu_wrapper.outerWidth();

							if( li_item_position.left + megamenu_wrapper_width > main_nav_container_right_edge ) {
								megamenu_wrapper_position = -1 * ( li_item_position.left - ( main_nav_container_right_edge - megamenu_wrapper_width ) );

								if( js_local_vars.logo_alignment.toLowerCase() == 'right' ) {
									if( li_item_position.left + megamenu_wrapper_position < main_nav_container_left_edge ) {
										megamenu_wrapper_position = -1 * ( li_item_position.left - main_nav_container_left_edge );
									}
								}

								megamenu_wrapper.css( 'left', megamenu_wrapper_position );
							}
						}
					});
				});

			} else {
				return this.each( function() {
					jQuery( this ).children( 'li' ).each( function() {
						var li_item = jQuery( this ),
							li_item_position = li_item.offset(),
							li_item_right_edge = li_item_position.left + li_item.outerWidth(),
							megamenu_wrapper = li_item.find( '.fusion-megamenu-wrapper' ),
							megamenu_wrapper_width = megamenu_wrapper.outerWidth(),
							megamenu_wrapper_position = 0;

						// check if there is a megamenu
						if( megamenu_wrapper.length ) {
							megamenu_wrapper.removeAttr( 'style' );

							// set megamenu max width
							var reference_avada_row;

							if( jQuery( '.fusion-secondary-main-menu' ).length ) {
								reference_avada_row = jQuery( '.fusion-header-wrapper .fusion-secondary-main-menu .fusion-row' );
							} else {
								reference_avada_row = jQuery( '.fusion-header-wrapper .fusion-row' );
							}

							if( megamenu_wrapper.hasClass( 'col-span-12' ) && ( reference_avada_row.width() < megamenu_wrapper.data( 'maxwidth' ) ) ) {
								megamenu_wrapper.css( 'width', reference_avada_row.width() );
							} else {
								megamenu_wrapper.removeAttr( 'style' );
							}

							if( li_item_right_edge - megamenu_wrapper_width < main_nav_container_left_edge ) {

								megamenu_wrapper_position = -1 * ( megamenu_wrapper_width - ( li_item_right_edge - main_nav_container_left_edge ) );

								if( js_local_vars.logo_alignment.toLowerCase() == 'left' || ( js_local_vars.logo_alignment.toLowerCase() == 'center' && ! jQuery( '.header-v5' ).length ) || jQuery( this ).parents( '.sticky-header' ).length ) {
									if( li_item_right_edge - megamenu_wrapper_position > main_nav_container_right_edge ) {
										megamenu_wrapper_position = -1 * ( main_nav_container_right_edge - li_item_right_edge );
									}
								}

								megamenu_wrapper.css( 'right', megamenu_wrapper_position );
							}
						}
					});
				});
			}
		}
	};

	jQuery.fn.calc_megamenu_responsive_column_widths = function( variables ) {
		jQuery( this ).find( '.fusion-megamenu-menu' ).each( function() {
			var megamenu_holder = jQuery( this ).find( '.fusion-megamenu-holder' ),
				megamenu_holder_full_width = megamenu_holder.data( 'width' ),
				reference_fusion_row = ( jQuery( '.fusion-secondary-main-menu' ).length ) ? jQuery( '.fusion-header-wrapper .fusion-secondary-main-menu .fusion-row' ) : jQuery( '.fusion-header-wrapper .fusion-row' ),
				available_space = reference_fusion_row.width();

			if( js_local_vars.header_position != 'Top' ) {
				var main_padding_left = jQuery( '#main' ).css( 'padding-left' ).replace( 'px', '' );
				available_space = jQuery( window ).width() - main_padding_left - jQuery( '#side-header' ).outerWidth();
			}

			if( available_space < megamenu_holder_full_width ) {
				megamenu_holder.css( 'width', available_space );

				if( ! megamenu_holder.parents( '.fusion-megamenu-wrapper' ).hasClass( 'fusion-megamenu-fullwidth' ) ) {
					megamenu_holder.find( '.fusion-megamenu-submenu' ).each( function() {
						var submenu = jQuery( this );
						var submenu_width = submenu.data( 'width' ) * available_space / megamenu_holder_full_width;
						submenu.css( 'width', submenu_width );
					});
				}
			} else {
				megamenu_holder.css( 'width', megamenu_holder_full_width );

				if( ! megamenu_holder.parents( '.fusion-megamenu-wrapper' ).hasClass( 'fusion-megamenu-fullwidth' ) ) {
					megamenu_holder.find( '.fusion-megamenu-submenu' ).each( function() {
						jQuery( this ).css( 'width', jQuery( this ).data( 'width' ) );
					});
				}
			}
		});
	};

	jQuery.fn.position_last_top_menu_item = function( variables ) {
		if( jQuery( this ).children( 'ul' ).length || jQuery( this).children( 'div' ).length ) {
			var last_item = jQuery( this ),
				last_item_left_pos = last_item.position().left,
				last_item_width = last_item.outerWidth(),
				last_item_child,
				parent_container = jQuery( '.fusion-secondary-header .fusion-row' ),
				parent_container_left_pos = parent_container.position().left,
				parent_container_width = parent_container.outerWidth();

			if( last_item.children( 'ul' ).length ) {
				last_item_child =  last_item.children( 'ul' );
			} else if( last_item.children('div').length ) {
				last_item_child =  last_item.children( 'div' );
			}

			if( ! jQuery( 'body.rtl' ).length ) {
				if( last_item_left_pos + last_item_child.outerWidth() > parent_container_left_pos + parent_container_width ) {
					last_item_child.css( 'right', '-1px' ).css( 'left', 'auto' );

					last_item_child.find( '.sub-menu' ).each( function() {
						jQuery( this ).css( 'right', '100px' ).css( 'left', 'auto' );
					});
				}
			} else {
				if( last_item_child.position().left < last_item_left_pos ) {
					last_item_child.css( 'left', '-1px' ).css( 'right', 'auto' );

					last_item_child.find( '.sub-menu' ).each( function() {
						jQuery( this ).css( 'left', '100px' ).css( 'right', 'auto' );
					});
				}
			}
		}
	};

	// IE8 fixes
	jQuery( '.fusion-main-menu > ul > li:last-child' ).addClass( 'fusion-last-menu-item' );
	if( cssua.ua.ie && cssua.ua.ie.substr(0, 1) == '8' ) {
		jQuery( '.fusion-header-shadow' ).removeClass( 'fusion-header-shadow' );
	}

	// Calculate main menu dropdown submenu position
	if( jQuery.fn.fusion_position_menu_dropdown ) {
		jQuery( '.fusion-dropdown-menu, .fusion-dropdown-menu li' ).mouseenter( function() {
			jQuery( this ).fusion_position_menu_dropdown();
		});

		jQuery( '.fusion-dropdown-menu > ul > li' ).each( function() {
			jQuery( this ).walk_through_menu_items();
		});

		jQuery( window ).on( 'resize', function() {
			jQuery( '.fusion-dropdown-menu > ul > li' ).each( function() {
				jQuery( this ).walk_through_menu_items();
			});
		});
	}

	// Set overflow state of main nav items; done to get rid of menu overflow
	jQuery( '.fusion-dropdown-menu ' ).mouseenter( function() {
		jQuery( this ).css( 'overflow', 'visible' );
	});
	jQuery( '.fusion-dropdown-menu' ).mouseleave( function() {
		jQuery( this ).css( 'overflow', '' );
	});

	// Search icon show/hide
	jQuery( document ).click( function() {
		jQuery( '.fusion-main-menu-search .fusion-custom-menu-item-contents' ).hide();
		jQuery( '.fusion-main-menu-search' ).removeClass( 'fusion-main-menu-search-open' );
		jQuery( '.fusion-main-menu-search' ).find( 'style' ).remove();
	});

	jQuery( '.fusion-main-menu-search' ).click(function(e) {
		e.stopPropagation();
	});

	jQuery( '.fusion-main-menu-search .fusion-main-menu-icon' ).click(function(e) {
		e.stopPropagation();

		if( jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).css( 'display' ) == 'block' ) {
			jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).hide();
			jQuery( this ).parent().removeClass( 'fusion-main-menu-search-open' );

			jQuery( this ).parent().find( 'style' ).remove();
		} else {
			jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).removeAttr( 'style' );
			jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).show();
			jQuery( this ).parent().addClass( 'fusion-main-menu-search-open' );

			jQuery( this ).parent().append( '<style>.fusion-main-menu{overflow:visible!important;</style>' );
			jQuery( this ).parent().find( '.fusion-custom-menu-item-contents .s' ).focus();

			// position main menu search box on click positioning
			if( js_local_vars.header_position == 'Top' ) {
				if( ! jQuery( 'body.rtl' ).length && jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).offset().left < 0 ) {
					jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).css({
						'left': '0',
						'right': 'auto'
					});
				}

				if( jQuery( 'body.rtl' ).length && jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).offset().left + jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).width()  > jQuery( window ).width() ) {
					jQuery( this ).parent().find( '.fusion-custom-menu-item-contents' ).css({
						'left': 'auto',
						'right': '0'
					});
				}
			}
		}
	});

	// Calculate megamenu position
	if( jQuery.fn.fusion_position_megamenu ) {
		jQuery( '.fusion-main-menu > ul' ).fusion_position_megamenu();

		jQuery( '.fusion-main-menu .fusion-megamenu-menu' ).mouseenter( function() {
			jQuery( this ).parent().fusion_position_megamenu();
		});

		jQuery(window).resize(function() {
			jQuery( '.fusion-main-menu > ul' ).fusion_position_megamenu();
		});
	}

	// Calculate megamenu column widths
	if( jQuery.fn.calc_megamenu_responsive_column_widths ) {
		jQuery( '.fusion-main-menu > ul' ).calc_megamenu_responsive_column_widths();

		jQuery(window).resize(function() {
			jQuery( '.fusion-main-menu > ul' ).calc_megamenu_responsive_column_widths();
		});
	}

	// Top Menu last item positioning
	jQuery('.fusion-header-wrapper .fusion-secondary-menu > ul > li:last-child').position_last_top_menu_item();

	fusion_reposition_menu_item( '.fusion-main-menu .fusion-main-menu-cart' );
	fusion_reposition_menu_item( '.fusion-secondary-menu .fusion-menu-login-box' );

	function fusion_reposition_menu_item( $menu_item ) {
		// Position main menu cart dropdown correctly
		if( js_local_vars.header_position == 'Top' ) {
			jQuery( $menu_item ).mouseenter( function(e) {

				if( jQuery(this).find( '> div' ).length && jQuery(this).find( '> div' ).offset().left < 0 ) {
					jQuery (this ).find( '> div' ).css({
						'left': '0',
						'right': 'auto'
					});
				}

				if( jQuery(this).find( '> div' ).length && jQuery( this ).find( '> div' ).offset().left + jQuery( this ).find( '> div' ).width()  > jQuery( window ).width() ) {
					jQuery( this ).find( '> div' ).css({
						'left': 'auto',
						'right': '0'
					});
				}
			});

			jQuery( window ).on( 'resize', function() {
				jQuery( $menu_item ).find( '> div' ).each( function() {
					var $menu_item_dropdown = jQuery( this ),
						$menu_item_dropdown_width = $menu_item_dropdown.outerWidth(),
						$menu_item_dropdown_left_edge = $menu_item_dropdown.offset().left,
						$menu_item_dropdown_right_edge = $menu_item_dropdown_left_edge + $menu_item_dropdown_width,
						$menu_item_left_edge = $menu_item_dropdown.parent().offset().left,
						window_right_edge = jQuery( window ).width();


					if( ! jQuery( 'body.rtl' ).length ) {
						if( ( $menu_item_dropdown_left_edge < $menu_item_left_edge && $menu_item_dropdown_left_edge < 0 ) || ( $menu_item_dropdown_left_edge == $menu_item_left_edge && $menu_item_dropdown_left_edge - $menu_item_dropdown_width < 0 ) ) {
							$menu_item_dropdown.css({
								'left': '0',
								'right': 'auto'
							});
						} else {
							$menu_item_dropdown.css({
								'left': 'auto',
								'right': '0'
							});
						}
					} else {
						if( ( $menu_item_dropdown_left_edge == $menu_item_left_edge && $menu_item_dropdown_right_edge > window_right_edge ) || ( $menu_item_dropdown_left_edge < $menu_item_left_edge && $menu_item_dropdown_right_edge + $menu_item_dropdown_width > window_right_edge )  ) {
							$menu_item_dropdown.css({
								'left': 'auto',
								'right': '0'
							});
						} else {
							$menu_item_dropdown.css({
								'left': '0',
								'right': 'auto'
							});
						}
					}
				});
			});
		}
	}

	// Reinitialize google map on megamenu
	jQuery('.fusion-megamenu-menu').mouseenter(function() {
		if(jQuery(this).find('.shortcode-map').length ) {
			jQuery(this).find('.shortcode-map').each(function() {
				jQuery( this ).reinitialize_google_map();
			});
		}
	});

	// Make iframes in megamenu widget area load correctly in Safari and IE
	// Safari part - load the iframe correctly
    var iframe_loaded = false;
    jQuery( '.fusion-megamenu-menu' ).mouseover(
		function() {
			jQuery( this ).find( '.fusion-megamenu-widgets-container iframe' ).each(
				function() {
					if( ! iframe_loaded ) {
						jQuery( this ).attr('src', jQuery( this ).attr( 'src' ) );
					}
					iframe_loaded = true;
				}
			);
    	}
    );

    // IE part - making the megamenu stay on hover
    jQuery( '.fusion-megamenu-wrapper iframe' ).mouseover(
		function() {
			jQuery( this ).parents( '.fusion-megamenu-widgets-container').css( 'display', 'block' );
			jQuery( this ).parents( '.fusion-megamenu-wrapper' ).css({ 'opacity': '1', 'visibility': 'visible' });
    	}
    );

    jQuery( '.fusion-megamenu-wrapper iframe' ).mouseout(
		function() {
			jQuery( this ).parents( '.fusion-megamenu-widgets-container').css( 'display', '' );
			jQuery( this ).parents( '.fusion-megamenu-wrapper' ).css({ 'opacity': '', 'visibility': '' });
    	}
    );

	// Position main menu cart dropdown correctly on side-header
	jQuery( '.fusion-navbar-nav .cart' ).find( '.cart-contents' ).position_cart_dropdown();

	jQuery(window).on( 'resize', function() {
		jQuery( '.fusion-navbar-nav .cart' ).find( '.cart-contents' ).position_cart_dropdown();
	});

	// Position main menu search form correctly on side-header
	jQuery( '.fusion-navbar-nav .search-link' ).click( function() {
		setTimeout( function() {
			jQuery( '.fusion-navbar-nav .search-link' ).parent().find( '.main-nav-search-form' ).position_menu_search_form();
		}, 5 );
	});

	jQuery(window).on( 'resize', function() {
		jQuery( '.fusion-navbar-nav .main-nav-search' ).find( '.main-nav-search-form' ).position_menu_search_form();
	});

	// Set overflow on the main menu correcty to show dropdowns when needed
	if ( ! jQuery( '.fusion-header-v6' ).length ) {
		jQuery( '.fusion-main-menu' ).mouseover(function() {
			jQuery( this ).css( 'overflow', 'visible' );
		});

		jQuery( '.fusion-main-menu' ).mouseout(function() {
			jQuery( this ).css( 'overflow', '' );
		});
	}

	/**
	 * Mobile Navigation
	 */

	jQuery( '.fusion-mobile-nav-holder' ).not( '.fusion-mobile-sticky-nav-holder' ).each(function() {
		var $mobile_nav_holder = jQuery( this );
		var $mobile_nav = '';
		var $menu = jQuery( this ).parent().find( '.fusion-main-menu, .fusion-secondary-menu' ).not( '.fusion-sticky-menu' );

		if ( $menu.length ) {
			if ( js_local_vars.mobile_menu_design == 'classic' ) {
				$mobile_nav_holder.append( '<div class="fusion-mobile-selector"><span>' + js_local_vars.dropdown_goto + '</span></div>' );
				jQuery( this ).find( '.fusion-mobile-selector' ).append( '<div class="fusion-selector-down"></div>' );
			}

			jQuery( $mobile_nav_holder ).append( jQuery( $menu ).find( '> ul' ).clone() );

			$mobile_nav = jQuery( $mobile_nav_holder ).find( '> ul' );

			$mobile_nav.find( '.fusion-caret, .fusion-menu-login-box .fusion-custom-menu-item-contents, .fusion-menu-cart .fusion-custom-menu-item-contents, .fusion-main-menu-search, li> a > span > .button-icon-divider-left, li > a > span > .button-icon-divider-right' ).remove();

			if ( js_local_vars.mobile_menu_design == 'classic' ) {
				$mobile_nav.find( '.fusion-menu-cart > a' ).html( js_local_vars.mobile_nav_cart );
			} else {
				$mobile_nav.find( '.fusion-main-menu-cart' ).remove();
			}

			$mobile_nav.find( 'li' ).each(function () {
				jQuery( this ).find( '> a > .menu-text' ).removeAttr( 'class' ).addClass( 'menu-text' );

				var classes = 'fusion-mobile-nav-item';

				if( jQuery( this ).hasClass( 'current-menu-item' ) || jQuery( this ).hasClass( 'current-menu-parent' ) || jQuery( this ).hasClass( 'current-menu-ancestor' ) ) {
					classes += ' fusion-mobile-current-nav-item';
				}

				jQuery( this ).attr( 'class', classes );

				if( jQuery( this ).attr( 'id' ) ) {
					jQuery( this ).attr( 'id', jQuery( this ).attr( 'id' ).replace( 'menu-item', 'mobile-menu-item' ) );
				}

				jQuery( this ).attr( 'style', '' );
			});

			jQuery( this ).find( '.fusion-mobile-selector' ).click(function() {
				if( $mobile_nav.hasClass( 'mobile-menu-expanded' ) ) {
					$mobile_nav.removeClass( 'mobile-menu-expanded' );
				} else {
					$mobile_nav.addClass( 'mobile-menu-expanded' );
				}

				$mobile_nav.slideToggle( 200, 'easeOutQuad' );
			});
		}
	});

	jQuery( '.fusion-mobile-sticky-nav-holder' ).each(function() {
		var $mobile_nav_holder = jQuery( this );
		var $mobile_nav = '';
		var $menu = jQuery( this ).parent().find( '.fusion-sticky-menu' );

		if( js_local_vars.mobile_menu_design == 'classic' ) {
			$mobile_nav_holder.append( '<div class="fusion-mobile-selector"><span>' + js_local_vars.dropdown_goto + '</span></div>' );
			jQuery( this ).find( '.fusion-mobile-selector' ).append( '<div class="fusion-selector-down"></div>' );
		}

		jQuery( $mobile_nav_holder ).append( jQuery( $menu ).find( '> ul' ).clone() );

		$mobile_nav = jQuery( $mobile_nav_holder ).find( '> ul' );

		$mobile_nav.find( '.fusion-menu-cart, .fusion-menu-login-box, .fusion-main-menu-search' ).remove();

		$mobile_nav.find( 'li' ).each(function () {
			var classes = 'fusion-mobile-nav-item';

			if( jQuery( this ).hasClass( 'current-menu-item' ) || jQuery( this ).hasClass( 'current-menu-parent' ) || jQuery( this ).hasClass( 'current-menu-ancestor' ) ) {
				classes += ' fusion-mobile-current-nav-item';
			}

			jQuery( this ).attr( 'class', classes );

			if( jQuery( this ).attr( 'id' ) ) {
				jQuery( this ).attr( 'id', jQuery( this ).attr( 'id' ).replace( 'menu-item', 'mobile-menu-item' ) );
			}

			jQuery( this ).attr( 'style', '' );
		});

		jQuery( this ).find( '.fusion-mobile-selector' ).click(function() {
			if( $mobile_nav.hasClass( 'mobile-menu-expanded' ) ) {
				$mobile_nav.removeClass( 'mobile-menu-expanded' );
			} else {
				$mobile_nav.addClass( 'mobile-menu-expanded' );
			}

			$mobile_nav.slideToggle( 200, 'easeOutQuad' );
		});
	});

	// Make megamenu items mobile ready
	jQuery( '.fusion-mobile-nav-holder > ul > li' ).each(function() {
		jQuery( this ).find( '.fusion-megamenu-widgets-container' ).remove();

		jQuery( this ).find( '.fusion-megamenu-holder > ul' ).each( function() {
			jQuery( this ).attr( 'class', 'sub-menu' );
			jQuery( this ).attr( 'style', '' );
			jQuery( this ).find( '> li' ).each( function() {
				// add menu needed menu classes to li elements
				var classes = 'fusion-mobile-nav-item';

				if( jQuery( this ).hasClass( 'current-menu-item' ) || jQuery( this ).hasClass( 'current-menu-parent' ) || jQuery( this ).hasClass( 'current-menu-ancestor' ) || jQuery( this ).hasClass( 'fusion-mobile-current-nav-item' ) ) {
					classes += ' fusion-mobile-current-nav-item';
				}
				jQuery( this ).attr( 'class', classes );

				// Append column titles and title links correctly
				if( ! jQuery( this ).find( '.fusion-megamenu-title a, > a' ).length ) {
					jQuery( this ).find( '.fusion-megamenu-title' ).each( function() {
						if( ! jQuery( this ).children( 'a' ).length ) {
							jQuery( this ).append( '<a href="#">' + jQuery( this ).text() + '</a>' );
						}
					});

					if( ! jQuery( this ).find( '.fusion-megamenu-title' ).length ) {

						var parent_li = jQuery( this );

						jQuery( this ).find( '.sub-menu').each( function() {
							parent_li.after( jQuery( this ) );

						});
						jQuery( this ).remove();
					}
				}
				jQuery( this ).prepend( jQuery( this ).find( '.fusion-megamenu-title a, > a' ) );

				jQuery( this ).find( '.fusion-megamenu-title' ).remove();
			});
			jQuery( this ).closest( '.fusion-mobile-nav-item' ).append( jQuery( this ) );
		});

		jQuery( this ).find( '.fusion-megamenu-wrapper, .caret, .fusion-megamenu-bullet' ).remove();
	});

	// Mobile Modern Menu
	jQuery( '.fusion-mobile-menu-icons .fusion-icon-bars' ).click(function( e ) {
		e.preventDefault();

		var $wrapper;

		if( jQuery( '.fusion-header-v4').length >= 1 || jQuery( '.fusion-header-v5' ).length >= 1 ) {
			$wrapper = '.fusion-secondary-main-menu';
		} else if ( jQuery( '#side-header').length >= 1 ) {
			$wrapper = '#side-header';
		} else {
			$wrapper = '.fusion-header';
		}

		if( jQuery( '.fusion-is-sticky' ).length >= 1 && jQuery( '.fusion-mobile-sticky-nav-holder' ).length >= 1 ) {
			jQuery( $wrapper ).find( '.fusion-mobile-sticky-nav-holder' ).slideToggle( 200, 'easeOutQuad' );
		} else {
			jQuery( $wrapper ).find( '.fusion-mobile-nav-holder' ).not( '.fusion-mobile-sticky-nav-holder' ).slideToggle( 200, 'easeOutQuad' );
		}
	});

	jQuery( '.fusion-mobile-menu-icons .fusion-icon-search' ).click(function( e ) {
		e.preventDefault();

		jQuery( '.fusion-secondary-main-menu .fusion-secondary-menu-search, .side-header-wrapper .fusion-secondary-menu-search' ).slideToggle( 200, 'easeOutQuad' );
	});

	// Collapse mobile menus when on page anchors are clicked
	jQuery( '.fusion-mobile-nav-holder .fusion-mobile-nav-item a:not([href="#"])' ).click( function() {
		var $target = jQuery( this.hash );
		if ( $target.length && this.hash.slice( 1 ) !== '' ) {
			if ( jQuery( this ).parents( '.fusion-mobile-menu-design-classic' ).length ) {
				jQuery( this ).parents( '.fusion-menu, .menu' )
					.hide()
					.removeClass( 'mobile-menu-expanded' );
			} else {
				jQuery( this ).parents( '.fusion-mobile-nav-holder' ).hide();
			}
		}
	});

	// Make mobile menu sub-menu toggles
	if( js_local_vars.submenu_slideout == 1 ) {
		jQuery( '.fusion-mobile-nav-holder > ul li' ).each(function() {
			var classes = 'fusion-mobile-nav-item';

			if( jQuery( this ).hasClass( 'current-menu-item' ) || jQuery( this ).hasClass( 'current-menu-parent' ) || jQuery( this ).hasClass( 'current-menu-ancestor' ) || jQuery( this ).hasClass( 'fusion-mobile-current-nav-item' ) ) {
				classes += ' fusion-mobile-current-nav-item';
			}

			jQuery( this ).attr( 'class', classes );

			if( jQuery( this ).find( ' > ul' ).length ) {
				jQuery( this ).prepend( '<span href="#" aria-haspopup="true" class="fusion-open-submenu"></span>' );

				jQuery( this ).find( ' > ul' ).hide();
			}
		});

		jQuery( '.fusion-mobile-nav-holder .fusion-open-submenu' ).click( function(e) {
			e.stopPropagation();

			jQuery( this ).parent().children( '.sub-menu' ).slideToggle( 200, 'easeOutQuad' );
		});
	}

	// Flyout Menu
	function set_flyout_active_css() {
		jQuery( 'body' ).bind( 'touchmove', function(e){
			if ( ! jQuery( e.target ).parents( '.fusion-flyout-menu' ).length ) {
				e.preventDefault();
			}
		});

		var $wp_adminbar_height = ( jQuery( '#wpadminbar' ).length ) ? jQuery( '#wpadminbar' ).height() : 0,
			$flyout_menu_top_height = jQuery( '.fusion-header-v6-content' ).height() + $wp_adminbar_height;

		// Make usre the menu is opened in a way, that menu items do not collide with the header
		if ( jQuery( '.fusion-header-v6' ).hasClass( 'fusion-flyout-menu-active' ) ) {
			jQuery( '.fusion-header-v6 .fusion-flyout-menu' ).css({
				'height': 'calc(100% - ' + $flyout_menu_top_height + 'px)',
				'margin-top': $flyout_menu_top_height
			});

			if ( jQuery( '.fusion-header-v6 .fusion-flyout-menu .fusion-menu' ).height() > jQuery( '.fusion-header-v6 .fusion-flyout-menu' ).height() ) {
				jQuery( '.fusion-header-v6 .fusion-flyout-menu' ).css( 'display', 'block' );
			}
		}

		// Make sure logo and menu stay sticky on flyout opened, even if sticky header is disabled
		if ( js_local_vars.header_sticky == '0' ) {
			jQuery( '.fusion-header-v6 .fusion-header' ).css({
				'position': 'fixed',
				'width': '100%',
				'max-width': '100%',
				'top': $wp_adminbar_height,
				'z-index': '210'
			});

			jQuery( '.fusion-header-sticky-height' ).css({
				'display': 'block',
				'height': jQuery( '.fusion-header-v6 .fusion-header' ).height()
			});
		}
	}

	function reset_flyout_active_css() {
		setTimeout( function() {
			jQuery( '.fusion-header-v6 .fusion-flyout-menu' ).css( 'display', '' );

			if ( js_local_vars.header_sticky == '0' ) {
				jQuery( '.fusion-header-v6 .fusion-header' ).attr( 'style', '' );
				jQuery( '.fusion-header-sticky-height' ).attr( 'style', '' );
			}
			jQuery( 'body' ).unbind( 'touchmove' );
		}, 250 );
	}

	jQuery( '.fusion-flyout-menu-icons .fusion-flyout-menu-toggle' ).on( 'click', function() {
		var $flyout_content = jQuery( this ).parents( '.fusion-header-v6' );

		if ( $flyout_content.hasClass( 'fusion-flyout-active' ) ) {
			if ( $flyout_content.hasClass( 'fusion-flyout-search-active' ) ) {
				$flyout_content.addClass( 'fusion-flyout-menu-active' );

				set_flyout_active_css();
			} else {
				$flyout_content.removeClass( 'fusion-flyout-active' );
				$flyout_content.removeClass( 'fusion-flyout-menu-active' );

				reset_flyout_active_css();
			}
			$flyout_content.removeClass( 'fusion-flyout-search-active' );
		} else {
			$flyout_content.addClass( 'fusion-flyout-active' );
			$flyout_content.addClass( 'fusion-flyout-menu-active' );

			set_flyout_active_css();
		}
	});

	jQuery( '.fusion-flyout-menu-icons .fusion-flyout-search-toggle' ).on( 'click', function() {
		var $flyout_content = jQuery( this ).parents( '.fusion-header-v6' );

		if ( $flyout_content.hasClass( 'fusion-flyout-active' ) ) {
			if ( $flyout_content.hasClass( 'fusion-flyout-menu-active' ) ) {
				$flyout_content.addClass( 'fusion-flyout-search-active' );

				// Set focus on search field if not on mobiles
				if ( Modernizr.mq( 'only screen and (min-width:'  + parseInt( js_local_vars.side_header_break_point ) +  'px)' ) ) {
					$flyout_content.find( '.fusion-flyout-search .s' ).focus();
				}
			} else {
				$flyout_content.removeClass( 'fusion-flyout-active' );
				$flyout_content.removeClass( 'fusion-flyout-search-active' );

				reset_flyout_active_css();
			}
			$flyout_content.removeClass( 'fusion-flyout-menu-active' );
		} else {
			$flyout_content.addClass( 'fusion-flyout-active' );
			$flyout_content.addClass( 'fusion-flyout-search-active' );

			// Set focus on search field if not on mobiles
			if ( Modernizr.mq( 'only screen and (min-width:'  + parseInt( js_local_vars.side_header_break_point ) +  'px)' ) ) {
				$flyout_content.find( '.fusion-flyout-search .s' ).focus();
			}

			set_flyout_active_css();
		}
	});
});

jQuery( window ).load(function() {
	// Sticky Header
	if( js_local_vars.header_sticky == '1' && ( jQuery( '.fusion-header-wrapper' ).length >= 1 || jQuery( '#side-header' ).length >= 1 )  ) {
		var $animation_duration = 300;
		if( js_local_vars.sticky_header_shrinkage == '0' ) {
			$animation_duration = 0;
		}
		var $header_parent = jQuery( '.fusion-header' ).parent();
		window.$header_parent_height = $header_parent.outerHeight();
		window.$header_height = jQuery( '.fusion-header' ).outerHeight();
		var $menu_height = parseInt( js_local_vars.nav_height );
		var $menu_border_height = parseInt( js_local_vars.nav_highlight_border );
		window.$scrolled_header_height = 65;
		var $logo = ( jQuery( '.fusion-logo img:visible' ).length ) ? jQuery( '.fusion-logo img:visible' ) : '';
		var $sticky_header_scrolled = false;
		window.$sticky_trigger = jQuery( '.fusion-header' );
		window.$sticky_trigger_position = ( window.$sticky_trigger.length ) ? Math.round( window.$sticky_trigger.offset().top ) - window.$wp_adminbar_height - window.$woo_store_notice : 0;
		window.$wp_adminbar_height = ( jQuery( '#wpadminbar' ).length ) ? jQuery( '#wpadminbar' ).height() : 0;
		window.$woo_store_notice = ( jQuery( '.demo_store' ).length ) ? jQuery( '.demo_store' ).outerHeight() : 0;
		window.$sticky_header_type = 1;
		window.$logo_height, window.$main_menu_height;
		window.$slider_offset = 0;
		window.$site_width = jQuery( '#wrapper' ).outerWidth();
		window.$media_query_test_1 = Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: portrait)' ) ||  Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape)' );
		window.$media_query_test_2 = Modernizr.mq( 'screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' );
		window.$media_query_test_3 = Modernizr.mq( 'screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' );
		window.$media_query_test_4 = Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' );

		var $standard_logo_height = jQuery( '.fusion-standard-logo' ).height() + parseInt( jQuery( '.fusion-logo' ).data( 'margin-top' ) ) + parseInt( jQuery( '.fusion-logo' ).data( 'margin-bottom' ) );
		window.$initial_desktop_header_height = Math.max( window.$header_height, Math.max( $menu_height + $menu_border_height, $standard_logo_height ) + parseInt( jQuery( '.fusion-header' ).find( '.fusion-row' ).css( 'padding-top' ) ) + parseInt( jQuery( '.fusion-header' ).find( '.fusion-row' ).css( 'padding-bottom' ) ) );
		window.$initial_sticky_header_shrinkage = js_local_vars.sticky_header_shrinkage;
		window.$sticky_can_be_shrinked = true;

		if( js_local_vars.sticky_header_shrinkage == '0' ) {
			$animation_duration = 0;
			window.$scrolled_header_height = window.$header_height;
		}
		if ( $logo ) {
			// Getting the correct natural height of the visible logo
			if ( $logo.hasClass( 'fusion-logo-2x' ) ) {
				var $logo_image = new Image();
				$logo_image.src = $logo.attr( 'src' );
				window.original_logo_height = parseInt( $logo.height() ) + parseInt( js_local_vars.logo_margin_top ) + parseInt( js_local_vars.logo_margin_bottom );
			} else {
				// For normal logo we need to setup the image object to get the natural heights
				var $logo_image = new Image();
				$logo_image.src = $logo.attr( 'src' );
				window.original_logo_height = parseInt( $logo_image.naturalHeight ) + parseInt( js_local_vars.logo_margin_top ) + parseInt( js_local_vars.logo_margin_bottom );

				// IE8, Opera fallback
				$logo_image.onload = function() {
					window.original_logo_height = parseInt( this.height ) + parseInt( js_local_vars.logo_margin_top ) + parseInt( js_local_vars.logo_margin_bottom );
				};
			}
		}

		// Different sticky header behavior for header v4/v5
		// Instead of header with logo, secondary menu is made sticky
		if( jQuery( '.fusion-header-v4' ).length >= 1 || jQuery( '.fusion-header-v5' ).length >= 1 ) {
			window.$sticky_header_type = 2;
			if ( js_local_vars.header_sticky_type2_layout == 'menu_and_logo' || ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) && js_local_vars.mobile_menu_design == 'modern' ) ) {
				window.$sticky_trigger = jQuery( '.fusion-sticky-header-wrapper' );
			} else {
				window.$sticky_trigger = jQuery( '.fusion-secondary-main-menu' );
			}
			window.$sticky_trigger_position = Math.round( window.$sticky_trigger.offset().top ) - window.$wp_adminbar_height - window.$woo_store_notice;
		}

		if( window.$sticky_header_type == 1 ) {
			if( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
				window.$scrolled_header_height = window.$header_height;
			} else {
				window.$original_sticky_trigger_height = jQuery ( window.$sticky_trigger ).outerHeight();
			}
		}

		if ( window.$sticky_header_type == 2 ) {
			if ( js_local_vars.mobile_menu_design == 'classic' ) {
				jQuery( $header_parent ).height( window.$header_parent_height );
			}

			if( ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
				jQuery( $header_parent ).height( window.$header_parent_height );
			} else {
				window.$scrolled_header_height = window.$header_parent_height;
			}
		}

		// Side Header
		if( jQuery( '#side-header' ).length >= 1 ) {
			window.$sticky_header_type = 3;
		}

		if ( jQuery( document ).height() - ( window.$initial_desktop_header_height - window.$scrolled_header_height ) < jQuery( window ).height() && js_local_vars.sticky_header_shrinkage == 1 ) {
			window.$sticky_can_be_shrinked = false;
			jQuery( '.fusion-header-wrapper' ).removeClass( 'fusion-is-sticky' );
		} else {
			window.$sticky_can_be_shrinked = true;
		}

		var resize_width = jQuery(window).width();
		var resize_height = jQuery(window).height();

		jQuery( window ).resize(function() {
			window.$media_query_test_1 = Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: portrait)' ) ||  Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape)' );
			window.$media_query_test_2 = Modernizr.mq( 'screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' );
			window.$media_query_test_3 = Modernizr.mq( 'screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' );
			window.$media_query_test_4 = Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' );

			if( js_local_vars.header_sticky_tablet != '1' && ( window.$media_query_test_1 ) ) {
				jQuery( '.fusion-header-wrapper, .fusion-header-sticky-height, .fusion-header, .fusion-logo, .fusion-header-wrapper .fusion-main-menu > li a, .fusion-header-wrapper .fusion-secondary-main-menu' ).attr( 'style', '' );
				jQuery( '.fusion-header-wrapper' ).removeClass( 'fusion-is-sticky' );
			} else if( js_local_vars.header_sticky_tablet == '1' && ( window.$media_query_test_1 ) ) {
				$animation_duration = 0;
			}

			if( js_local_vars.header_sticky_mobile != '1' && window.$media_query_test_2 ) {
				jQuery( '.fusion-header-wrapper, .fusion-header-sticky-height, .fusion-header, .fusion-logo, .fusion-header-wrapper .fusion-main-menu > li a, .fusion-header-wrapper .fusion-secondary-main-menu' ).attr( 'style', '' );
				jQuery( '.fusion-header-wrapper' ).removeClass( 'fusion-is-sticky' );
			} else if( js_local_vars.header_sticky_mobile == '1' && window.$media_query_test_2 ) {
				$animation_duration = 0;
			}

			if( jQuery(window).width() != resize_width || jQuery(window).height() != resize_height ) { // check for actual resize
				var $menu_height = parseInt( js_local_vars.nav_height );
				var $menu_border_height = parseInt( js_local_vars.nav_highlight_border );

				if( jQuery( '#wpadminbar' ).length ) {
					window.$wp_adminbar_height = jQuery( '#wpadminbar' ).height();
				} else {
					window.$wp_adminbar_height = 0;
				}

				window.$woo_store_notice = ( jQuery( '.demo_store' ).length ) ? jQuery( '.demo_store' ).outerHeight() : 0;

				if ( jQuery( '.fusion-is-sticky' ).length ) {
					var $sticky_trigger = jQuery( '.fusion-header' );

					if ( window.$sticky_header_type == 2 ) {
						if ( js_local_vars.header_sticky_type2_layout == 'menu_only' && ( js_local_vars.mobile_menu_design == 'classic' || ! window.$media_query_test_4 ) ) {
							$sticky_trigger = jQuery( '.fusion-secondary-main-menu' );
						} else {
							$sticky_trigger = jQuery( '.fusion-sticky-header-wrapper' );
						}
					}

					if ( jQuery( '#wpadminbar' ).length ) {
						// Unset the top value for all candidates
						jQuery( '.fusion-header, .fusion-sticky-header-wrapper, .fusion-secondary-main-menu' ).css( 'top', '' );

						// Set top value for coreect selector
						jQuery( $sticky_trigger ).css( 'top', window.$wp_adminbar_height + window.$woo_store_notice );
					}

					if ( 'boxed' === js_local_vars.layout_mode ) {
						jQuery( $sticky_trigger ).css( 'max-width', jQuery( '#wrapper' ).outerWidth() + 'px' );
					}
				}

				// Refresh header v1, v2, v3 and v6
				if ( window.$sticky_header_type == 1 ) {
					js_local_vars.sticky_header_shrinkage = window.$initial_sticky_header_shrinkage;

					if ( jQuery( '.fusion-secondary-header' ).length ) {
						window.$sticky_trigger_position = Math.round( jQuery( '.fusion-secondary-header' ).offset().top )  - window.$wp_adminbar_height - window.$woo_store_notice + jQuery( '.fusion-secondary-header' ).outerHeight();
					// If there is no secondary header, trigger position is 0
					} else {
						window.$sticky_trigger_position = Math.round( jQuery( '.fusion-header' ).offset().top )  - window.$wp_adminbar_height - window.$woo_store_notice;
					}

					// Desktop mode
					if ( ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
						var $logo_height_with_margin = jQuery( '.fusion-logo img:visible' ).outerHeight() + parseInt( js_local_vars.logo_margin_top ) + parseInt( js_local_vars.logo_margin_bottom );
							$main_menu_width = 0;

						// Calculate actual menu width
						jQuery( '.fusion-main-menu > ul > li' ).each( function() {
							$main_menu_width += jQuery( this ).outerWidth();
						});

						if ( jQuery( '.fusion-header-v6' ).length ) {
							$main_menu_width = 0;
						}

						// Sticky desktop header
						if ( jQuery( '.fusion-is-sticky' ).length ) {
							if ( $main_menu_width > ( jQuery( '.fusion-header .fusion-row' ).width() - jQuery( '.fusion-logo img:visible' ).outerWidth() ) ) {
								window.$header_height = jQuery( '.fusion-main-menu' ).outerHeight() + $logo_height_with_margin;

								// Headers v2 and v3 have a 1px bottom border
								if ( jQuery( '.fusion-header-v2' ).length || jQuery( '.fusion-header-v3' ).length ) {
									window.$header_height += 1;
								}
							} else {
								if ( js_local_vars.sticky_header_shrinkage == '0' ) {
									if ( window.original_logo_height > $menu_height + $menu_border_height ) {
										window.$header_height = window.original_logo_height;
									} else {
										window.$header_height = $menu_height + $menu_border_height;
									}

									window.$header_height += parseInt( js_local_vars.header_padding_top ) + parseInt( js_local_vars.header_padding_bottom );

									// Headers v2 and v3 have a 1px bottom border
									if ( jQuery( '.fusion-header-v2' ).length || jQuery( '.fusion-header-v3' ).length ) {
										window.$header_height += 1;
									}
								} else {
									window.$header_height = 65;
								}
							}

							window.$scrolled_header_height = window.$header_height;

							jQuery( '.fusion-header-sticky-height' ).css( 'height', window.$header_height );
							jQuery( '.fusion-header' ).css( 'height', window.$header_height );
						// Non sticky desktop header
						} else {
							if ( $main_menu_width > ( jQuery( '.fusion-header .fusion-row' ).width() - jQuery( '.fusion-logo img:visible' ).outerWidth() ) ) {
								window.$header_height = jQuery( '.fusion-main-menu' ).outerHeight() + $logo_height_with_margin;
								js_local_vars.sticky_header_shrinkage = '0';
							} else {
								if ( window.original_logo_height > $menu_height + $menu_border_height ) {
									window.$header_height = window.original_logo_height;
								} else {
									window.$header_height = $menu_height + $menu_border_height;
								}
							}

							window.$header_height += parseInt( js_local_vars.header_padding_top ) + parseInt( js_local_vars.header_padding_bottom );

							// Headers v2 and v3 have a 1px bottom border
							if ( jQuery( '.fusion-header-v2' ).length || jQuery( '.fusion-header-v3' ).length ) {
								window.$header_height += 1;
							}

							window.$scrolled_header_height = 65;

							if( js_local_vars.sticky_header_shrinkage == '0' ) {
								window.$scrolled_header_height = window.$header_height;
							}

							jQuery( '.fusion-header-sticky-height' ).css( 'height', window.$header_height );
							jQuery( '.fusion-header' ).css( 'height', window.$header_height );
						}
					}

					// Mobile mode
					if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
						jQuery( '.fusion-header' ).css( 'height', '' );

						window.$header_height = jQuery( '.fusion-header' ).outerHeight();
						window.$scrolled_header_height = window.$header_height;

						jQuery( '.fusion-header-sticky-height' ).css( 'height', window.$scrolled_header_height );
					}
				}

				// Refresh header v4 and v5
				if ( window.$sticky_header_type == 2 ) {
					if ( js_local_vars.mobile_menu_design == 'modern' ) {
						// Desktop mode and sticky active
						if ( ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) &&
							 jQuery( '.fusion-is-sticky' ).length &&
							 js_local_vars.header_sticky_type2_layout == 'menu_only'
						) {
							window.$header_parent_height = jQuery( '.fusion-header' ).parent().outerHeight() + jQuery( '.fusion-secondary-main-menu' ).outerHeight();
						} else {
							window.$header_parent_height = jQuery( '.fusion-header' ).parent().outerHeight();
						}
						window.$scrolled_header_height = window.header_parent_height;

						// Desktop Mode
						if ( ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
							window.$header_parent_height = jQuery( '.fusion-header' ).outerHeight() + jQuery( '.fusion-secondary-main-menu' ).outerHeight();
							window.$sticky_trigger_position = Math.round( jQuery( '.fusion-header' ).offset().top )  - window.$wp_adminbar_height - window.$woo_store_notice + jQuery( '.fusion-header' ).outerHeight();

							jQuery( $header_parent ).height( window.$header_parent_height );
							jQuery( '.fusion-header-sticky-height' ).css( 'height', '' );
						}

						// Mobile Mode
						if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
							// Trigger position basis is fusion-secondary-header, if there is a secondary header
							if ( jQuery( '.fusion-secondary-header' ).length ) {
								window.$sticky_trigger_position = Math.round( jQuery( '.fusion-secondary-header' ).offset().top )  - window.$wp_adminbar_height - window.$woo_store_notice + jQuery( '.fusion-secondary-header' ).outerHeight();
							// If there is no secondary header, trigger position is 0
							} else {
								window.$sticky_trigger_position = Math.round( jQuery( '.fusion-header' ).offset().top )  - window.$wp_adminbar_height - window.$woo_store_notice;
							}

							jQuery( $header_parent ).height( '' );
							jQuery( '.fusion-header-sticky-height' ).css( 'height', jQuery( '.fusion-sticky-header-wrapper' ).outerHeight() ).hide();
						}
					}

					if ( js_local_vars.mobile_menu_design == 'classic' ) {
						window.$header_parent_height = jQuery( '.fusion-header' ).outerHeight() + jQuery( '.fusion-secondary-main-menu' ).outerHeight();
						window.$sticky_trigger_position = Math.round( jQuery( '.fusion-header' ).offset().top ) - window.$wp_adminbar_height - window.$woo_store_notice + jQuery( '.fusion-header' ).outerHeight();

						jQuery( $header_parent ).height( window.$header_parent_height );
					}
				}

				// Refresh header v3
				if ( window.$sticky_header_type == 3 ) {
					var $position_top = '';
					// Desktop mode
					if ( ! Modernizr.mq( 'only screen and (max-width:' + js_local_vars.side_header_break_point + 'px)' ) ) {
						jQuery( '#side-header-sticky' ).css({
							height: '',
							top: ''
						});

						if ( jQuery( '#side-header' ).hasClass( 'fusion-is-sticky' ) ) {
							jQuery( '#side-header' ).css({
								top: ''
							});

							jQuery( '#side-header' ).removeClass( 'fusion-is-sticky' );
						}
					}
				}

				if ( jQuery( document ).height() - ( window.$initial_desktop_header_height - window.$scrolled_header_height ) < jQuery( window ).height() && js_local_vars.sticky_header_shrinkage == 1 ) {
					window.$sticky_can_be_shrinked = false;
					jQuery( '.fusion-header-wrapper' ).removeClass( 'fusion-is-sticky' );
					jQuery( '.fusion-header-sticky-height' ).hide();
					jQuery( '.fusion-header' ).css( 'height', '' );

					jQuery( '.fusion-logo' ).css({
						'margin-top': '',
						'margin-bottom': ''
					});

					jQuery( '.fusion-main-menu > ul > li > a' ).css({
						'height': '',
						'line-height': ''
					});

					jQuery( '.fusion-logo img' ).css( 'height', '' );
				} else {
					window.$sticky_can_be_shrinked = true;

					// Resizing sticky header
					if( jQuery( '.fusion-is-sticky' ).length >= 1 ) {
						if( window.$sticky_header_type == 1 && ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
							// Animate Header Height
							if( ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
								if ( window.$header_height == window.$initial_desktop_header_height ) {
									jQuery( window.$sticky_trigger ).stop(true, true).animate({
										height: window.$scrolled_header_height
									}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
										jQuery(this).css( 'overflow', 'visible' );
									} });
									jQuery( '.fusion-header-sticky-height' ).show();
									jQuery( '.fusion-header-sticky-height' ).stop(true, true).animate({
										height: window.$scrolled_header_height
									}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
										jQuery(this).css( 'overflow', 'visible' );
									} });
								} else {
									jQuery( '.fusion-header-sticky-height' ).show();
								}
							} else {
								jQuery( '.fusion-header-sticky-height' ).css( 'height', window.$scrolled_header_height ).show();
							}

							// Animate Logo
							if( js_local_vars.sticky_header_shrinkage == '1' && window.$header_height == window.$initial_desktop_header_height ) {
								if( $logo ) {
									var $scrolled_logo_height = $logo.height();

									if(  $scrolled_logo_height < window.$scrolled_header_height - 10 ) {
										var $scrolled_logo_container_margin = ( window.$scrolled_header_height - $scrolled_logo_height ) / 2;
									} else {
										$scrolled_logo_height = window.$scrolled_header_height - 10;
										var $scrolled_logo_container_margin = 5;
									}

									$logo.stop(true, true).animate({
										'height': $scrolled_logo_height
									}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
										jQuery(this).css( 'display', '' );
									}, step: function() {
										jQuery(this).css( 'display', '' );
									} });
								}

								jQuery( '.fusion-logo' ).stop(true, true).animate({
									'margin-top': $scrolled_logo_container_margin,
									'margin-bottom': $scrolled_logo_container_margin
								}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic' });

								// Animate Menu Height
								if ( ! jQuery( '.fusion-header-v6' ).length ) {
									jQuery( '.fusion-main-menu > ul > li > a' ).stop(true, true).animate({
										height: window.$scrolled_header_height - $menu_border_height,
										'line-height': window.$scrolled_header_height - $menu_border_height
									}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic' });
								}
							}
						}
					}
				}

				resize_width = jQuery(window).width();
				resize_height = jQuery(window).height();
			}
		}); // end resize event


		jQuery( window ).scroll(function() {

			if ( window.$sticky_can_be_shrinked ) {
				if( js_local_vars.header_sticky_tablet != '1' && ( window.$media_query_test_1 ) ) {
					return;
				} else if( js_local_vars.header_sticky_tablet == '1' && ( window.$media_query_test_1 ) ) {
					$animation_duration = 0;
				}

				if( js_local_vars.header_sticky_mobile != '1' && window.$media_query_test_2 ) {
					return;
				} else if( js_local_vars.header_sticky_mobile == '1' && window.$media_query_test_2 ) {
					$animation_duration = 0;
				}

				if( window.$sticky_header_type == 3 && js_local_vars.header_sticky_mobile != '1' ) {
					return;
				}

				if( window.$sticky_header_type == 3 && js_local_vars.header_sticky_mobile == '1' && ! window.$media_query_test_3 ) {
					return;
				}

				// Change the sticky trigger position to the bottom of the mobile menu
				if( jQuery( '.fusion-is-sticky' ).length == 0 && jQuery( '.fusion-header, .fusion-secondary-main-menu' ).find( '.fusion-mobile-nav-holder > ul' ).is( ':visible' ) ) {
					window.$sticky_trigger_position = Math.round( jQuery( '.fusion-header, .fusion-sticky-header-wrapper' ).find( '.fusion-mobile-nav-holder:visible' ).offset().top ) - window.$wp_adminbar_height - window.$woo_store_notice + jQuery( '.fusion-header, .fusion-sticky-header-wrapper' ).find( '.fusion-mobile-nav-holder:visible' ).height();
				}

				// If sticky header is not active, reassign the triggers
				if( window.$sticky_header_type != 3 && jQuery( '.fusion-is-sticky' ).length == 0 && ! jQuery( '.fusion-header, .fusion-secondary-main-menu' ).find( '.fusion-mobile-nav-holder > ul' ).is( ':visible' ) ) {
					window.$sticky_trigger = jQuery( '.fusion-header' );
					window.$sticky_trigger_position = Math.round( window.$sticky_trigger.offset().top )  - window.$wp_adminbar_height - window.$woo_store_notice;

					if( window.$sticky_header_type == 2 ) {
						if ( js_local_vars.header_sticky_type2_layout == 'menu_and_logo' || ( window.$media_query_test_4 && js_local_vars.mobile_menu_design == 'modern' ) ) {
							window.$sticky_trigger = jQuery( '.fusion-sticky-header-wrapper' );
						} else {
							window.$sticky_trigger = jQuery( '.fusion-secondary-main-menu' );
						}
						window.$sticky_trigger_position = Math.round( window.$sticky_trigger.offset().top )  - window.$wp_adminbar_height - window.$woo_store_notice;
					}

					// set sticky header height for header v4 and v5
					if( js_local_vars.mobile_menu_design == 'modern' && window.$sticky_header_type == 2 && ( window.$media_query_test_4 || js_local_vars.header_sticky_type2_layout == 'menu_and_logo' ) ) {
						// Refresh header height on scroll
						window.$header_height = jQuery( window.$sticky_trigger ).outerHeight();
						window.$scrolled_header_height = window.$header_height;
						jQuery( '.fusion-header-sticky-height' ).css( 'height', window.$scrolled_header_height ).show();
					}
				}

				if( jQuery( window ).scrollTop() > window.$sticky_trigger_position ) { // sticky header mode
					if( $sticky_header_scrolled == false ) {
						var $wp_adminbar_height = 0;
						var $woo_store_notice = ( jQuery( '.demo_store' ).length ) ? jQuery( '.demo_store' ).outerHeight() : 0;

						if ( jQuery( '#wpadminbar' ).length ) {
							$wp_adminbar_height = jQuery( '#wpadminbar' ).height();
						}



						jQuery( '.fusion-header-wrapper' ).addClass( 'fusion-is-sticky' );
						jQuery( window.$sticky_trigger ).css( 'top', $wp_adminbar_height + $woo_store_notice );
						$logo = jQuery( '.fusion-logo img:visible' );

						// Hide all mobile menus
						if( js_local_vars.mobile_menu_design == 'modern' ) {
							jQuery( '.fusion-header, .fusion-secondary-main-menu' ).find( '.fusion-mobile-nav-holder' ).hide();
							jQuery( '.fusion-secondary-main-menu .fusion-main-menu-search .fusion-custom-menu-item-contents' ).hide();
						} else {
							jQuery( '.fusion-header, .fusion-secondary-main-menu' ).find( '.fusion-mobile-nav-holder > ul' ).hide();
						}

						if( js_local_vars.mobile_menu_design == 'modern' ) {
							// hide normal mobile menu if sticky menu is set in sticky header
							if( jQuery( '.fusion-is-sticky' ).length >= 1 && jQuery( '.fusion-mobile-sticky-nav-holder' ).length >= 1 && jQuery( '.fusion-mobile-nav-holder' ).is( ':visible' ) ) {
								jQuery( '.fusion-mobile-nav-holder' ).not( '.fusion-mobile-sticky-nav-holder' ).hide();
							}
						}

						if( js_local_vars.layout_mode == 'boxed' ) {
							jQuery( window.$sticky_trigger ).css( 'max-width', jQuery( '#wrapper' ).outerWidth() );
						}

						if( window.$sticky_header_type == 1 ) {
							// Animate Header Height

							if( ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
								if ( window.$header_height == window.$initial_desktop_header_height ) {
									jQuery( window.$sticky_trigger ).stop( true, true ).animate({
										height: window.$scrolled_header_height
									}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
										jQuery( this ).css( 'overflow', 'visible' );
									} });

									jQuery( '.fusion-header-sticky-height' ).show();
									jQuery( '.fusion-header-sticky-height' ).stop( true, true ).animate({
										height: window.$scrolled_header_height
									}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
										jQuery( this ).css( 'overflow', 'visible' );
									} });
								} else {
									jQuery( '.fusion-header-sticky-height' ).show();
								}
							} else {
								jQuery( '.fusion-header-sticky-height' ).css( 'height', window.$scrolled_header_height ).show();
							}

							// Add sticky shadow
							setTimeout( function() {
								jQuery( '.fusion-header' ).addClass( 'fusion-sticky-shadow' );
							}, 150 );

							if( js_local_vars.sticky_header_shrinkage == '1' && window.$header_height == window.$initial_desktop_header_height ) {
								// Animate header padding
								jQuery( window.$sticky_trigger ).find( '.fusion-row' ).stop( true, true ).animate({
									'padding-top': 0,
									'padding-bottom': 0
								}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic' });

								// Animate Logo
								if( $logo ) {
									var $scrolled_logo_height = $logo.height();

									$logo.attr( 'data-logo-height', $logo.height() );
									$logo.attr( 'data-logo-width', $logo.width() );

									if(  $scrolled_logo_height < window.$scrolled_header_height - 10 ) {
										var $scrolled_logo_container_margin = ( window.$scrolled_header_height - $scrolled_logo_height ) / 2;
									} else {
										$scrolled_logo_height = window.$scrolled_header_height - 10;
										var $scrolled_logo_container_margin = 5;
									}

									$logo.stop( true, true ).animate({
										'height': $scrolled_logo_height
									}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
										jQuery( this ).css( 'display', '' );
									}, step: function() {
										jQuery( this ).css( 'display', '' );
									} });
								}

								jQuery( '.fusion-logo' ).stop( true, true ).animate({
									'margin-top': $scrolled_logo_container_margin,
									'margin-bottom': $scrolled_logo_container_margin
								}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic' });

								// Animate Menu Height
								if ( ! jQuery( '.fusion-header-v6' ).length ) {
									jQuery( '.fusion-main-menu > ul > li > a' ).stop( true, true ).animate({
										height: window.$scrolled_header_height - $menu_border_height,
										'line-height': window.$scrolled_header_height - $menu_border_height
									}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic' });
								}
							}

						}

						if ( window.$sticky_header_type == 2 ) {
							if ( js_local_vars.header_sticky_type2_layout == 'menu_and_logo' ) {
								jQuery( window.$sticky_trigger ).css( 'height', '' );

								// Refresh header height on scroll
								window.$header_height = jQuery( window.$sticky_trigger ).outerHeight();
								window.$scrolled_header_height = window.$header_height;
								jQuery( window.$sticky_trigger ).css( 'height', window.$scrolled_header_height );
								jQuery( '.fusion-header-sticky-height' ).css( 'height', window.$scrolled_header_height );
							}

							jQuery( '.fusion-header-sticky-height' ).show();
						}

						if( window.$sticky_header_type == 3 && Modernizr.mq( 'only screen and (max-width:' + js_local_vars.side_header_break_point + 'px)' ) ) {
							jQuery( '#side-header-sticky' ).css({
								height: jQuery( '#side-header' ).outerHeight()
							});

							jQuery( '#side-header' ).css({
								position: 'fixed',
								top: $wp_adminbar_height + $woo_store_notice
							}).addClass( 'fusion-is-sticky' );
						}

						$sticky_header_scrolled = true;
					}
				} else if( jQuery( window ).scrollTop() <= window.$sticky_trigger_position ) {
					jQuery( '.fusion-header-wrapper' ).removeClass( 'fusion-is-sticky' );
					jQuery( '.fusion-header' ).removeClass( 'fusion-sticky-shadow' );
					$logo = jQuery( '.fusion-logo img:visible' );

					if( js_local_vars.mobile_menu_design == 'modern' ) {
						// hide sticky menu if sticky menu is set in normal header
						if( jQuery( '.fusion-is-sticky' ).length == 0 && jQuery( '.fusion-mobile-sticky-nav-holder' ).length >= 1 && jQuery( '.fusion-mobile-nav-holder' ).is( ':visible' ) ) {
							jQuery( '.fusion-mobile-sticky-nav-holder' ).hide();
						}
					}

					if( window.$sticky_header_type == 1 ) {
						// Animate Header Height to Original Size
						if( ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
							// Done to make sure that resize event while sticky is active doesn't lead to no animation on scroll up
							if ( window.$sticky_header_type == 1 && window.$header_height == 65 ) {
								window.$header_height = window.$initial_desktop_header_height;
							}

							if ( window.$header_height == window.$initial_desktop_header_height ) {
								jQuery( window.$sticky_trigger ).stop( true, true ).animate({
									height: window.$header_height
								}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
									jQuery( this ).css( 'overflow', 'visible' );
								}, step: function() {
									jQuery( this ).css( 'overflow', 'visible' );
								} });

								jQuery( '.fusion-header-sticky-height' ).stop( true, true ).animate({
									height: window.$header_height
								}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
									jQuery( this ).css( 'overflow', 'visible' );
								}, step: function() {
									jQuery( this ).css( 'overflow', 'visible' );
								} });
							}
							jQuery( '.fusion-header-sticky-height' ).hide();
						} else {
							jQuery( '.fusion-header-sticky-height' ).hide().css( 'height', window.$header_height + $menu_border_height );
						}

						if( js_local_vars.sticky_header_shrinkage == '1' && window.$header_height == window.$initial_desktop_header_height ) {
							// Animate header padding to Original Size
							jQuery( window.$sticky_trigger ).find( '.fusion-row' ).stop( true, true ).animate({
								'padding-top': js_local_vars.header_padding_top,
								'padding-bottom': js_local_vars.header_padding_bottom
							}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic' });

							// Animate Logo to Original Size
							if( $logo ) {
								$logo.stop( true, true ).animate({
									'height': $logo.data( 'logo-height' )
								}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic', complete: function() {
									jQuery( this ).css( 'display', '' );
									jQuery( '.fusion-sticky-logo-1x, .fusion-sticky-logo-2x' ).css( 'height', '' );
								} });
							}

							jQuery( '.fusion-logo' ).stop( true, true ).animate({
								'margin-top': jQuery('.fusion-logo').data('margin-top'),
								'margin-bottom': jQuery('.fusion-logo').data('margin-bottom')
							}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic' });

							// Animate Menu Height to Original Size
							if ( ! jQuery( '.fusion-header-v6' ).length ) {
								jQuery( '.fusion-main-menu > ul > li > a' ).stop( true, true ).animate({
									height: $menu_height,
									'line-height': $menu_height
								}, { queue: false, duration: $animation_duration, easing: 'easeOutCubic' });
							}
						}
					}

					if( window.$sticky_header_type == 2 ) {
						jQuery( '.fusion-header-sticky-height' ).hide();

						if ( js_local_vars.header_sticky_type2_layout == 'menu_and_logo' ) {
							jQuery( window.$sticky_trigger ).css( 'height', '' );

							// Refresh header height on scroll
							window.$header_height = jQuery( window.$sticky_trigger ).outerHeight();
							window.$scrolled_header_height = window.$header_height;
							jQuery( window.$sticky_trigger ).css( 'height', window.$scrolled_header_height );
							jQuery( '.fusion-header-sticky-height' ).css( 'height', window.$scrolled_header_height );
						}


					}

					if( window.$sticky_header_type == 3 && Modernizr.mq( 'only screen and (max-width:' + js_local_vars.side_header_break_point + 'px)' ) ) {
						jQuery( '#side-header-sticky' ).css({
							height: ''
						});

						jQuery( '#side-header' ).css({
							'position': ''
						}).removeClass( 'fusion-is-sticky' );
					}

					$sticky_header_scrolled = false;
				}

			}
		});

		jQuery( window ).trigger( 'scroll' ); // trigger scroll for page load


	}

	// adjust mobile menu when it falls to 2 rows
	var mobile_menu_sep_added = false;

	function adjust_mobile_menu_settings() {
		var menu_width = 0;

		if( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
			jQuery( '.fusion-secondary-menu > ul' ).children( 'li' ).each( function() {
				menu_width += jQuery( this ).outerWidth( true ) + 2;
			});

			if( menu_width > jQuery( window ).width() && jQuery( window ).width() > 318 ) {
				if( ! mobile_menu_sep_added ) {
					jQuery( '.fusion-secondary-menu > ul' ).append( '<div class="fusion-mobile-menu-sep"></div>' );
					jQuery( '.fusion-secondary-menu > ul' ).css( 'position', 'relative' );
					jQuery( '.fusion-mobile-menu-sep' ).css( {
						'position': 'absolute',
						'top': jQuery( '.fusion-secondary-menu > ul > li' ).height() - 1 + 'px',
						'width': '100%',
						'border-bottom-width': '1px',
						'border-bottom-style': 'solid'
					});
					mobile_menu_sep_added = true;
				}
			} else {
				jQuery( '.fusion-secondary-menu > ul' ).css( 'position', '' );
				jQuery( '.fusion-secondary-menu > ul' ).find( '.fusion-mobile-menu-sep' ).remove();
				mobile_menu_sep_added = false;
			}
		} else {
			jQuery( '.fusion-secondary-menu > ul' ).css( 'position', '' );
			jQuery( '.fusion-secondary-menu > ul' ).find( '.fusion-mobile-menu-sep' ).remove();
			mobile_menu_sep_added = false;
		}
	}

	adjust_mobile_menu_settings();

	jQuery( window ).on( 'resize', function() {
		adjust_mobile_menu_settings();
	});
});

// Reintalize scripts after ajax
jQuery( document ).ajaxComplete( function() {
	jQuery( window ).trigger( 'scroll' ); // trigger scroll for page load

	if( jQuery( '.fusion-is-sticky' ).length >= 1 && window.$sticky_trigger && window.$sticky_header_type != 3 ) {
		var $sticky_trigger = jQuery( window.$sticky_trigger ),
			$menu_border_height = parseInt( js_local_vars.nav_highlight_border ),
			$menu_height = $sticky_trigger.height() - $menu_border_height;

		if ( window.$sticky_header_type == 2 ) {
			$sticky_trigger = jQuery( '.fusion-secondary-main-menu' );
			$menu_height = $sticky_trigger.find( '.fusion-main-menu > ul > li > a' ).height();
		}

		jQuery( '.fusion-main-menu > ul > li > a' ).css({
			height: $menu_height + 'px',
			'line-height': $menu_height + 'px'
		});
	}
});
;var generate_carousel = function() {
	if ( jQuery().carouFredSel ) {
		jQuery( '.fusion-carousel' ).each( function() {
			// Initialize the needed variables from data fields
			var $image_size = ( jQuery( this ).attr( 'data-imagesize' ) ) ? jQuery( this ).data( 'imagesize' ) : 'fixed',
				$center_vertically = ( jQuery( this ).attr( 'data-metacontent' ) && jQuery( this ).data( 'metacontent' ) == 'yes' ) ? false : true,
				$autoplay = ( jQuery( this ).attr( 'data-autoplay' ) && jQuery( this ).data( 'autoplay' ) == 'yes' ) ? true : false,
				$timeout_duration = ( jQuery( this ).parents( '.related-posts' ).length ) ? js_local_vars.related_posts_speed : js_local_vars.carousel_speed,
				$scroll_effect = ( jQuery( this ).attr( 'data-scrollfx' ) ) ? jQuery( this ).data( 'scrollfx' ) : 'scroll',
				$scroll_items = ( jQuery( this ).attr( 'data-scrollitems' ) ) ? jQuery( this ).data( 'scrollitems' ) : null,
				$touch_scroll = ( jQuery( this ).attr( 'data-touchscroll' ) && jQuery( this ).data( 'touchscroll' ) == 'yes' ) ? true : false,
				$touch_scroll_class = ( $touch_scroll ) ? ' fusion-carousel-swipe' : '',
				$column_maximum = ( jQuery( this ).attr( 'data-columns' ) ) ? jQuery( this ).data( 'columns' ) : 6,
				$item_margin = ( jQuery( this ).attr( 'data-itemmargin' ) ) ? parseInt( jQuery( this ).data( 'itemmargin' ) ) : 44,
				$item_min_width = ( jQuery( this ).attr( 'data-itemwidth' ) ) ? parseInt( jQuery( this ).data( 'itemwidth' ) )  + $item_margin : 180 + $item_margin,
				$carousel_width = jQuery( this ).width(),
				$carousel_height = ( jQuery ( this ).parent().hasClass( 'fusion-image-carousel' ) && $image_size == 'fixed' ) ? '115px' : 'variable',
				$max_number_of_items = Math.floor( $carousel_width / $item_min_width );

			// Shift the wrapping positioning container $item_margin to the left
			jQuery( this ).find( '.fusion-carousel-positioner' ).css( 'margin-left', '-' + $item_margin + 'px' );

			// Add $item_margin as left margin to all items
			jQuery( this ).find( '.fusion-carousel-item' ).css( 'margin-left', $item_margin  + 'px' );

			// Shift the left navigation button $item_margin to the right
			jQuery( this ).find( '.fusion-nav-prev' ).css( 'margin-left', $item_margin + 'px' );

			// Initialize the carousel
			jQuery( this ).find( 'ul' ).carouFredSel({
				circular: true,
				infinite: true,
				responsive: true,
				centerVertically: $center_vertically,
				height: $carousel_height,
				width: '100%',
				auto: {
					play: $autoplay,
					timeoutDuration: parseInt( $timeout_duration )
				},
				items: {
					height: $carousel_height,
					width: $item_min_width,
					visible: {
						min: 1,
						max: $column_maximum
					}
				},
				scroll: {
					pauseOnHover: true,
					items: $scroll_items,
					fx: $scroll_effect,
				},
				swipe: {
					onTouch: $touch_scroll,
					onMouse: $touch_scroll,
					options: {
						excludedElements: 'button, input, select, textarea, a, .noSwipe',
					},
				},
				prev: jQuery( this ).find( '.fusion-nav-prev' ),
				next: jQuery( this ).find( '.fusion-nav-next' ),
				onCreate: function( data ) {
					// Make the images visible once the carousel is loaded
					jQuery( this ).find( '.fusion-carousel-item-wrapper' ).css( 'visibility', 'visible' );

					// Make the navigation visible once the carousel is loaded
					jQuery( this ).parents( '.fusion-carousel' ).find( '.fusion-carousel-nav' ).css( 'visibility', 'visible' );

					// Remove overflow: hidden to  make carousel stretch full width
					if ( jQuery( this ).parents( '.fusion-woo-featured-products-slider' ).length ) {
						jQuery( this ).parent().css( 'overflow', '' );
					}

					// Set the line-height of the main ul element to the height of the wrapping container
					if ( $center_vertically ) {
						jQuery( this ).css( 'line-height', jQuery( this ).parent().height() + 'px' );
					}

					// Set the ul element to top: auto position to make is respect top padding
					jQuery( this ).css( 'top', 'auto' );

					// Set the position of the right navigation element to make it fit the overall carousel width
					jQuery( this ).parents( '.fusion-carousel' ).find( '.fusion-nav-next' ).each( function() {
						jQuery( this ).css( 'left', jQuery( this ).parents( '.fusion-carousel' ).find( '.fusion-carousel-wrapper' ).width() - jQuery( this ).width() );
					});

					// Resize the placeholder images correctly in "fixed" picture size carousels
					if ( $image_size == 'fixed' ) {
						jQuery( this ).find( '.fusion-placeholder-image' ).each( function() {
							jQuery( this ).css(	'height', jQuery( this ).parents( '.fusion-carousel-item' ).siblings().first().find( 'img' ).height() );

						});
					}

					jQuery( window ).trigger( 'resize' );
				},
				currentVisible: function( $items ) {
					return $items;
				},
			}, {
				// Set custom class name to the injected carousel container
				wrapper: {
					classname: 'fusion-carousel-wrapper' + $touch_scroll_class,
				}
			});
		});
	}
};

var fusion_reanimate_slider = function( content_container ) {
	var slide_content = content_container.find( '.slide-content' );

	jQuery( slide_content ).each( function() {

		jQuery(this).stop( true, true );

		jQuery(this).css('opacity', '0');
		jQuery(this).css('margin-top', '50px');

		jQuery(this).animate({
			'opacity': '1',
			'margin-top': '0'
		}, 1000 );

	});
};

// Calculate the responsive type values for font size and line height for all heading tags
var fusion_calculate_responsive_type_values = function( $custom_sensitivity, $custom_minimum_font_size_factor, $custom_mobile_break_point, $elements ) {

    // Setup options
    var $sensitivity = $custom_sensitivity || 1,
    	$minimum_font_size_factor = $custom_minimum_font_size_factor || 1.5,
		$body_font_size = parseInt( jQuery( "body" ).css( 'font-size' ) ),
    	$minimum_font_size = $body_font_size * $minimum_font_size_factor,
    	$mobile_break_point = ( $custom_mobile_break_point || $custom_mobile_break_point === 0 ) ? $custom_mobile_break_point : 800;

    var calculate_values = function() {
		// Get the site width for responsive type
		if ( jQuery( window ).width() >= $mobile_break_point ) {
			// Get px based site width from Theme Options
			if ( js_local_vars.site_width.indexOf( 'px' ) ) {
				var $site_width = parseInt( js_local_vars.site_width );
			// If site width is percentage based, use default site width
			} else {
				var $site_width = 1100;
			}
		// If we are below $mobile_break_point of viewport width, set $mobile_break_point as site width
		} else {
			var $site_width = $mobile_break_point;
		}

		// The resizing factor can be finetuned through a custom sensitivity; values below 1 decrease resizing speed
		var $window_site_width_ratio = jQuery( window ).width() / $site_width,
			$resize_factor = 1 - ( ( 1 - $window_site_width_ratio ) * $sensitivity );

		// If window width is smaller than site width then let's adjust the headings
		if ( jQuery( window ).width() <= $site_width ) {

			// Loop over all heading tegs
			jQuery( $elements ).each(
				function() {
					// Only decrease font-size if the we stay above $minimum_font_size
					if ( jQuery( this ).data( 'fontsize' ) * $resize_factor > $minimum_font_size ) {
						jQuery( this ).css( {
							'font-size': Math.round( jQuery( this ).data( 'fontsize' ) * $resize_factor * 1000 ) / 1000,
							'line-height': ( Math.round( jQuery( this ).data( 'lineheight' ) * $resize_factor * 1000 ) / 1000 ) + 'px'
						});
					// If decreased font size would become too small, natural font size is above $minimum_font_size, set font size to $minimum_font_size
					} else if ( jQuery( this ).data( 'fontsize' ) > $minimum_font_size ) {
						jQuery( this ).css( {
							'font-size': $minimum_font_size,
							'line-height': ( Math.round( jQuery( this ).data( 'lineheight' ) * $minimum_font_size / jQuery( this ).data( 'fontsize' ) * 1000 ) / 1000 ) + 'px'
						});
					}
				}
			);
		// If window width is larger than site width, delete any resizing styles
		} else {
			jQuery( $elements ).each(
				function() {
					// If initially an inline font size was set, restore it
					if ( jQuery( this ).data( 'inline-fontsize' ) ) {
						jQuery( this ).css( 'font-size', jQuery( this ).data( 'fontsize' ) );
					// Otherwise remove inline font size
					} else {
						jQuery( this ).css( 'font-size', '' );
					}
					// If initially an inline line height was set, restore it
					if ( jQuery( this ).data( 'inline-lineheight' ) ) {
						jQuery( this ).css( 'line-height', jQuery( this ).data( 'lineheight' ) + 'px' );
					// Otherwise remove inline line height
					} else {
						jQuery( this ).css( 'line-height', '' );
					}

				}
			);
		}
	};

	calculate_values();

	jQuery( window ).on( 'resize orientationchange', calculate_values );
};

$top = $bottom = false;
$last_window_position = 0;
$last_window_height = jQuery( window ).height();

function fusion_side_header_scroll() {
	var $media_query_ipad = Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: portrait)' ) ||  Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape)' );

	if ( ! $media_query_ipad ) {
		var $document_height = jQuery( document ).height(),
			$window_position = jQuery( window ).scrollTop(),
			$window_height = jQuery( window ).height(),
			$body_height = jQuery( 'body' ).height(),
			$adminbar_height = jQuery( '#wpadminbar' ).height(),
			$side_header = jQuery( '#side-header' ),
			$side_header_wrapper = jQuery( '.side-header-wrapper' ),
			$side_header_height = $side_header_wrapper.outerHeight(),
			$boxed_wrapper_offset = 0;

		if ( jQuery( 'body' ).hasClass( 'layout-boxed-mode' ) && jQuery( 'body' ).hasClass( 'side-header-right' ) ) {
			$side_header = jQuery( '.side-header-wrapper' );
			$boxed_wrapper_offset = jQuery( '#boxed-wrapper' ).offset().top;
		}

		if ( Modernizr.mq( 'only screen and (max-width:' + js_local_vars.side_header_break_point + 'px)' ) ) {

			if ( ! $side_header.hasClass( 'fusion-is-sticky' ) ) {
				$side_header.css({
					'bottom': '',
					'position': ''
				});
			}

			return;
		}

		if ( $side_header_height + $adminbar_height > $window_height ) {
			$side_header.css( 'height', 'auto' );
			if ( $window_position > $last_window_position ) {
				if ( $top ) {
					$top = false;
					$top_offset = ( $side_header_wrapper.offset().top > 0 ) ? $side_header_wrapper.offset().top - $boxed_wrapper_offset : $adminbar_height;
					$side_header.attr( 'style', 'top: ' + $top_offset + 'px; height: auto;' );
				} else if ( ! $bottom && $window_position + $window_height > $side_header_height + $side_header_wrapper.offset().top && $side_header_height + $adminbar_height < $body_height ) {
					$bottom = true;
					$side_header.attr( 'style', 'position: fixed; bottom: 0; top: auto; height: auto;' );
				}
			} else if ( $window_position < $last_window_position ) {
				if ( $bottom ) {
					$bottom = false;
					$top_offset = ( $side_header_wrapper.offset().top > 0 ) ? $side_header_wrapper.offset().top - $boxed_wrapper_offset : $adminbar_height;
					$side_header.attr( 'style', 'top: ' + $top_offset + 'px; height: auto;' );
				} else if ( ! $top && $window_position + $adminbar_height < $side_header_wrapper.offset().top ) {
					$top = true;
					$side_header.attr( 'style', 'position: fixed; height: auto;' );
				}
			} else {
				$top = $bottom = false;

				$top_offset = ( $side_header_wrapper.offset().top > 0 ) ? $side_header_wrapper.offset().top - $boxed_wrapper_offset : $adminbar_height;
				if ( $window_height > $last_window_height && $body_height > $side_header_wrapper.offset().top  + $boxed_wrapper_offset + $side_header_height && $window_position + $window_height > $side_header_wrapper.offset().top + $side_header_height ) {
					$top_offset += $window_height - $last_window_height;
				}
				$side_header.attr( 'style', 'top:' + $top_offset + 'px; height: auto;' );
			}
		} else {
			$top = true;
			$side_header.attr( 'style', 'position: fixed;' );
		}

		$last_window_position = $window_position;
		$last_window_height = $window_height;
	}
}

function add_styles_for_old_ie_versions() {

	// IE10
	if ( cssua.ua.ie == '10.0' ) {
		jQuery( 'head' ).append('<style type="text/css">.layout-boxed-mode .fusion-footer-parallax { left: auto; right: auto; }.fusion-imageframe,.imageframe-align-center{font-size: 0px; line-height: normal;}.fusion-button.button-pill,.fusion-button.button-pill:hover{filter: none;}.fusion-header-shadow:after, body.side-header-left .header-shadow#side-header:before, body.side-header-right .header-shadow#side-header:before{ display: none }.search input,.searchform input {padding-left:10px;} .avada-select-parent .select-arrow,.select-arrow{height:33px;background-color:' + js_local_vars.form_bg_color + '}.search input{padding-left:5px;}header .tagline{margin-top:3px;}.star-rating span:before {letter-spacing: 0;}.avada-select-parent .select-arrow,.gravity-select-parent .select-arrow,.wpcf7-select-parent .select-arrow,.select-arrow{background: #fff;}.star-rating{width: 5.2em;}.star-rating span:before {letter-spacing: 0.1em;}</style>');
	}

	// IE11
	if ( cssua.ua.ie == '11.0' ) {
		jQuery( 'head' ).append('<style type="text/css">.layout-boxed-mode .fusion-footer-parallax { left: auto; right: auto; }</style>');
	}
}

// Get WP admin bar height
function get_adminbar_height() {
	var $adminbar_height = 0;


	if ( jQuery( '#wpadminbar' ).length ) {
		$adminbar_height = parseInt( jQuery( '#wpadminbar' ).outerHeight() );
	}

	return $adminbar_height;
}

// Get current height of sticky header
function get_sticky_header_height() {
	var $sticky_header_type = 1,
		$sticky_header_height = 0,
		$media_query_ipad = Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: portrait)' ) ||  Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape)' );

	// Set header type to 2 for headers v4, v5
	if ( jQuery( '.fusion-header-v4' ).length || jQuery( '.fusion-header-v5' ).length ) {
		$sticky_header_type = 2;
	}

	// Sticky header is enabled
	if ( js_local_vars.header_sticky == '1' && jQuery( '.fusion-header-wrapper' ).length ) {
		// Desktop mode - headers v1, v2, v3
		if ( $sticky_header_type == 1 ) {
			$sticky_header_height = jQuery( '.fusion-header' ).outerHeight() - 1;

			// For headers v1 - v3 the sticky header min height is always 65px
			if ( $sticky_header_height < 64 ) {
				$sticky_header_height = 64;
			}

		// Desktop mode - headers v4, v5
		} else {
			$sticky_header_height = jQuery( '.fusion-secondary-main-menu' ).outerHeight();

			if ( js_local_vars.header_sticky_type2_layout == 'menu_and_logo' ) {
				$sticky_header_height += jQuery( '.fusion-header' ).outerHeight();
			}
		}

		// Mobile mode
		if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {

			// Sticky header is enabled on mobile
			if ( js_local_vars.header_sticky_mobile == '1' ) {
				// Classic mobile menu
				if ( jQuery( '.fusion-mobile-menu-design-classic' ).length ) {
					$sticky_header_height = jQuery( '.fusion-secondary-main-menu' ).outerHeight();
				}

				// Modern mobile menu
				if ( jQuery( '.fusion-mobile-menu-design-modern' ).length ) {
					$sticky_header_height = jQuery( '.fusion-header' ).outerHeight();
				}
			// Sticky header is disabled on mobile
			} else {
				$sticky_header_height = 0;
			}
		}

		// Tablet mode
		if ( js_local_vars.header_sticky_tablet != '1' && $media_query_ipad ) {
			$sticky_header_height = 0;
		}
	}

	return $sticky_header_height;
}

// Calculate height of sticky header on page load
function get_waypoint_top_offset() {
	var $sticky_header_height = 0,
		$media_query_ipad = Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1366px) and (orientation: portrait)' ) ||  Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape)' );

	// Sticky header is enabled
	if ( js_local_vars.header_sticky == '1' && jQuery( '.fusion-header-wrapper' ).length ) {

		// Desktop mode - headers v1, v2, v3
		if ( $sticky_header_type == 1 ) {
			$sticky_header_height = jQuery( '.fusion-header' ).outerHeight() - 1;

		// Desktop mode - headers v4, v5
		} else {
			// Menu only
			$sticky_header_height = jQuery( '.fusion-secondary-main-menu' ).outerHeight();

			// Menu and logo
			if ( js_local_vars.header_sticky_type2_layout == 'menu_and_logo' ) {
				$sticky_header_height += jQuery( '.fusion-header' ).outerHeight() - 1;
			}
		}

		// Mobile mode
		if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {

			// Sticky header is enabled on mobile
			if ( js_local_vars.header_sticky_mobile == '1' ) {
				$sticky_header_height = jQuery( '.fusion-header' ).outerHeight() - 1;
			// Sticky header is disabled on mobile
			} else {
				$sticky_header_height = 0;
			}
		}

		// Tablet mode
		if ( js_local_vars.header_sticky_tablet != '1' && $media_query_ipad ) {
			$sticky_header_height = 0;
		}
	}

	return $sticky_header_height;
}

function get_waypoint_offset( $object ) {
	var $offset = $object.data( 'animationoffset' );

	if ( $offset === undefined ) {
		$offset = 'bottom-in-view';
	}

	if ( $offset == 'top-out-of-view' ) {
		var $adminbar_height = get_adminbar_height(),
			$sticky_header_height = get_waypoint_top_offset();

		$offset = $adminbar_height + get_waypoint_top_offset();
	}

	return $offset;
}

(function( jQuery ) {

	"use strict";

	jQuery('.tfs-slider').each(function() {
		var this_tfslider = this;

		if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
			jQuery(this_tfslider).data('parallax', 0);
			jQuery(this_tfslider).data('full_screen', 0);
		}

		if(cssua.ua.tablet_pc) {
			jQuery(this_tfslider).data('parallax', 0);
		}

		if(cssua.ua.mobile) {
			jQuery(this_tfslider).data('parallax', 0);
		}
	});

	// Waypoint
	jQuery.fn.init_waypoint = function() {
		if( jQuery().waypoint ) {

			// Counters Box
			jQuery('.fusion-counter-box').not('.fusion-modal .fusion-counter-box').each( function() {
				var $offset = get_waypoint_offset( jQuery( this ) );

				jQuery( this ).waypoint(function() {
					jQuery(this).find('.display-counter').each(function() {
						jQuery(this).fusion_box_counting();
					});
				}, {
					triggerOnce: true,
					offset: $offset
				});
			});

			// Counter Circles
			jQuery('.counter-circle-wrapper').not('.fusion-accordian .counter-circle-wrapper, .fusion-tabs .counter-circle-wrapper, .fusion-modal .counter-circle-wrapper').each( function() {
				var $offset = get_waypoint_offset( jQuery( this ) );

				jQuery( this ).waypoint(function() {
					jQuery(this).fusion_recalc_circles( true );
					jQuery(this).fusion_draw_circles();
				}, {
					triggerOnce: true,
					offset: $offset
				});
			});

			// Counter Circles Responsive Resizing
			jQuery('.counter-circle-wrapper').not('.fusion-modal .counter-circle-wrapper').each( function() {
				var $offset = get_waypoint_offset( jQuery( this ) );

				if ( $offset == 'top-out-of-view' ) {
					var $adminbar_height = get_adminbar_height(),
						$sticky_header_height = get_waypoint_top_offset();

					$offset = $adminbar_height + get_waypoint_top_offset();
				}

				jQuery( this ).waypoint(function() {
					var counter_circles = jQuery( this );

					jQuery(window).on('resize', function() {
						counter_circles.fusion_redraw_circles();
					});
				}, {
					triggerOnce: true,
					offset: $offset
				});
			});

			// Progressbar
			jQuery( '.fusion-progressbar' ).not('.fusion-modal .fusion-progressbar').each( function() {
				var $offset = get_waypoint_offset( jQuery( this ) );

				jQuery( this ).waypoint( function() {
					jQuery(this).fusion_draw_progress();
				}, {
					triggerOnce: true,
					offset: $offset
				});
			});

			// Content Boxes Timeline Design
			jQuery( '.fusion-content-boxes' ).each( function() {
				var $offset = get_waypoint_offset( jQuery( this ) );

				jQuery( this ).waypoint( function() {
					var $delay = 0;

					jQuery( this ).find( '.content-box-column' ).each( function() {
						var $element = this;

						setTimeout( function() {
							jQuery( $element ).find( '.fusion-animated' ).css( 'visibility', 'visible' );

							// this code is executed for each appeared element
							var $animation_type = jQuery( $element ).find( '.fusion-animated' ).data( 'animationtype' ),
								$animation_duration = jQuery( $element ).find( '.fusion-animated' ).data( 'animationduration' );

							jQuery( $element ).find( '.fusion-animated' ).addClass( $animation_type );

							if ( $animation_duration ) {
								jQuery( $element ).find( '.fusion-animated' ).css( '-moz-animation-duration', $animation_duration + 's' );
								jQuery( $element ).find( '.fusion-animated' ).css( '-webkit-animation-duration', $animation_duration + 's' );
								jQuery( $element ).find( '.fusion-animated' ).css( '-ms-animation-duration', $animation_duration + 's' );
								jQuery( $element ).find( '.fusion-animated' ).css( '-o-animation-duration', $animation_duration + 's' );
								jQuery( $element ).find( '.fusion-animated' ).css( 'animation-duration', $animation_duration + 's' );
							}

							if( jQuery( $element ).parents( '.fusion-content-boxes' ).hasClass( 'content-boxes-timeline-horizontal' ) ||
								jQuery( $element ).parents( '.fusion-content-boxes' ).hasClass( 'content-boxes-timeline-vertical' ) ) {
								jQuery( $element ).addClass( 'fusion-appear' );
							}
						}, $delay );

						$delay += parseInt( jQuery( this ).parents( '.fusion-content-boxes' ).attr( 'data-animation-delay' ) );
					});
				}, {
					triggerOnce: true,
					offset: $offset
				});
			});

			// CSS Animations
			jQuery( '.fusion-animated' ).each( function() {
				var $offset = get_waypoint_offset( jQuery( this ) );

				if ( $offset == 'top-out-of-view' ) {
					var $adminbar_height = get_adminbar_height(),
						$sticky_header_height = get_sticky_header_height();

					$offset = $adminbar_height + $sticky_header_height;
				}

				jQuery( this ).waypoint( function() {
					if( ! jQuery( this ).parents( '.fusion-delayed-animation' ).length ) {
						jQuery( this ).css( 'visibility', 'visible' );

						// this code is executed for each appeared element
						var $animation_type = jQuery( this ).data( 'animationtype' ),
							$animation_duration = jQuery( this ).data( 'animationduration' );

						jQuery( this ).addClass( $animation_type );

						if ( $animation_duration ) {
							jQuery( this ).css( '-moz-animation-duration', $animation_duration + 's' );
							jQuery( this ).css( '-webkit-animation-duration', $animation_duration + 's' );
							jQuery( this ).css( '-ms-animation-duration', $animation_duration + 's' );
							jQuery( this ).css( '-o-animation-duration', $animation_duration + 's' );
							jQuery( this ).css( 'animation-duration', $animation_duration + 's' );

							// Remove the animation class, when the animation is finished; this is done
							// to prevent conflicts with image hover effects
							var $current_element = jQuery( this );
							setTimeout(
								function() {
									$current_element.removeClass( $animation_type );
								}, $animation_duration * 1000
							);
						}
					}

				}, { triggerOnce: true, offset: $offset } );
			});
		}
	};

	// Recalculate carousel elements
	jQuery.fn.fusion_recalculate_carousel = function() {
		jQuery( this ).not( '.fusion-woo-featured-products-slider' ).each( function() {
			var $carousel = jQuery( this ),
				$image_size = jQuery( this ).data( 'imagesize' );

			// Timeout needed for size changes to take effect, before weaccess them
			setTimeout( function() {
				// Set the position of the right navigation element to make it fit the overall carousel width
				$carousel.find( '.fusion-nav-next' ).each( function() {
					jQuery( this ).css( 'left', $carousel.find( '.fusion-carousel-wrapper' ).width() - jQuery( this ).width() );
				});

				// Resize the placeholder images correctly in "fixed" picture size carousels
				if ( $image_size == 'fixed' ) {
					var $image_heights = $carousel.find( '.fusion-carousel-item' ).map( function () {
							return jQuery( this ).find( 'img' ).height();
						}).get(),
						$needed_height = Math.max.apply( null, $image_heights );

					$carousel.find( '.fusion-placeholder-image' ).each( function() {
						jQuery( this ).css(	'height', $needed_height );
					});
					if ( jQuery( $carousel ).parents( '.fusion-image-carousel' ).length >= 1 ) {
						$carousel.find( '.fusion-image-wrapper' ).each( function() {
							jQuery( this ).css(	'height', $needed_height );
							jQuery( this ).css(	'width', '100%' );
							jQuery( this ).find( '> a' ).css( 'line-height', ( $needed_height - 2 ) + 'px' );
						});
					}
				}
			}, 5 );
		});
	};

	// Animate counter boxes
	jQuery.fn.fusion_box_counting = function() {
		var $count_value = jQuery( this ).data( 'value' ),
			$count_direction = jQuery( this ).data( 'direction' ),
			$delimiter = jQuery( this ).data( 'delimiter' ),
			$from_value = 0,
			$to_value = $count_value,
			$counter_box_speed = js_local_vars.counter_box_speed,
			$counter_box_interval = Math.round( js_local_vars.counter_box_speed / 100 );

		if ( ! $delimiter ) {
			$delimiter = '';
		}

		if ( $count_direction == 'down' ) {
			$from_value = $count_value;
			$to_value = 0;
		}

		jQuery (this ).countTo( {
			from: $from_value,
			to: $to_value,
			refreshInterval: $counter_box_interval,
			speed: $counter_box_speed,
			formatter: function ( value, options ) {
				value = value.toFixed( options.decimals );
				value = value.replace( /\B(?=(\d{3})+(?!\d))/g, $delimiter );

				if ( value == '-0' ) {
					value = 0;
				}

				return value;
			}
		} );
	};

	// Animate counter circles
	jQuery.fn.fusion_draw_circles = function() {
		var circle = jQuery( this );
		var countdown = circle.children( '.counter-circle' ).attr( 'data-countdown' );
		var filledcolor = circle.children( '.counter-circle' ).attr( 'data-filledcolor' );
		var unfilledcolor = circle.children( '.counter-circle' ).attr( 'data-unfilledcolor' );
		var scale = circle.children( '.counter-circle' ).attr( 'data-scale' );
		var size = circle.children( '.counter-circle' ).attr( 'data-size' );
		var speed = circle.children( '.counter-circle' ).attr( 'data-speed' );
		var strokesize = circle.children( '.counter-circle' ).attr( 'data-strokesize' );
		var percentage = circle.children( '.counter-circle' ).attr( 'data-percent' );

		if( scale ) {
			scale = jQuery( 'body' ).css( 'color' );
		}

		if( countdown ) {
			circle.children( '.counter-circle' ).attr( 'data-percent', 100 );

			circle.children( '.counter-circle' ).easyPieChart({
				barColor: filledcolor,
				trackColor: unfilledcolor,
				scaleColor: scale,
				scaleLength: 5,
				lineCap: 'round',
				lineWidth: strokesize,
				size: size,
				rotate: 0,
				animate: {
					duration: speed, enabled: true
				}
			});
			circle.children( '.counter-circle' ).data( 'easyPieChart' ).enableAnimation();
			circle.children( '.counter-circle' ).data( 'easyPieChart' ).update( percentage );
		} else {
			circle.children( '.counter-circle' ).easyPieChart({
				barColor: filledcolor,
				trackColor: unfilledcolor,
				scaleColor: scale,
				scaleLength: 5,
				lineCap: 'round',
				lineWidth: strokesize,
				size: size,
				rotate: 0,
				animate: {
					duration: speed, enabled: true
				}
			});
		}
	};

	jQuery.fn.fusion_recalc_circles = function( $animate ) {
		var $counter_circles_wrapper = jQuery( this );

		// Make sure that only currently visible circles are redrawn; important e.g. for tabs
		if ( $counter_circles_wrapper.is( ':hidden' ) ) {
			return;
		}

		$counter_circles_wrapper.attr( 'data-currentsize', $counter_circles_wrapper.width() );
		$counter_circles_wrapper.removeAttr( 'style' );
		$counter_circles_wrapper.children().removeAttr( 'style' );
		var $current_size = $counter_circles_wrapper.data( 'currentsize' ),
			$original_size = $counter_circles_wrapper.data( 'originalsize' ),
			$fusion_counters_circle_width = $counter_circles_wrapper.parent().width();

		// Overall container width is smaller than one counter circle; e.g. happens for elements in column shortcodes
		if ( $fusion_counters_circle_width < $counter_circles_wrapper.data( 'currentsize' ) ) {

			$counter_circles_wrapper.css({
				'width': $fusion_counters_circle_width,
				'height': $fusion_counters_circle_width,
				'line-height': $fusion_counters_circle_width + 'px'
			});
			$counter_circles_wrapper.find( '.fusion-counter-circle' ).each( function() {
				jQuery( this ).css({
					'width': $fusion_counters_circle_width,
					'height': $fusion_counters_circle_width,
					'line-height': $fusion_counters_circle_width + 'px',
					'font-size': 50 * $fusion_counters_circle_width / 220
				});
				jQuery( this ).data( 'size', $fusion_counters_circle_width );
				jQuery( this ).data( 'strokesize', $fusion_counters_circle_width / 220 * 11 );
				if ( ! $animate ) {
					jQuery( this ).data( 'animate', false );
				}
				jQuery( this ).attr( 'data-size', $fusion_counters_circle_width );
				jQuery( this ).attr( 'data-strokesize', $fusion_counters_circle_width / 220 * 11 );
			});

		} else {
			$counter_circles_wrapper.css({
				'width': $original_size,
				'height': $original_size,
				'line-height': $original_size + 'px'
			});
			$counter_circles_wrapper.find( '.fusion-counter-circle' ).each( function() {
				jQuery( this ).css({
					'width': $original_size,
					'height': $original_size,
					'line-height': $original_size + 'px',
					'font-size': 50* $original_size / 220
				});

				jQuery( this ).data( 'size', $original_size );
				jQuery( this ).data( 'strokesize', $original_size / 220 * 11 );
				if ( ! $animate ) {
					jQuery( this ).data( 'animate', false );
				}
				jQuery( this ).attr( 'data-size', $original_size );
				jQuery( this ).attr( 'data-strokesize', $original_size / 220 * 11 );
			});

		}
	};

	jQuery.fn.fusion_redraw_circles = function() {
		var $counter_circles_wrapper = jQuery( this );

		// Make sure that only currently visible circles are redrawn; important e.g. for tabs
		if ( $counter_circles_wrapper.is( ':hidden' ) ) {
			return;
		}

		$counter_circles_wrapper.fusion_recalc_circles( false );
		$counter_circles_wrapper.find( 'canvas' ).remove();
		$counter_circles_wrapper.find( '.counter-circle' ).removeData( 'easyPieChart' );
		$counter_circles_wrapper.fusion_draw_circles();
	};

	// animate progress bar
	jQuery.fn.fusion_draw_progress = function() {
		var progressbar = jQuery( this );
		if ( jQuery( 'html' ).hasClass( 'lt-ie9' ) ) {
			progressbar.css( 'visibility', 'visible' );
			progressbar.each( function() {
				var percentage = progressbar.find( '.progress' ).attr("aria-valuenow");
				progressbar.find( '.progress' ).css( 'width', '0%' );
				progressbar.find( '.progress' ).animate( {
					width: percentage+'%'
				}, 'slow' );
			} );
		} else {
			progressbar.find( '.progress' ).css( "width", function() {
				return jQuery( this ).attr( "aria-valuenow" ) + "%";
			});
		}
	};

	// set flip boxes equal front/back height
	jQuery.fn.fusion_calc_flip_boxes_height = function() {
		var flip_box = jQuery( this );
		var outer_height, height, top_margin = 0;

		flip_box.find( '.flip-box-front' ).css( 'min-height', '' );
		flip_box.find( '.flip-box-back' ).css( 'min-height', '' );
		flip_box.find( '.flip-box-front-inner' ).css( 'margin-top', '' );
		flip_box.find( '.flip-box-back-inner' ).css( 'margin-top', '' );
		flip_box.css( 'min-height', '' );

		setTimeout( function() {
			if( flip_box.find( '.flip-box-front' ).outerHeight() > flip_box.find( '.flip-box-back' ).outerHeight() ) {
				height = flip_box.find( '.flip-box-front' ).height();
				if( cssua.ua.ie && cssua.ua.ie.substr(0, 1) == '8' ) {
					outer_height = flip_box.find( '.flip-box-front' ).height();
				} else {
					outer_height = flip_box.find( '.flip-box-front' ).outerHeight();
				}
				top_margin = ( height - flip_box.find( '.flip-box-back-inner' ).outerHeight() ) / 2;

				flip_box.find( '.flip-box-back' ).css( 'min-height', outer_height );
				flip_box.css( 'min-height', outer_height );
				flip_box.find( '.flip-box-back-inner' ).css( 'margin-top', top_margin );
			} else {
				height = flip_box.find( '.flip-box-back' ).height();
				if( cssua.ua.ie && cssua.ua.ie.substr(0, 1) == '8' ) {
					outer_height = flip_box.find( '.flip-box-back' ).height();
				} else {
					outer_height = flip_box.find( '.flip-box-back' ).outerHeight();
				}
				top_margin = ( height - flip_box.find( '.flip-box-front-inner' ).outerHeight() ) / 2;

				flip_box.find( '.flip-box-front' ).css( 'min-height', outer_height );
				flip_box.css( 'min-height', outer_height );
				flip_box.find( '.flip-box-front-inner' ).css( 'margin-top', top_margin );
			}

			if( cssua.ua.ie && cssua.ua.ie.substr(0, 1) == '8' ) {
				flip_box.find( '.flip-box-back' ).css( 'height', '100%' );
			}

		}, 100 );
	};

	// fusion scroller plugin to change css while scrolling
	jQuery.fn.fusion_scroller = function( options ) {
        var settings = jQuery.extend({
        	type: 'opacity',
        	offset: 0,
        	end_offset: ''
        }, options );

		var divs = jQuery(this);

		divs.each(function() {
			var offset, height, end_offset;
			var current_element = this;

			jQuery(window).on('scroll', function() {
				offset = jQuery(current_element).offset().top;
				if(jQuery('body').hasClass('admin-bar')) {
					offset = jQuery(current_element).offset().top - jQuery('#wpadminbar').outerHeight();
				}
				if(settings.offset > 0) {
					offset = jQuery(current_element).offset().top - settings.offset;
				}
				height = jQuery(current_element).outerHeight();

				end_offset = offset + height;
				if(settings.end_offset) {
					end_offset = jQuery(settings.end_offset).offset().top;
				}

	        	var st = jQuery(this).scrollTop();

				if(st >= offset && st <= end_offset) {
					var diff = end_offset - st;
					var diff_percentage = (diff / height) * 100;

					if(settings.type == 'opacity') {
						var opacity = (diff_percentage / 100) * 1;
						jQuery(current_element).css({
							'opacity': opacity
						});
					} else if(settings.type == 'blur') {
						var diff_percentage = 100 - diff_percentage;
						var blur = 'blur(' + ((diff_percentage / 100) * 50) + 'px)';
						jQuery(current_element).css({
							'-webkit-filter': blur,
							'-ms-filter': blur,
							'-o-filter': blur,
							'-moz-filter': blur,
							'filter': blur
						});
					} else if(settings.type == 'fading_blur') {
						var opacity = (diff_percentage / 100) * 1;
						var diff_percentage = 100 - diff_percentage;
						var blur = 'blur(' + ((diff_percentage / 100) * 50) + 'px)';
						jQuery(current_element).css({
							'-webkit-filter': blur,
							'-ms-filter': blur,
							'-o-filter': blur,
							'-moz-filter': blur,
							'filter': blur,
							'opacity': opacity
						});
					}
				}

				if( st < offset ) {
					if(settings.type == 'opacity') {
						jQuery(current_element).css({
							'opacity': 1
						});
					} else if(settings.type == 'blur') {
						var blur = 'blur(0px)';
						jQuery(current_element).css({
							'-webkit-filter': blur,
							'-ms-filter': blur,
							'-o-filter': blur,
							'-moz-filter': blur,
							'filter': blur
						});
					} else if(settings.type == 'fading_blur') {
						var blur = 'blur(0px)';
						jQuery(current_element).css({
							'opacity': 1,
							'-webkit-filter': blur,
							'-ms-filter': blur,
							'-o-filter': blur,
							'-moz-filter': blur,
							'filter': blur
						});
					}
				}
			});
		});
	};

	// Change active tab when a link containing a tab ID is clicked; on and off page
	jQuery.fn.fusion_switch_tab_on_link_click = function( $custom_id ) {

		// The custom_id is used for on page links

		if ( $custom_id ) {
			var $link_hash = $custom_id;
		} else {
			var $link_hash = ( document.location.hash.substring( 0, 2 )  == '#_' ) ? document.location.hash.replace( '#_', '#' ) : document.location.hash;
		}

		var $link_id = ( $link_hash.substring( 0, 2 )  == '#_' ) ? $link_hash.split( '#_' )[1] : $link_hash.split( '#' )[1];

		if( $link_hash && jQuery( this ).find( '.nav-tabs li a[href="' + $link_hash + '"]' ).length ) {
			jQuery( this ).find( '.nav-tabs li' ).removeClass( 'active' );
			jQuery( this ).find( '.nav-tabs li a[href="' + $link_hash + '"]' ).parent().addClass( 'active' );

			jQuery( this ).find( '.tab-content .tab-pane' ).removeClass( 'in' ).removeClass( 'active' );
			jQuery( this ).find( '.tab-content .tab-pane[id="' + $link_id  + '"]' ).addClass( 'in' ).addClass( 'active' );
		}

		if( $link_hash && jQuery( this ).find( '.nav-tabs li a[id="' + $link_id + '"]' ).length ) {
			jQuery( this ).find( '.nav-tabs li' ).removeClass( 'active' );
			jQuery( this ).find( '.nav-tabs li a[id="' + $link_id + '"]' ).parent().addClass( 'active' );

			jQuery( this ).find( '.tab-content .tab-pane' ).removeClass( 'in' ).removeClass( 'active' );
			jQuery( this ).find( '.tab-content .tab-pane[id="' + jQuery( this ).find( '.nav-tabs li a[id="' + $link_id + '"]' ).attr( 'href' ).split('#')[1] + '"]' ).addClass( 'in' ).addClass( 'active' );
		}
	};

	// Max height for columns and content boxes
	jQuery.fn.equalHeights = function( $min_height, $max_height ) {
		if ( Modernizr.mq( 'only screen and (min-width: ' + js_local_vars.content_break_point + 'px)' ) || Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait)' ) ) {
			var $tallest = ( $min_height ) ? $min_height : 0;

			this.each( function() {
				jQuery( this ).css( 'min-height', '0' );
				jQuery( this ).css('height', 'auto' );
				jQuery( this ).find( '.fusion-column-table' ).css('height', 'auto' );

				if ( jQuery( this ).outerHeight() > $tallest ) {
					$tallest = jQuery( this ).outerHeight();
				}
			});

			if ( ( $max_height ) && $tallest > $max_height ) {
				$tallest = $max_height;
			}

			return this.each( function() {
				var $new_height = $tallest;

				// If $new_height is 0, then there is no content in any of the columns. Set the empty column param, so that bg images can be scaled correctly
				if ( $new_height == '0' ) {
					jQuery( this ).attr( 'data-empty-column', 'true' );
				}

				// Needed for vertically centered columns
                if ( jQuery( this ).children( '.fusion-column-table' ).length ) {
                    $new_height = $tallest - ( jQuery( this ).outerHeight() - jQuery( this ).height() );
                }

				jQuery( this ).css( 'min-height', $new_height );
				jQuery( this ).find( '.fusion-column-table' ).height( $new_height );
			});
		} else {
			return this.each( function() {
				jQuery( this ).css( 'min-height', '' );
				jQuery( this ).find( '.fusion-column-table' ).css( 'height', '' );
			});
		}
	};

	// Set the bg image dimensions of an empty column as data attributes
	jQuery.fn.fusion_set_bg_img_dims = function() {
		jQuery( this ).each( function() {
			if ( ( jQuery.trim( jQuery( this ).html() ) == '<div class="fusion-clearfix"></div>' || jQuery.trim( jQuery( this ).html() ) == '<div class="fusion-column-table" style="height: 0px;"><div class="fusion-column-tablecell"><div class="fusion-clearfix"></div></div></div>' ) && jQuery( this ).data( 'bg-url' ) ) {
				// For background image we need to setup the image object to get the natural heights
				var $background_image = new Image();
				$background_image.src = jQuery( this ).data( 'bg-url' );
				var $image_height = parseInt( $background_image.naturalHeight ),
					$image_width = parseInt( $background_image.naturalWidth );

				// IE8, Opera fallback
				$background_image.onload = function() {
					$image_height = parseInt( this.height );
					$image_width = parseInt( this.width );
				};

				// Set the
				jQuery( this ).attr( 'data-bg-height', $image_height );
				jQuery( this ).attr( 'data-bg-width', $image_width );
			}
		});
	 };

	// Calculate the correct aspect ratio respecting height of an empty column with bg image
	jQuery.fn.fusion_calculate_empty_column_height = function() {

		jQuery( this ).each( function() {
			if ( ( jQuery( this ).parents( '.fusion-equal-height-columns' ).length && ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.content_break_point + 'px)' ) || jQuery( this ).data( 'empty-column' ) == true ) ) || ! jQuery( this ).parents( '.fusion-equal-height-columns' ).length ) {
				if ( jQuery.trim( jQuery( this ).html() ) == '<div class="fusion-clearfix"></div>' ) {
					var $image_height = jQuery( this ).data( 'bg-height' ),
						$image_width = jQuery( this ).data( 'bg-width' ),
						$container_width = jQuery( this ).outerWidth(),
						$width_ratio = $container_width / $image_width,
						$calculated_container_height = $image_height * $width_ratio;

					jQuery( this ).height( $calculated_container_height );
				}
			}
		});
	 };

	// Reinitialize google map; needed when maps are loaded inside of hidden containers
	jQuery.fn.reinitialize_google_map = function() {
		var fusion_map_object = jQuery( this ).data( 'plugin_fusion_maps' );

		if ( fusion_map_object ) {
			var	map = fusion_map_object.map,
				center = map.getCenter(),
				markers = fusion_map_object.markers;

			google.maps.event.trigger( map, 'resize' );
			map.setCenter( center );
			if ( markers ) {
				for ( var i = 0; i < markers.length; i++ ) {
					google.maps.event.trigger( markers[i], 'click' );
					google.maps.event.trigger( markers[i], 'click' );
				}
			}
		}
	};

	// Initialize fusion filters and corresponding posts
	jQuery.fn.fusion_filters_initialization = function( $posts ) {
		// Check if filters are displayed
		if ( jQuery( this ).length ) {

			// Show the filters container
			jQuery( this ).fadeIn();

			// Set needed variables
			var $filters = jQuery( this ).find( '.fusion-filter' ),
				$filter_active = jQuery( this ).find( '.fusion-active' ),
				$filter_active_link = $filter_active.children( 'a' ),
				$filter_active_data_slug = $filter_active_link.attr( 'data-filter' ).substr( 1 );

			// Loop through filters
			if ( $filters ) {
				$filters.each( function() {
					var $filter = jQuery( this ),
						$filter_name = $filter.children( 'a' ).data( 'filter' );

					// Loop through initial post set
					if ( $posts ) {
						// If "All" filter is deactivated, hide posts for later check for active filter
						if ( $filter_active_data_slug.length ) {
							$posts.hide();
						}

						$posts.each( function() {
							var $post = jQuery( this ),
								$post_gallery_name = $post.find( '.fusion-rollover-gallery' ).data( 'rel' );

							// If a post belongs to an invisible filter, fade it in
							if ( $post.hasClass( $filter_name.substr( 1 ) ) ) {
								if ( $filter.hasClass( 'fusion-hidden' ) ) {
									$filter.removeClass( 'fusion-hidden' );
								}
							}

							// If "All" filter is deactivated, only show the items of the first filter (which is auto activated)
							if ( $filter_active.length && $post.hasClass( $filter_active ) ) {
								$post.show();

								// Set the lightbox gallery
								$post.find( '.fusion-rollover-gallery' ).attr( 'data-rel', $post_gallery_name.replace( 'gallery', $filter_active ) );
							}
						});
					}
				});
			}

			if ( $filter_active_data_slug.length ) {
				// Relayout the posts according to filter selection
				jQuery( instance.elements ).isotope( { filter: '.' + $filter_active } );

				// Create new lightbox instance for the new gallery
				$il_instances.push( jQuery( '[data-rel="iLightbox[' + $filter_active + ']"], [rel="iLightbox[' + $filter_active + ']"]' ).iLightBox( $avada_lightbox.prepare_options( 'iLightbox[' + $filter_active + ']' ) ) );

				// Refresh the lightbox
				$avada_lightbox.refresh_lightbox();

				// Set active filter to lightbox created
				$filter_active_link.data( 'lightbox', 'created' );
			}
		}
	};

	// Initialize parallax footer
	jQuery.fn.fusion_footer_parallax = function() {
		var $footer = jQuery( this );

		// Needed timeout for dynamic footer content
		setTimeout( function() {
			var $wrapper_height = ( $footer.css( 'position' ) == 'fixed' ) ? jQuery( '#wrapper' ).outerHeight() : jQuery( '#wrapper' ).outerHeight() - $footer.outerHeight();

			// On desktops enable parallax footer effect
			if ( $footer.outerHeight() < jQuery( window ).height() && $wrapper_height > jQuery( window ).height() && ( js_local_vars.header_position == 'Top' || ( js_local_vars.header_position != 'Top' && jQuery( window ).height() > jQuery( '.side-header-wrapper' ).height() ) ) && ( Modernizr.mq( 'only screen and (min-width:'  + parseInt( js_local_vars.side_header_break_point ) +  'px)' ) && ! Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait)' ) && ! Modernizr.mq( 'only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape)' ) ) ) {
				$footer.css( {
					'position': '',
					'margin': '',
					'padding': ''
				});
				jQuery( '#main' ).css( 'margin-bottom', $footer.outerHeight() );

				if( jQuery('.tfs-slider').length >= 1 && jQuery('.tfs-slider').data('parallax') == 1 && $footer.hasClass('fusion-footer-parallax') ) {
					var $slider_height = jQuery('.tfs-slider').parents('#sliders-container').outerHeight();
					var $footer_height = $footer.outerHeight();
					if( $slider_height > $footer_height ) {
						jQuery( '#main' ).css('min-height', $slider_height + 100 );
					} else if( $footer_height > $slider_height ) {
						jQuery( '#main' ).css('min-height', $footer_height + 100 );
					}
				}
			// On mobiles the footer will be static
			} else {
				$footer.css( {
					'position': 'static',
					'margin': '0',
					'padding': '0'
				});
				jQuery( '#main' ).css( 'margin-bottom', '' );
			}
		}, 1 );
	};

	jQuery.fn.fusion_countdown = function() {

		var $countdown = jQuery( this ),
			$timer 	= $countdown.data( 'timer' ).split( '-' ),
			$gmt_offset = $countdown.data( 'gmt-offset' ),
			$omit_weeks	= $countdown.data( 'omit-weeks' );

		$countdown.countDown({
			gmtOffset: $gmt_offset,
			omitWeeks: $omit_weeks,
			targetDate: {

				'year':     $timer[0],
				'month':    $timer[1],
				'day':      $timer[2],
				'hour':     $timer[3],
				'min':      $timer[4],
				'sec':      $timer[5]
			}

		});

		$countdown.css( 'visibility', 'visible' );
	};

	jQuery.fn.fusion_deactivate_mobile_image_hovers = function() {
		if ( js_local_vars.disable_mobile_image_hovers != 1 ) {
			if ( Modernizr.mq( 'only screen and (max-width:' + js_local_vars.side_header_break_point + 'px)' ) ) {
				jQuery( this ).removeClass( 'fusion-image-hovers' );
			} else {
				jQuery( this ).addClass( 'fusion-image-hovers' );
			}
		}
	};

	// Add/remove the mobile title class, depending on available space and title length
	jQuery.fn.fusion_responsive_title_shortcode = function() {
		jQuery( this ).each( function() {
			var $title_wrapper = jQuery( this ),
				$title = $title_wrapper.find( 'h1, h2, h3, h4, h5, h6' ),
				$title_min_width = ( $title.data( 'min-width' ) ) ? $title.data( 'min-width' ) : $title.outerWidth(),
				$wrapping_parent = $title_wrapper.parent(),
				$wrapping_parent_width = ( $title_wrapper.parents( '.slide-content' ).length ) ? $wrapping_parent.width() : $wrapping_parent.outerWidth();

			if ( $title_min_width == 0 && $wrapping_parent_width == 0 ) {
				$title_wrapper.removeClass( 'fusion-border-below-title' );
			} else if ( $title_min_width + 100 >= $wrapping_parent_width ) {
				$title_wrapper.addClass( 'fusion-border-below-title' );
				$title.data( 'min-width', $title_min_width );
			} else {
				$title_wrapper.removeClass( 'fusion-border-below-title' );
			}
		});
	};


	// Smooth scrolling to anchor target
	jQuery.fn.fusion_scroll_to_anchor_target = function() {
		var $href = jQuery( this ).attr( 'href' ),
			$href_hash = $href.substr( $href.indexOf( '#' ) ).slice( 1 ),
			$target = jQuery( '#' + $href_hash );

		if ( $target.length && $href_hash !== '' ) {
			var $adminbar_height = get_adminbar_height(),
				$sticky_header_height = get_sticky_header_height(),
				$current_scroll_position = jQuery( document ).scrollTop(),
				$new_scroll_position = $target.offset().top - $adminbar_height - $sticky_header_height,
				$half_scroll_amount = Math.abs( $current_scroll_position - $new_scroll_position ) / 2;

			if ( $current_scroll_position > $new_scroll_position ) {
				var $half_scroll_position = $current_scroll_position - $half_scroll_amount;
			} else {
				var $half_scroll_position = $current_scroll_position + $half_scroll_amount;
			}

			jQuery( 'html, body' ).animate({
				 scrollTop: $half_scroll_position
			}, { duration: 400, easing: 'easeInExpo', complete: function() {

					$adminbar_height = get_adminbar_height();
					$sticky_header_height = get_sticky_header_height();

					$new_scroll_position = ( $target.offset().top - $adminbar_height - $sticky_header_height );

					jQuery( 'html, body' ).animate({
						 scrollTop: $new_scroll_position
					}, 450, 'easeOutExpo');

				}

			});

			// On page tab link
			if ( $target.hasClass( 'tab-link' ) ) {
				jQuery( '.fusion-tabs' ).fusion_switch_tab_on_link_click();
			}

			return false;
		}
	};

})( jQuery );

jQuery( window ).load( function() { // start window_load_1

	// Static layout
	if( js_local_vars.is_responsive == '0' ) {
		var column_classes = ['col-sm-0', 'col-sm-1', 'col-sm-2', 'col-sm-3', 'col-sm-4', 'col-sm-5', 'col-sm-6', 'col-sm-7', 'col-sm-8', 'col-sm-9', 'col-sm-10', 'col-sm-11', 'col-sm-12'];
		jQuery( '.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12' ).each( function() {
			for( var i = 0; i < column_classes.length; i++ ) {
				if( jQuery( this ).attr('class').indexOf( column_classes[i] ) !== -1 ) {
					jQuery( this ).addClass( 'col-xs-' + i );
				}
			}
		});
	}

	// Initialize Waypoint
	setTimeout( function() {
		jQuery(window).init_waypoint();
		jQuery.waypoints( 'viewportHeight' );
	}, 300 );

	// Counters Box - Modals
	jQuery('.fusion-modal .fusion-counter-box').each(function() {
		jQuery(this).appear(function() {
			jQuery(this).find('.display-counter').each(function() {
				jQuery(this).fusion_box_counting();
			});
		});
	});

	// Counter Circles - Toggles, Tabs, Modals
	jQuery('.fusion-accordian .counter-circle-wrapper, .fusion-tabs .counter-circle-wrapper, .fusion-modal .counter-circle-wrapper').each(function() {
		jQuery(this).appear(function() {
			jQuery(this).fusion_draw_circles();
		});
	});

	// Progressbar - Modals
	jQuery('.fusion-modal .fusion-progressbar').each(function() {
		jQuery(this).appear(function() {
			jQuery(this).fusion_draw_progress();
		});
	});

	// Flip Boxes
	jQuery( '.flip-box-inner-wrapper' ).each( function() {
		jQuery( this ).fusion_calc_flip_boxes_height();
	});

	jQuery( window ).resize( function() {
		jQuery( '.flip-box-inner-wrapper' ).each( function() {
			jQuery( this ).fusion_calc_flip_boxes_height();
		});
	});

	// Testimonials
	function onBefore( curr, next, opts, fwd ) {
	  var $ht = jQuery( this ).height();

	  //set the active testimonial class for resize event
	  jQuery( this ).parent().children().removeClass( 'active-testimonial' );
	  jQuery( this ).addClass( 'active-testimonial' );

	  //set the container's height to that of the current slide
	  jQuery( this ).parent().animate( { height: $ht }, 500 );
	}

	if ( jQuery().cycle ) {
		var reviews_cycle_args = {
			fx: 'fade',
			before:  onBefore,
			containerResize: 0,
			containerResizeHeight: 1,
			height: 'auto',
			width: '100%',
			fit: 1,
			speed: 500,
			delay: 0
		};

		if ( js_local_vars.testimonials_speed ) {
			reviews_cycle_args.timeout = parseInt( js_local_vars.testimonials_speed );
		}

		reviews_cycle_args.pager = '.testimonial-pagination';

		jQuery( '.fusion-testimonials .reviews' ).each( function() {
			if ( jQuery( this ).children().length == 1 ) {
				jQuery( this ).children().fadeIn();
			}

			reviews_cycle_args.pager = '#' + jQuery( this ).parent().find( '.testimonial-pagination' ).attr( 'id' );

			reviews_cycle_args.random = jQuery( this ).parent().data( 'random' );
			jQuery( this ).cycle( reviews_cycle_args );
		});



		jQuery( window ).resize( function() {
			jQuery( '.fusion-testimonials .reviews' ).each( function() {
				jQuery( this ).css( 'height', jQuery( this ).children( '.active-testimonial' ).height() );
			});
		});
	}

	// Toggles
	jQuery( document ).on('click', '.fusion-accordian .panel-title a', function ( e ) {
		e.preventDefault();

		var clicked_toggle = jQuery( this );
		var toggle_content_to_activate = jQuery( jQuery( this ).data( 'target' ) ).find( '.panel-body' );

		if( clicked_toggle.hasClass( 'active' ) ) {
			clicked_toggle.parents( '.fusion-accordian ').find( '.panel-title a' ).removeClass( 'active' );
		} else {
			clicked_toggle.parents( '.fusion-accordian ').find( '.panel-title a' ).removeClass( 'active' );
			clicked_toggle.addClass( 'active' );

			setTimeout( function(){
				toggle_content_to_activate.find( '.shortcode-map' ).each(function() {
					jQuery( this ).reinitialize_google_map();
				});

				if( toggle_content_to_activate.find( '.fusion-carousel' ).length ) {
					generate_carousel();
				}

				toggle_content_to_activate.find( '.fusion-portfolio' ).each( function() {
					jQuery( this ).find( '.fusion-portfolio-wrapper' ).isotope();
				});

				// To make premium sliders work in tabs
				if( toggle_content_to_activate.find( '.flexslider, .rev_slider_wrapper, .ls-container' ).length ) {
					jQuery( window ).trigger( 'resize' );
				}

				// Flip Boxes
				toggle_content_to_activate.find( '.flip-box-inner-wrapper' ).each( function() {
					jQuery( this ).fusion_calc_flip_boxes_height();
				});

				toggle_content_to_activate.find( '.fusion-blog-shortcode' ).each( function() {
					var columns = 2;
					for( i = 1; i < 7; i++ ) {
						if( jQuery( this ).find( '.fusion-blog-layout-grid' ).hasClass( 'fusion-blog-layout-grid-' + i ) ) {
							columns = i;
						}
					}

					var grid_width = Math.floor( 100 / columns * 100 ) / 100  + '%';
					jQuery( this ).find( '.fusion-blog-layout-grid' ).find( '.fusion-post-grid' ).css( 'width', grid_width );

					jQuery( this ).find( '.fusion-blog-layout-grid' ).isotope();

					// Reinitialize select arrows
					calc_select_arrow_dimensions();
				});
			}, 350);
		}
	});

	// Initialize Bootstrap Modals
	jQuery( '.fusion-modal' ).each( function() {
		jQuery( '#wrapper' ).append( jQuery( this ) );
	});

	jQuery( '.fusion-modal' ).bind('hidden.bs.modal', function () {
		jQuery( 'html' ).css( 'overflow', '' );
	});

	jQuery( '.fusion-modal' ).bind('show.bs.modal', function () {
		var $slidingbar = jQuery( '#slidingbar' );

		jQuery( 'html' ).css( 'overflow', 'visible' );

		var modal_window = jQuery ( this );



		// Reinitialize dynamic content
		setTimeout( function(){
			// Autoplay youtube videos, if the params have been set accordingly in the video shortcodes
			modal_window.find( '.fusion-youtube' ).find( 'iframe' ).each( function(i) {
				if ( jQuery( this ).parents( '.fusion-video' ).data( 'autoplay' ) == true ) {
					jQuery( this ).parents( '.fusion-video' ).data( 'autoplay', 'false' );

					var func = 'playVideo';
					this.contentWindow.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
				}
			});

			// Autoplay vimeo videos, if the params have been set accordingly in the video shortcodes
			modal_window.find( '.fusion-vimeo' ).find( 'iframe' ).each( function(i) {
				if ( jQuery( this ).parents( '.fusion-video' ).data( 'autoplay' ) == true ) {
					jQuery( this ).parents( '.fusion-video' ).data( 'autoplay', 'false' );

					$f( jQuery( this )[0] ).api('play');
				}
			});

			// To make premium sliders work in tabs
			if ( modal_window.find( '.flexslider, .rev_slider_wrapper, .ls-container' ).length ) {
				jQuery( window ).trigger( 'resize' );
			}

			// Flip Boxes
			modal_window.find( '.flip-box-inner-wrapper' ).each( function() {
				jQuery( this ).fusion_calc_flip_boxes_height();
			});

			// Reinitialize carousels
			if( modal_window.find( '.fusion-carousel' ).length ) {
				generate_carousel();
			}

			// Reinitialize blog shortcode isotope grid
			modal_window.find( '.fusion-blog-shortcode' ).each( function() {
				var columns = 2;
				for( i = 1; i < 7; i++ ) {
					if( jQuery( this ).find( '.fusion-blog-layout-grid' ).hasClass( 'fusion-blog-layout-grid-' + i ) ) {
						columns = i;
					}
				}

				var grid_width = Math.floor( 100 / columns * 100 ) / 100  + '%';
				jQuery( this ).find( '.fusion-blog-layout-grid' ).find( '.fusion-post-grid' ).css( 'width', grid_width );

				jQuery( this ).find( '.fusion-blog-layout-grid' ).isotope();

				calc_select_arrow_dimensions();
			});

			// Reinitialize google maps
			modal_window.find( '.shortcode-map' ).each(function() {
				jQuery( this ).reinitialize_google_map();
			});

			// Reinitialize portfolio
			modal_window.find( '.fusion-portfolio' ).each( function() {
				jQuery( this ).find( '.fusion-portfolio-wrapper' ).isotope();
			});

			// Reinitialize testimonial height; only needed for hidden wrappers
			if ( $slidingbar.find( '.fusion-testimonials' ).length ) {
				var $active_testimonial = $slidingbar.find( '.fusion-testimonials .reviews' ).children( '.active-testimonial' );

				$slidingbar.find( '.fusion-testimonials .reviews' ).height( $active_testimonial.height() );
			}

			// Reinitialize select arrows
			calc_select_arrow_dimensions();
		}, 350);
	});

	if( jQuery( '#sliders-container .tfs-slider' ).data( 'parallax' ) == 1 ) {
		jQuery( '.fusion-modal' ).css( 'top', jQuery( '.header-wrapper' ).height() );
	}

	// stop videos in modals when closed
    jQuery( '.fusion-modal' ).each(function() {
        jQuery( this ).on( 'hide.bs.modal', function() {

			// Youtube
			jQuery( this ).find('iframe').each(function(i) {
				var func = 'pauseVideo';
				this.contentWindow.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
			});

			// Vimeo
			jQuery( this ).find('.fusion-vimeo iframe').each(function(i) {
				$f(this).api('pause');
			});
		});
	});

	jQuery('[data-toggle=modal]').on('click', function(e) {
		e.preventDefault();
	});

	jQuery( '.fusion-modal-text-link' ).click( function( e ) {
		e.preventDefault();
	});

	if(cssua.ua.mobile || cssua.ua.tablet_pc) {
		jQuery('.fusion-popover, .fusion-tooltip').each(function() {
			jQuery(this).attr('data-trigger', 'click');
			jQuery(this).data('trigger', 'click');
		});
	}

	// Initialize Bootstrap Popovers
	jQuery( '[data-toggle~="popover"]' ).popover({
		container: 'body'
	});

	// Initialize Bootstrap Tabs
	// Initialize vertical tabs content container height
	if( jQuery( '.vertical-tabs' ).length ) {
		jQuery( '.vertical-tabs .tab-content .tab-pane' ).each( function() {
			if( jQuery ( this ).parents( '.vertical-tabs' ).hasClass( 'clean' ) ) {
				jQuery ( this ).css( 'min-height', jQuery( '.vertical-tabs .nav-tabs' ).outerHeight() - 10 );
			} else {
				jQuery ( this ).css( 'min-height', jQuery( '.vertical-tabs .nav-tabs' ).outerHeight() );
			}

			if( jQuery ( this ).find( '.video-shortcode' ).length ) {
				var video_width = parseInt( jQuery ( this ).find( '.fusion-video' ).css( 'max-width' ).replace( 'px', '' ) );
				jQuery ( this ).css({
					'float': 'none',
					'max-width': video_width + 60
				});
			}
		});
	}

	jQuery( window ).on( 'resize', function() {
		if( jQuery( '.vertical-tabs' ).length ) {
			jQuery( '.vertical-tabs .tab-content .tab-pane' ).css( 'min-height', jQuery( '.vertical-tabs .nav-tabs' ).outerHeight() );
		}
	});

	// Initialize Bootstrap Tooltip
	jQuery( '[data-toggle="tooltip"]' ).each( function() {
		if ( jQuery( this ).parents( '.fusion-header-wrapper' ).length ) {
			$container = '.fusion-header-wrapper';
		} else if ( jQuery( this ).parents( '#side-header' ).length ) {
			$container = '#side-header';
		} else {
			$container = 'body';
		}

		jQuery( this ).tooltip({
			container: $container
		});
	});

	jQuery( '.fusion-tooltip' ).hover( function(){
			// Get the current title attribute
			var $title = jQuery( this ).attr( 'title' );

			// Store it in a data var
			jQuery( this ).attr( 'data-title', $title );

			// Set the title to nothing so we don't see the tooltips
			jQuery( this ).attr( 'title', '' );

	});

	 jQuery( '.fusion-tooltip' ).click( function(){

			// Retrieve the title from the data attribute
			var $title = jQuery( this ).attr( 'data-title' );

			// Return the title to what it was
			jQuery( this ).attr( 'title', $title );

			jQuery( this ).blur();

		});

	// Events Calendar Reinitialize Scripts
	jQuery( '.tribe_events_filters_close_filters, .tribe_events_filters_show_filters' ).on( 'click', function() {
		var tribe_events = jQuery( this );

		setTimeout( function() {
			jQuery( tribe_events ).parents( '#tribe-events-content-wrapper' ).find( '.fusion-blog-layout-grid' ).isotope();
		});
	});

	generate_carousel();

	// Equal Heights Elements
	jQuery( '.content-boxes-icon-boxed' ).each( function() {
		jQuery( this ).find('.content-box-column .content-wrapper-boxed' ).equalHeights();
		jQuery( this ).find('.content-box-column .content-wrapper-boxed' ).css( 'overflow', 'visible' );
	});

	jQuery( window ).on( 'resize', function() {
		jQuery( '.content-boxes-icon-boxed' ).each( function() {
			jQuery( this ).find( '.content-box-column .content-wrapper-boxed' ).equalHeights();
			jQuery( this ).find( '.content-box-column .content-wrapper-boxed' ).css( 'overflow', 'visible' );
		});
	});

	jQuery( '.content-boxes-clean-vertical' ).each( function() {
		jQuery( this ).find('.content-box-column .col' ).equalHeights();
		jQuery( this ).find('.content-box-column .col' ).css( 'overflow', 'visible' );
	});

	jQuery( window ).on( 'resize', function() {
		jQuery( '.content-boxes-clean-vertical' ).each( function() {
			jQuery( this ).find( '.content-box-column .col' ).equalHeights();
			jQuery( this ).find( '.content-box-column .col' ).css( 'overflow', 'visible' );
		});
	});

	jQuery( '.content-boxes-clean-horizontal' ).each( function() {
		jQuery( this ).find('.content-box-column .col' ).equalHeights();
		jQuery( this ).find('.content-box-column .col' ).css( 'overflow', 'visible' );
	});

	jQuery( window ).on( 'resize', function() {
		jQuery( '.content-boxes-clean-horizontal' ).each( function() {
			jQuery( this ).find( '.content-box-column .col' ).equalHeights();
			jQuery( this ).find( '.content-box-column .col' ).css( 'overflow', 'visible' );
		});
	});

	jQuery( '.double-sidebars.woocommerce .social-share > li' ).equalHeights();

	jQuery( '.fusion-fullwidth.fusion-equal-height-columns' ).each( function() {
		jQuery( this ).find( '.fusion-layout-column .fusion-column-wrapper' ).not( function( $index, $element ) {
			return jQuery( $element ).parents( '.fusion-column-wrapper' ).length ? 1 : 0;
		}).equalHeights();
	});

	jQuery( '.fusion-layout-column .fusion-column-wrapper' ).fusion_set_bg_img_dims();
	jQuery( '.fusion-layout-column .fusion-column-wrapper' ).fusion_calculate_empty_column_height();

	jQuery( window ).on( 'resize', function() {
		jQuery( '.fusion-fullwidth.fusion-equal-height-columns' ).each( function() {
			jQuery( this ).find( '.fusion-layout-column .fusion-column-wrapper' ).not( function( $index, $element ) {
				return jQuery( $element ).parents( '.fusion-column-wrapper' ).length ? 1 : 0;
			}).equalHeights();
		});

		jQuery( '.fusion-layout-column .fusion-column-wrapper' ).fusion_calculate_empty_column_height();
	});


	/**
	 * Icon Hack for iOS7 on Buttons
	 */
	if(cssua.ua.ios) {
		var ios_version = parseInt(cssua.ua.ios);
		if(ios_version == 7) {
			jQuery('.button-icon-divider-left, .button-icon-divider-right').each(function() {
				var height = jQuery(this).parent().outerHeight();
				jQuery(this).css('height', height);

			});
		}
	}
}); // end window_load_1

jQuery( document ).ajaxComplete( function() {
	jQuery( '.wpcf7-response-output' ).each( function() {
		if ( jQuery( this ).hasClass( 'wpcf7-validation-errors' ) && ! jQuery( this ).find( '.alert-icon' ).length ) {
			jQuery( this ).addClass( 'fusion-alert' );
			if ( jQuery( 'body' ).hasClass( 'rtl' ) ) {
				jQuery( this ).append( '<button class="close toggle-alert" aria-hidden="true" data-dismiss="alert" type="button">&times;</button><span class="alert-icon"><i class="fa fa-lg fa-exclamation-triangle"></i></span>');
			} else {
				jQuery( this ).prepend( '<button class="close toggle-alert" aria-hidden="true" data-dismiss="alert" type="button">&times;</button><span class="alert-icon"><i class="fa fa-lg fa-exclamation-triangle"></i></span>');
			}
		}

		if ( jQuery( this ).hasClass( 'wpcf7-mail-sent-ok' ) && ! jQuery( this ).find( '.alert-icon' ).length ) {
			jQuery( this ).addClass( 'fusion-alert' );
			if ( jQuery( 'body' ).hasClass( 'rtl' ) ) {
				jQuery( this ).append( '<button class="close toggle-alert" aria-hidden="true" data-dismiss="alert" type="button">&times;</button><span class="alert-icon"><i class="fa fa-lg fa-check-circle"></i></span>');
			} else {
				jQuery( this ).prepend( '<button class="close toggle-alert" aria-hidden="true" data-dismiss="alert" type="button">&times;</button><span class="alert-icon"><i class="fa fa-lg fa-check-circle"></i></span>');
			}
		}
	});

		jQuery('.wpcf7-response-output.fusion-alert .close').click(function(e) {
			e.preventDefault();

			jQuery(this).parent().slideUp();
		});
});

jQuery( document ).ready(function($) { // start document_ready_1
	add_styles_for_old_ie_versions();

	// Deactivate image hover animations on mobiles
	jQuery( 'body').fusion_deactivate_mobile_image_hovers();
	jQuery(window).on( 'resize', function() {
		jQuery( 'body').fusion_deactivate_mobile_image_hovers();
	});

	// Setup the countdown shortcodes
	jQuery( '.fusion-countdown-counter-wrapper' ).each( function() {
		$countdown_id = jQuery( this ).attr( 'id' );
		jQuery( '#' + $countdown_id ).fusion_countdown();
	});


	// Make the side header scrolling happen
	jQuery( window ).on( 'scroll', fusion_side_header_scroll );
	jQuery( window ).on( 'resize', fusion_side_header_scroll );

	// Loop through all headings
	jQuery( 'h1, h2, h3, h4, h5, h6' ).each(
		function() {

			// If there are inline styles on the element initially, store information about it in data attribute
			if ( jQuery( this ).prop( 'style' )['font-size'] ) {
				jQuery( this ).attr( 'data-inline-fontsize', true );
			}

			if ( jQuery( this ).prop( 'style' )['font-size'] ) {
				jQuery( this ).attr( 'data-inline-lineheight', true );
			}

			// Set the original font size and line height to every heading as data attribute
			jQuery( this ).attr( 'data-fontsize', parseInt( jQuery( this ).css( 'font-size' ) ) );
			jQuery( this ).attr( 'data-lineheight', parseInt( jQuery( this ).css( 'line-height' ) ) );
		}
	);

	// Setup responsive type for headings if enabled in Theme Options
	if ( js_local_vars.typography_responsive == 1 ) {
		// Calculate responsive type values
		fusion_calculate_responsive_type_values( js_local_vars.typography_sensitivity, js_local_vars.typography_factor, 800, 'h1, h2, h3, h4, h5, h6' );
	}

	jQuery( '.tfs-slider' ).each(function() {
		fusion_calculate_responsive_type_values( jQuery( this ).data( 'typo_sensitivity' ), jQuery( this ).data( 'typo_factor' ), 800, '.tfs-slider h2, .tfs-slider h3' );
	});

	// Carousel resize
	jQuery(window).on( 'resize', function() {
		jQuery( '.fusion-carousel' ).fusion_recalculate_carousel();
	});

	// Enable autoplaying videos when not in a modal
	jQuery( '.fusion-video' ).each( function() {
		if ( ! jQuery( this ).parents( '.fusion-modal' ).length && jQuery( this ).data( 'autoplay' ) == 1 ) {
			jQuery( this ).find( 'iframe' ).each(function(i) {
				jQuery( this ).attr( 'src', jQuery( this ).attr( 'src' ).replace( 'autoplay=0', 'autoplay=1' ) );
			});
		}
	});

	// Handle parallax footer
	jQuery( '.fusion-footer-parallax' ).fusion_footer_parallax();

	jQuery( window ).on( 'resize', function() {
		jQuery( '.fusion-footer-parallax' ).fusion_footer_parallax();
	});

	// Disable bottom margin on empty footer columns
	jQuery( '.fusion-footer .fusion-footer-widget-area .fusion-column' ).each(
		function() {
			if ( jQuery( this ).is(':empty') ) {
				jQuery( this ).css( 'margin-bottom', '0' );
			}
		}
	);

	if ( js_local_vars.disable_mobile_animate_css != '1' && cssua.ua.mobile ) {
		jQuery( 'body' ).addClass( 'dont-animate' );
	} else {
		jQuery( 'body' ).addClass( 'do-animate' );
	}

	// Comment form title changes
	if ( jQuery( '.comment-respond .comment-reply-title' ).length && ! jQuery( '.comment-respond .comment-reply-title' ).parents( '.woocommerce-tabs' ).length ) {
		var $title_sep = js_local_vars.title_style_type.split( ' ' ),
			$title_sep_class_string = '',
			$title_main_sep_class_string = '';

		for ( var i = 0; i < $title_sep.length; i++ ) {
			$title_sep_class_string += ' sep-' + $title_sep[i];
		}

		if ( $title_sep_class_string.indexOf( 'underline' ) > -1 ) {
			$title_main_sep_class_string = $title_sep_class_string;
		}

		if ( jQuery( 'body' ).hasClass( 'rtl' ) ) {
			jQuery( '.comment-respond .comment-reply-title' ).addClass( 'title-heading-right' );
		} else {
			jQuery( '.comment-respond .comment-reply-title' ).addClass( 'title-heading-left' );
		}

		$styles = ' style="margin-top:' + js_local_vars.title_margin_top + ';margin-bottom:' + js_local_vars.title_margin_bottom + ';"';

		jQuery( '.comment-respond .comment-reply-title' ).wrap( '<div class="fusion-title title fusion-title-size-three' + $title_sep_class_string + '"' + $styles + '></div>' );

		if ( $title_sep_class_string.indexOf( 'underline' ) == -1 ) {
			jQuery( '.comment-respond .comment-reply-title' ).parent().append( '<div class="title-sep-container"><div class="title-sep' + $title_sep_class_string + ' "></div></div>' );
		}
	}

	// Sidebar Position
	if(jQuery('#sidebar-2').length >= 1) {
		var sidebar_1_float = jQuery('#sidebar').css('float');
		jQuery('body').addClass('sidebar-position-' + sidebar_1_float);
	}

	jQuery('.fusion-flip-box').mouseover(function() {
		jQuery(this).addClass('hover');
	});

	jQuery('.fusion-flip-box').mouseout(function() {
		jQuery(this).removeClass('hover');
	});

	jQuery('.fusion-accordian .panel-title a').click(function(e) {
		e.preventDefault();
	});

	jQuery(".my-show").click(function(){
		jQuery(".my-hidden").css('visibility', 'visible');
	});

	if (jQuery(".demo_store").length ) {
		jQuery("#wrapper").css('margin-top', jQuery(".demo_store").outerHeight());
		if(jQuery("#slidingbar-area").outerHeight()  > 0) {
			jQuery(".header-wrapper").css('margin-top', '0');
		}
		if(jQuery('.sticky-header').length ) {
			jQuery('.sticky-header').css('margin-top', jQuery('.demo_store').outerHeight());
		}
	}

	// Slidingbar initialization
	var slidingbar_state = 0;

 	// Open slidingbar on page load if .open_onload class is present
	if ( jQuery( '#slidingbar-area.open_onload' ).length ) {
		jQuery( '#slidingbar' ).slideDown( 240,'easeOutQuad' );
		jQuery( '.sb-toggle' ).addClass( 'open' );
		slidingbar_state = 1;

		// Reinitialize google maps
		if ( jQuery('#slidingbar .shortcode-map' ).length ) {
			jQuery( '#slidingbar' ).find( '.shortcode-map' ).each( function() {
				jQuery( this ).reinitialize_google_map();
			});
		}

		jQuery( '#slidingbar-area' ).removeClass('open_onload');
	}

	// Handle the slidingbar toggle click
	jQuery( '.sb-toggle' ).click( function(){
		var $slidingbar = jQuery ( this ).parents( '#slidingbar-area' ).children( '#slidingbar' );

		//Expand
		if ( slidingbar_state === 0 ) {
			$slidingbar.slideDown( 240, 'easeOutQuad' );
			jQuery( '.sb-toggle' ).addClass( 'open' );
			slidingbar_state = 1;

			// Reinitialize google maps
			if ( $slidingbar.find( '.shortcode-map' ).length ) {
				$slidingbar.find( '.shortcode-map' ).each( function() {
					jQuery( this ).reinitialize_google_map();
				});
			}

			// Reinitialize carousels
			if( $slidingbar.find( '.fusion-carousel' ).length ) {
				generate_carousel();
			}

			jQuery( '#slidingbar' ).find( '.fusion-carousel' ).fusion_recalculate_carousel();

			// reinitialize testimonial height; only needed for hidden wrappers
			if ( $slidingbar.find( '.fusion-testimonials' ).length ) {
				var $active_testimonial = $slidingbar.find( '.fusion-testimonials .reviews' ).children( '.active-testimonial' );

				$slidingbar.find( '.fusion-testimonials .reviews' ).height( $active_testimonial.height() );
			}

		//Collapse
		} else if( slidingbar_state == 1 ) {
			$slidingbar.slideUp(240,'easeOutQuad');
			jQuery( '.sb-toggle' ).removeClass( 'open' );
			slidingbar_state = 0;
		}
	});

	// Foter without social icons
	if( ! jQuery( '.fusion-social-links-footer' ).find( '.fusion-social-networks' ).children().length ) {
		jQuery( '.fusion-social-links-footer' ).hide();
		jQuery( '.fusion-footer-copyright-area .fusion-copyright-notice' ).css( 'padding-bottom', '0' );
	}

	// To top
	if(jQuery().UItoTop) {
		if(cssua.ua.mobile && js_local_vars.status_totop_mobile == '1') {
			jQuery().UItoTop({ easingType: 'easeOutQuart' });
		} else if( ! cssua.ua.mobile ) {
			jQuery().UItoTop({ easingType: 'easeOutQuart' });
		}
	}

	// sticky header resizing control
	jQuery(window).on('resize', function() {
		// check for woo demo bar which can take on 2 lines and thus sticky position must be calculated
		if(jQuery(".demo_store").length) {
			jQuery("#wrapper").css('margin-top', jQuery(".demo_store").outerHeight());
			if(jQuery('.sticky-header').length) {
				jQuery(".sticky-header").css('margin-top', jQuery(".demo_store").outerHeight());
			}
		}

		if(jQuery(".sticky-header").length ) {
			if(jQuery(window).width() < 765) {
				jQuery('body.admin-bar #header-sticky.sticky-header').css('top', '46px');
			} else {
				jQuery('body.admin-bar #header-sticky.sticky-header').css('top', '32px');
			}
		}
	});

	//side header main nav
	if(js_local_vars.mobile_menu_design == 'classic') {
		jQuery('.sh-mobile-nav-holder').append('<div class="mobile-selector"><span>'+js_local_vars.dropdown_goto+'</span></div>');
		jQuery('.sh-mobile-nav-holder .mobile-selector').append('<div class="selector-down"></div>');
	}
	jQuery('.sh-mobile-nav-holder').append(jQuery('.nav-holder .fusion-navbar-nav').clone());
	jQuery('.sh-mobile-nav-holder .fusion-navbar-nav').attr("id","mobile-nav");
	jQuery('.sh-mobile-nav-holder ul#mobile-nav').removeClass('fusion-navbar-nav');
	jQuery('.sh-mobile-nav-holder ul#mobile-nav').children('.cart').remove();
	jQuery('.sh-mobile-nav-holder ul#mobile-nav .mobile-nav-item').children('.login-box').remove();

	jQuery('.sh-mobile-nav-holder ul#mobile-nav li').children('#main-nav-search-link').each(function () {
		jQuery(this).parents('li').remove();
	});
	jQuery('.sh-mobile-nav-holder ul#mobile-nav').find('li').each(function () {
		var classes = 'mobile-nav-item';

		if(jQuery(this).hasClass('current-menu-item') || jQuery(this).hasClass('current-menu-parent') || jQuery(this).hasClass('current-menu-ancestor')) {
			classes += ' mobile-current-nav-item';
		}
		jQuery( this ).attr( 'class', classes );
		if( jQuery( this ).attr( 'id' ) ) {
			jQuery( this ).attr( 'id', jQuery( this ).attr( 'id' ).replace( 'menu-item', 'mobile-menu-item' ) );
		}
		jQuery( this ).attr( 'style', '' );
	});
	jQuery('.sh-mobile-nav-holder .mobile-selector').click(function(){
		if( jQuery('.sh-mobile-nav-holder #mobile-nav').hasClass( 'mobile-menu-expanded' ) ) {
			jQuery('.sh-mobile-nav-holder #mobile-nav').removeClass( 'mobile-menu-expanded' );
		} else {
			jQuery('.sh-mobile-nav-holder #mobile-nav').addClass( 'mobile-menu-expanded' );
	}
		jQuery('.sh-mobile-nav-holder #mobile-nav').slideToggle(200,'easeOutQuad');
	});

	// Make mobile menu sub-menu toggles
	if( js_local_vars.submenu_slideout == 1 ) {
		jQuery('.header-wrapper .mobile-topnav-holder .mobile-topnav li, .header-wrapper .mobile-nav-holder .navigation li, .sticky-header .mobile-nav-holder .navigation li, .sh-mobile-nav-holder .navigation li').each(function() {
			var classes = 'mobile-nav-item';

			if(jQuery(this).hasClass('current-menu-item') || jQuery(this).hasClass('current-menu-parent') || jQuery(this).hasClass('current-menu-ancestor') || jQuery(this).hasClass('mobile-current-nav-item')) {
				classes += ' mobile-current-nav-item';
			}
			jQuery( this ).attr( 'class', classes );

			if( jQuery( this ).find( ' > ul' ).length ) {
				jQuery( this ).prepend('<span href="#" aria-haspopup="true" class="open-submenu"></span>' );

				jQuery( this ).find( ' > ul' ).hide();
			}
		});

		jQuery('.header-wrapper .mobile-topnav-holder .open-submenu, .header-wrapper .mobile-nav-holder .open-submenu, .sticky-header .mobile-nav-holder .open-submenu, .sh-mobile-nav-holder .open-submenu').click( function(e) {
			e.stopPropagation();
			jQuery( this ).parent().children( '.sub-menu' ).slideToggle(200,'easeOutQuad');

		});
	}

	// One page scrolling effect
	var $adminbar_height = get_adminbar_height(),
		$sticky_header_height = get_sticky_header_height();

	jQuery( window ).on('resize scroll', function() {
		$adminbar_height = get_adminbar_height();
		$sticky_header_height = get_sticky_header_height();
	});

	// Ititialize ScrollSpy script
	jQuery( 'body' ).scrollspy({
		target: '.fusion-menu',
		offset: parseInt( $adminbar_height + $sticky_header_height + 1 )
	});

	// Reset ScrollSpy offset to correct height after page is fully loaded, may be needed for
    jQuery( window ).load( function() {
		$adminbar_height = get_adminbar_height();
		$sticky_header_height = get_sticky_header_height();

    	jQuery( 'body' ).data()['bs.scrollspy'].options.offset = parseInt( $adminbar_height + $sticky_header_height + 1 );
    });

	jQuery( '.fusion-menu a:not([href="#"], .fusion-megamenu-widgets-container a, .search-link), .fusion-mobile-nav-item a:not([href="#"], .search-link), .fusion-button:not([href="#"], input, button), .fusion-one-page-text-link:not([href="#"])' ).click( function( e ) {
		if ( this.hash ) {
			// Current path
			var $current_href = window.location.href.split( '#' ),
				$current_path = ( $current_href[0].charAt( $current_href[0].length - 1 ) == '/' ) ? $current_href[0] : $current_href[0] + '/',

				// Target path
				$target       = jQuery( this ).attr( 'href' ),
				$target_array = $target.split( '#' ),
				$target_id    = ( typeof $target_array[1] !== 'undefined' ) ? $target_array[1] : null,
				$target_path = $target_array[0],
				$target_path_last_char = $target_path.substring( $target_path.length - 1, $target_path.length );

			if ( $target_path_last_char != '/' ) {
				$target_path = $target_path + '/';
			}

			e.preventDefault();

			// If the link is outbound add an underscore right after the hash tag to make sure the link isn't present on the loaded page
			if ( location.pathname.replace( /^\//,'') == this.pathname.replace(/^\//,'') || $target.charAt(0) == '#' ) {
				jQuery( this ).fusion_scroll_to_anchor_target();
			} else {
				window.location = $target_path + '#_' + $target_id;
			}
		}
	});

	// side nav drop downs
	jQuery('.side-nav-left .side-nav li').each(function() {
		if(jQuery(this).find('> .children').length) {
			if( jQuery( '.rtl' ).length ) {
				jQuery(this).find('> a').prepend('<span class="arrow"></span>');
			} else {
				jQuery(this).find('> a').append('<span class="arrow"></span>');
			}
		}
	});

	jQuery('.side-nav-right .side-nav li').each(function() {
		if(jQuery(this).find('> .children').length) {
			if( jQuery( 'body.rtl' ).length ) {
				jQuery(this).find('> a').append('<span class="arrow"></span>');
			} else {
				jQuery(this).find('> a').prepend('<span class="arrow"></span>');
			}
		}
	});

	jQuery('.side-nav .current_page_item').each(function() {
		if(jQuery(this).find('.children').length ){
			jQuery(this).find('.children').show('slow');
		}
	});

	jQuery('.side-nav .current_page_item').each(function() {
		if(jQuery(this).parent().hasClass('side-nav')) {
			jQuery(this).find('ul').show('slow');
		}

		if(jQuery(this).parent().hasClass('children')){
			jQuery(this).parents('ul').show('slow');
		}
	});

	if ('ontouchstart' in document.documentElement || navigator.msMaxTouchPoints) {
		jQuery('.fusion-main-menu li.menu-item-has-children > a, .fusion-secondary-menu li.menu-item-has-children > a, .order-dropdown > li .current-li').on("click", function (e) {
			var link = jQuery(this);
			if (link.hasClass('hover')) {
				link.removeClass("hover");
				return true;
			} else {
				link.addClass("hover");
				jQuery('.fusion-main-menu li.menu-item-has-children > a, .fusion-secondary-menu li.menu-item-has-children > a, .order-dropdown > li .current-li').not(this).removeClass("hover");
				return false;
			}
		});


		jQuery('.sub-menu li, .fusion-mobile-nav-item li').not('li.menu-item-has-children').on("click", function (e) {
			var link = jQuery(this).find('a').attr('href');
			if(jQuery(this).find('a').attr('target') != '_blank') { // fix for #1564
				window.location = link;
			}

	  		return true;
		});
	}

	// Touch support for win phone devices
	jQuery( '.fusion-main-menu li.menu-item-has-children > a, .fusion-secondary-menu li.menu-item-has-children > a, .side-nav li.page_item_has_children > a' ).each( function() {
		jQuery( this ).attr( 'aria-haspopup', 'true' );
	});

	// Ubermenu responsive fix
	if(jQuery('.megaResponsive').length >= 1) {
		jQuery('.mobile-nav-holder.main-menu').addClass('set-invisible');
	}

	// WPML search form input add
	if( js_local_vars.language_flag !== '' ) {
		jQuery('.search-field, .searchform').each( function() {
			if( ! jQuery( this ).find( 'input[name="lang"]' ).length && ! jQuery( this ).parents( '.searchform' ).find( 'input[name="lang"]' ).length ) {
				jQuery( this ).append('<input type="hidden" name="lang" value="'+js_local_vars.language_flag+'"/>');
			}
		});
	}

	// New spinner for WPCF7
	jQuery( '<div class="fusion-slider-loading"></div>' ).insertAfter( '.wpcf7 .ajax-loader' );
	jQuery( '.wpcf7 img.ajax-loader' ).remove();

	jQuery( '.wpcf7-form .wpcf7-submit' ).on( 'click', function() {
		jQuery( this ).parents( '.wpcf7-form' ).find( '.fusion-slider-loading' ).show();
	});

	jQuery( document ).ajaxComplete( function( event, request, settings ) {
		if ( jQuery( '.wpcf7-form' ).find( '.fusion-slider-loading' ).filter( ':visible' ).length ) {
			jQuery( '.wpcf7-form' ).find( '.fusion-slider-loading' ).hide();
		}

	});

	jQuery( '#wrapper .fusion-sharing-box' ).each( function() {
		if( ! jQuery( 'meta[property="og:title"]' ).length ) {
			jQuery( 'head title' ).after( '<meta property="og:title" content="' + jQuery( this ).data( 'title' )  + '"/>' );
			jQuery( 'head title' ).after( '<meta property="og:description" content="' + jQuery( this ).data( 'description' )  + '"/>' );
			jQuery( 'head title' ).after( '<meta property="og:type" content="article"/>' );
			jQuery( 'head title' ).after( '<meta property="og:url" content="' + jQuery( this ).data( 'link' )  + '"/>' );
			jQuery( 'head title' ).after( '<meta property="og:image" content="' + jQuery( this ).data( 'image' )  + '"/>' );
		}
	});

	// Remove title separators and padding, when there is not enough space
	jQuery( '.fusion-title' ).fusion_responsive_title_shortcode();

	jQuery( window ).on( 'resize', function() {
		jQuery( '.fusion-title' ).fusion_responsive_title_shortcode();
	});

	// Position main menu search box correctly
	if( js_local_vars.header_position == 'Top' ) {
		jQuery(window).on( 'resize', function() {
			jQuery( '.main-nav-search' ).each( function() {
				if( jQuery( this ).hasClass( 'search-box-open' ) ) {
					var search_form = jQuery( this ).find( '.main-nav-search-form' ),
						search_form_width = search_form.outerWidth(),
						search_form_left_edge = search_form.offset().left,
						search_form_right_edge = search_form_left_edge + search_form_width,
						search_menu_item_left_edge = search_form.parent().offset().left,
						window_right_edge = jQuery( window ).width();


					if( ! jQuery( 'body.rtl' ).length ) {
						if( ( search_form_left_edge < search_menu_item_left_edge && search_form_left_edge < 0 ) || ( search_form_left_edge == search_menu_item_left_edge && search_form_left_edge - search_form_width < 0 ) ) {
							search_form.css({
								'left': '0',
								'right': 'auto'
							});
						} else {
							search_form.css({
								'left': 'auto',
								'right': '0'
							});
						}
					} else {
						if( ( search_form_left_edge == search_menu_item_left_edge && search_form_right_edge > window_right_edge ) || ( search_form_left_edge < search_menu_item_left_edge && search_form_right_edge + search_form_width > window_right_edge )  ) {
							search_form.css({
								'left': 'auto',
								'right': '0'
							});
						} else {
							search_form.css({
								'left': '0',
								'right': 'auto'
							});
						}
					}
				}
			});
		});
	}

	// Tabs
	// On page load
	// Direct linked tab handling
	jQuery( '.fusion-tabs' ).fusion_switch_tab_on_link_click();

	//On Click Event
	jQuery( '.nav-tabs li' ).click( function(e) {
		var clicked_tab = jQuery( this );
		var tab_content_to_activate = clicked_tab.find( 'a' ).attr( 'href' );
		var map_id = clicked_tab.attr( 'id' );

		clicked_tab.parents( '.fusion-tabs' ).find( '.nav li' ).removeClass( 'active' );

		if ( clicked_tab.parents( '.fusion-tabs' ).find( tab_content_to_activate ).find( '.fusion-woo-slider' ).length ) {
			var $nav_tabs_height = 0;
			if ( clicked_tab.parents( '.fusion-tabs' ).hasClass( 'horizontal-tabs' ) ) {
				$nav_tabs_height = clicked_tab.parents( '.fusion-tabs' ).find( '.nav' ).height();
			}
			clicked_tab.parents( '.fusion-tabs' ).height( clicked_tab.parents( '.fusion-tabs' ).find( '.tab-content' ).outerHeight( true ) + $nav_tabs_height );
		}

		/* Scroll mobile tabs to correct position; Disabled because it is jumpy
		if ( clicked_tab.parents( '.nav' ).hasClass( 'fusion-mobile-tab-nav' ) ) {
			setTimeout( function(){
				jQuery( 'html, body' ).animate({
					scrollTop: clicked_tab.offset().top - clicked_tab.outerHeight()
				}, 100 );
			}, 350 );
		}
		*/


		setTimeout( function(){
			// Google maps
			clicked_tab.parents( '.fusion-tabs' ).find( tab_content_to_activate ).find( '.shortcode-map' ).each(function() {
				jQuery( this ).reinitialize_google_map();
			});

			// Image Carousels
			if( clicked_tab.parents( '.fusion-tabs' ).find( tab_content_to_activate ).find( '.fusion-carousel' ).length ) {
				generate_carousel();
			}

			// Portfolio
			clicked_tab.parents( '.fusion-tabs' ).find( tab_content_to_activate ).find( '.fusion-portfolio' ).each( function() {
				var $portfolio_wrapper = jQuery( this ).find( '.fusion-portfolio-wrapper' ),
					$portfolio_wrapper_id = $portfolio_wrapper.attr( 'id' );

				// Done for multiple instances of recent works shortcode. Isotope needs ids to distinguish between instances
				if ( $portfolio_wrapper_id ) {
					$portfolio_wrapper = jQuery( '#' + $portfolio_wrapper_id );
				}

				$portfolio_wrapper.isotope();
			});

			// Make premium sliders and other elements work
			jQuery( window ).trigger( 'resize' );

			// Flip Boxes
			clicked_tab.parents( '.fusion-tabs' ).find( tab_content_to_activate ).find( '.flip-box-inner-wrapper' ).each( function() {
				jQuery( this ).fusion_calc_flip_boxes_height();
			});

			// Make WooCommerce shortcodes work
			if ( clicked_tab.parents( '.fusion-tabs' ).find( tab_content_to_activate ).find( '.fusion-woo-slider' ).length ) {
				clicked_tab.parents( '.fusion-tabs' ).css( 'height', '' );
			}

			jQuery( '.crossfade-images' ).each(	function() {
				fusion_resize_crossfade_images_container( jQuery( this ) );
				fusionResizeCrossfadeImages( jQuery( this ) );
			});

			// Blog
			clicked_tab.parents( '.fusion-tabs' ).find( tab_content_to_activate ).find( '.fusion-blog-shortcode' ).each( function() {
				var columns = 2;
				for( i = 1; i < 7; i++ ) {
					if( jQuery( this ).find( '.fusion-blog-layout-grid' ).hasClass( 'fusion-blog-layout-grid-' + i ) ) {
						columns = i;
					}
				}

				var grid_width = Math.floor( 100 / columns * 100 ) / 100  + '%';
				jQuery( this ).find( '.fusion-blog-layout-grid' ).find( '.fusion-post-grid' ).css( 'width', grid_width );

				jQuery( this ).find( '.fusion-blog-layout-grid' ).isotope();

				calc_select_arrow_dimensions();
			});

			// Reinitialize select arrows
			calc_select_arrow_dimensions();
		}, 350 );

		e.preventDefault();
	});

	// Tabs Widget
	jQuery( '.tabs-widget .tabset li a' ).click( function( e ) {
		e.preventDefault();
	});

	// When page loads
	jQuery( '.tabs-widget' ).each(function() {
		jQuery( this ).find( '.tabset li:first' ).addClass( 'active' ).show(); //Activate first tab
		jQuery( this ).find( '.tab_content:first' ).show(); //Show first tab content
	});

	//On Click Event
	jQuery( '.tabs-widget .tabset li' ).click(function(e) {
		var tab_to_activate = jQuery( this ).find( 'a' ).attr( 'href' );

		jQuery( this ).parent().find( ' > li' ).removeClass( 'active' ); //Remove all 'active' classes
		jQuery( this ).addClass( 'active' ); // Add 'active' class to selected tab

		jQuery( this ).parents( '.tabs-widget' ).find( '.tab_content' ).hide(); //Hide all tab content
		jQuery( this ).parents( '.tabs-widget' ).find( tab_to_activate ).fadeIn(); //Fade in the new active tab content
	});

	jQuery('.tooltip-shortcode, .fusion-secondary-header .fusion-social-networks li, .fusion-author-social .fusion-social-networks li, .fusion-footer-copyright-area .fusion-social-networks li, .fusion-footer-widget-area .fusion-social-networks li, .sidebar .fusion-social-networks li, .social_links_shortcode li, .share-box li, .social-icon, .social li').mouseenter(function(e){
		jQuery(this).find('.popup').hoverFlow(e.type, {
			'opacity' :'show'
		});
	});

	jQuery('.tooltip-shortcode, .fusion-secondary-header .fusion-social-networks li, .fusion-author-social .fusion-social-networks li, .fusion-footer-copyright-area .fusion-social-networks li, .fusion-footer-widget-area .fusion-social-networks li, .sidebar .fusion-social-networks li, .social_links_shortcode li, .share-box li, .social-icon, .social li').mouseleave(function(e){
		jQuery(this).find('.popup').hoverFlow(e.type, {
			'opacity' :'hide'
		});
	});

	// Make sure protfolio fixed width placeholders are sized correctly on resize
	jQuery( window ).on( 'resize', function() {
		jQuery( '.fusion-portfolio .fusion-portfolio-wrapper' ).each( function() {
			// Resize the placeholder images correctly in "fixed" picture size carousels
			if ( jQuery( this ).data( 'picturesize' ) == 'fixed' ) {
				jQuery( this ).find( '.fusion-placeholder-image' ).each( function() {
					jQuery( this ).css(	{
						'height': jQuery( this ).parents( '.fusion-portfolio-post' ).siblings().find( 'img' ).first().height(),
						'width': jQuery( this ).parents( '.fusion-portfolio-post' ).siblings().find( 'img' ).first().width()
					});

				});
			}
		});
	});

	// Handle the portfolio filter clicks
	jQuery('.fusion-portfolio .fusion-filters a').click( function( e ) {
		e.preventDefault();

		// Relayout isotope based on filter selection
		var $filter_active = jQuery( this ).data( 'filter' ),
			$lightbox_instances = [],
			$portfolio_id = jQuery( this ).parents( '.fusion-portfolio' ).data( 'id' );

		if ( ! $portfolio_id ) {
			$portfolio_id = '';
		}

		jQuery( this ).parents( '.fusion-portfolio' ).find( '.fusion-portfolio-wrapper' ).isotope( { filter: $filter_active } );

		// Remove active filter class from old filter item and add it to new
		jQuery( this ).parents( '.fusion-filters' ).find( '.fusion-filter' ).removeClass( 'fusion-active' );
		jQuery( this ).parent().addClass( 'fusion-active' );

		jQuery( this ).parents( '.fusion-portfolio' ).find( '.fusion-portfolio-wrapper' ).find( '.fusion-portfolio-post' ).each( function() {
			var $post_id = '';

			// For individual per post galleries set the post id
			if ( js_local_vars.lightbox_behavior == 'individual' && jQuery( this ).find( '.fusion-rollover-gallery' ).length ) {
				$post_id = jQuery( this ).find( '.fusion-rollover-gallery' ).data( 'id' );
			}

			if ( $filter_active.length > 1 ) {
				var $filter_selector = $filter_active.substr(1),
					$lightbox_string = 'iLightbox[' + $filter_selector + $post_id  + $portfolio_id + ']';
			} else {
				var $filter_selector = 'fusion-portfolio-post',
					$lightbox_string = 'iLightbox[gallery' + $post_id + $portfolio_id + ']';
			}

			if ( jQuery( this ).hasClass( $filter_selector ) || $filter_active.length == 1 ) {
				// Make sure that if $post_id is empty the filter category is only added once to the lightbox array
				if ( $filter_active.length > 1 && jQuery.inArray( $filter_selector + $post_id + $portfolio_id, $lightbox_instances ) === -1 ) {
					$lightbox_instances.push( $filter_selector + $post_id + $portfolio_id );
				} else if ( 1 === $filter_active.length && -1 === jQuery.inArray( $post_id + $portfolio_id, $lightbox_instances ) ) {
					$lightbox_instances.push( 'gallery' + $post_id + $portfolio_id );

				}

				jQuery( this ).find( '.fusion-rollover-gallery' ).attr( 'data-rel', $lightbox_string );
				jQuery( this ).find( '.fusion-portfolio-gallery-hidden a' ).attr( 'data-rel', $lightbox_string );
			}
		});

		// Check if we need to create a new gallery
		if ( jQuery( this ).data( 'lightbox' ) != 'created' ) {

			// Create new lightbox instance for the new galleries
			jQuery.each( $lightbox_instances, function( $key, $value ) {
				$il_instances.push( jQuery( '[data-rel="iLightbox[' + $value + ']"], [rel="iLightbox[' + $value + ']"]' ).iLightBox( $avada_lightbox.prepare_options( 'iLightbox[' + $value + ']' ) ) );
			});

			// Set filter to lightbox created
			jQuery( this ).data( 'lightbox', 'created' );
		}

		// Refresh the lightbox
		$avada_lightbox.refresh_lightbox();
	});

	// Setup filters and click events for the faq page
	jQuery( '.fusion-faqs, .fusion-faq-shortcode' ).each( function() {
		// Initialize the filters and corresponding posts
		// Check if filters are displayed
		var $faqs_page = jQuery( this ),
			$filters_wrapper = $faqs_page.find( '.fusion-filters' );

			// Make the faq posts visible
			jQuery( '.fusion-faqs-wrapper' ).fadeIn();

		if ( $filters_wrapper.length ) {

			// Make filters visible
			$filters_wrapper.fadeIn();

			// Set needed variables
			var $filters = $filters_wrapper.find( '.fusion-filter' ),
				$filter_active_element = $filters_wrapper.find( '.fusion-active' ).children( 'a' ),
				$filter_active =  $filter_active_element.attr( 'data-filter' ).substr( 1 ),
				$posts = jQuery( this ).find( '.fusion-faqs-wrapper .fusion-faq-post' );

			// Loop through filters
			if ( $filters ) {
				$filters.each( function() {
					var $filter = jQuery( this ),
						$filter_name = $filter.children( 'a' ).data( 'filter' );

					// Loop through post set
					if ( $posts ) {
						// If "All" filter is deactivated, hide posts for later check for active filter
						if ( $filter_active.length ) {
							$posts.hide();
						}

						$posts.each( function() {
							var $post = jQuery( this );

							// If a post belongs to an invisible filter, fade the filter in
							if ( $post.hasClass( $filter_name.substr( 1 ) ) ) {
								if ( $filter.hasClass( 'fusion-hidden' ) ) {
									$filter.removeClass( 'fusion-hidden' );
								}
							}

							// If "All" filter is deactivated, only show the items of the first filter (which is auto activated)
							if ( $filter_active.length && $post.hasClass( $filter_active ) ) {
								$post.show();
							}
						});
					}
				});
			}
		}

		// Handle the filter clicks
		$faqs_page .find( '.fusion-filters a' ).click( function(e) {
			e.preventDefault();

			var selector = jQuery( this ).attr( 'data-filter' );

			// Fade out the faq posts and fade in the ones matching the selector
			$faqs_page .find( '.fusion-faqs-wrapper .fusion-faq-post' ).fadeOut();
			setTimeout( function() {
				$faqs_page .find( '.fusion-faqs-wrapper .fusion-faq-post' + selector ).fadeIn();
			}, 400 );

			// Set the active
			jQuery( this ).parents( '.fusion-filters' ).find( '.fusion-filter' ).removeClass( 'fusion-active' );
			jQuery( this ).parent().addClass( 'fusion-active' );
		});
	});

	function isScrolledIntoView(elem)
	{
		var docViewTop = jQuery(window).scrollTop();
		var docViewBottom = docViewTop + jQuery(window).height();

		var elemTop = jQuery(elem).offset().top;
		var elemBottom = elemTop + jQuery(elem).height();

		return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
	}

	jQuery('.fusion-alert .close').click(function(e) {
		e.preventDefault();

		jQuery(this).parent().slideUp();
	});

	jQuery('input, textarea').placeholder();

	function checkForImage(url) {
		return( url.match(/\.(jpeg|jpg|gif|png)$/) !== null );
	}

	if(Modernizr.mq('only screen and (max-width: 479px)')) {
		jQuery('.overlay-full.layout-text-left .slide-excerpt p').each(function () {
			var excerpt = jQuery(this).html();
			var wordArray = excerpt.split(/[\s\.\?]+/); //Split based on regular expression for spaces
			var maxWords = 10; //max number of words
			var total_words = wordArray.length; //current total of words
			var newString = "";
			//Roll back the textarea value with the words that it had previously before the maximum was reached
			if (total_words > maxWords+1) {
				 for (var i = 0; i < maxWords; i++) {
					newString += wordArray[i] + " ";
				}
				jQuery(this).html(newString);
			}
		});

		jQuery('.fusion-portfolio .fusion-rollover-gallery').each(function () {
			var img = jQuery(this).attr('href');

			if(checkForImage(img) === true) {
				jQuery(this).parents('.fusion-image-wrapper').find('> img').attr('src', img).attr('width', '').attr('height', '');
			}
			jQuery(this).parents('.fusion-portfolio-post').css('width', 'auto');
			jQuery(this).parents('.fusion-portfolio-post').css('height', 'auto');
			jQuery(this).parents('.fusion-portfolio-one:not(.fusion-portfolio-one-text)').find('.fusion-portfolio-post').css('margin', '0');
		});

		if( jQuery('.fusion-portfolio').length ) {
			jQuery('.fusion-portfolio-wrapper').isotope();
		}
	}

	if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.content_break_point + 'px)' ) ) {
		jQuery('.tabs-vertical').addClass('tabs-horizontal').removeClass('tabs-vertical');
	}

	jQuery(window).on('resize', function() {
		if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.content_break_point + 'px)' ) ) {
			jQuery('.tabs-vertical').addClass('tabs-original-vertical');
			jQuery('.tabs-vertical').addClass('tabs-horizontal').removeClass('tabs-vertical');
		} else {
			jQuery('.tabs-original-vertical').removeClass('tabs-horizontal').addClass('tabs-vertical');
		}
	});

    // Text area limit expandability
    jQuery( '.textarea-comment' ).each( function() {
		jQuery( this ).css( 'max-width', jQuery( '#content').width() );
    });

    jQuery(window).on('resize', function() {
		jQuery( '.textarea-comment' ).each( function() {
			jQuery( this ).css( 'max-width', jQuery( '#content').width() );
		});
	});

	if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.content_break_point + 'px)' ) ) {
		 jQuery('.fullwidth-faded').each(function() {
		 	var bkgd_img = jQuery(this).css('background-image');
		 	jQuery(this).parent().css('background-image', bkgd_img);
		 	jQuery(this).remove();
		 });
	}

	// Remove gravity IE specific class
	jQuery( '.gform_wrapper' ).each( function() {
		jQuery( this ).removeClass( 'gf_browser_ie' );
	});

	// Content Boxes Link Area
	jQuery( '.link-area-box' ).on('click', function() {
		if ( jQuery( this ).data( 'link' ) ) {
 			if ( jQuery( this ).data( 'link-target' ) == '_blank' ) {
				window.open( jQuery( this ).data( 'link' ), '_blank' );
				jQuery( this ).find( '.heading-link' ).removeAttr( 'href' );
				jQuery( this ).find( '.fusion-read-more' ).removeAttr( 'href' );
			} else {
				window.location = jQuery( this ).data( 'link' );
			}
			jQuery( this ).find( '.heading-link' ).attr( 'target', '' );
			jQuery( this ).find( '.fusion-read-more' ).attr( 'target', '' );
		}
	});

	// Clean Horizontal and Vertical
	jQuery( '.link-type-button' ).each(function() {
		if( jQuery( this ).parents( '.content-boxes-clean-vertical' ).length >= 1 ) {
			var $button_height = jQuery( '.fusion-read-more-button' ).outerHeight();
			jQuery( this ).find( '.fusion-read-more-button' ).css( 'top', $button_height / 2 );
		}
	});

	jQuery( '.link-area-link-icon .fusion-read-more-button, .link-area-link-icon .fusion-read-more, .link-area-link-icon .heading' ).mouseenter(function() {
		jQuery( this ).parents( '.link-area-link-icon' ).addClass( 'link-area-link-icon-hover' );
	});
	jQuery( '.link-area-link-icon .fusion-read-more-button, .link-area-link-icon .fusion-read-more, .link-area-link-icon .heading' ).mouseleave(function() {
		jQuery( this ).parents( '.link-area-link-icon' ).removeClass( 'link-area-link-icon-hover' );
	});

	jQuery( '.link-area-box' ).mouseenter(function() {
		jQuery( this ).addClass( 'link-area-box-hover' );
	});
	jQuery( '.link-area-box' ).mouseleave(function() {
		jQuery( this ).removeClass( 'link-area-box-hover' );
	});
}); // end document_ready_1

jQuery(window).load(function() {
    if(cssua.ua.mobile === undefined) {
	    // Change opacity of page title bar on scrolling
	    if(js_local_vars.page_title_fading == '1') {
		    if(js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right') {
		    	jQuery('.fusion-page-title-wrapper').fusion_scroller({type: 'opacity', end_offset: '.fusion-page-title-captions > h1'});
		    } else {
			    jQuery('.fusion-page-title-wrapper').fusion_scroller({type: 'opacity', offset: 100});
			}
		}

		// Fading and blur effect for new fade="" param on full width boxes
	    jQuery('.fullwidth-faded').fusion_scroller({type: 'fading_blur'});
	}
});

/*
 * Dynamic javascript File Port
 */

function insertParam(url, parameterName, parameterValue, atStart){
	replaceDuplicates = true;

	if(url.indexOf('#') > 0){
		var cl = url.indexOf('#');
		urlhash = url.substring(url.indexOf('#'),url.length);
	} else {
		urlhash = '';
		var cl = url.length;
	}
	sourceUrl = url.substring(0,cl);

	var urlParts = sourceUrl.split("?");
	var newQueryString = "";

	if (urlParts.length > 1)
	{
		var parameters = urlParts[1].split("&");
		for (var i=0; (i < parameters.length); i++)
		{
			var parameterParts = parameters[i].split("=");
			if (!(replaceDuplicates && parameterParts[0] == parameterName))
			{
				if (newQueryString === "") {
					newQueryString = "?" + parameterParts[0] + "=" + (parameterParts[1]?parameterParts[1]:'');
				}
				else {
					newQueryString += "&";
					newQueryString += parameterParts[0] + "=" + (parameterParts[1]?parameterParts[1]:'');
				}
			}
		}
	}
	if (newQueryString === "")
		newQueryString = "?";

	if(atStart){
		newQueryString = '?'+ parameterName + "=" + parameterValue + (newQueryString.length>1?'&'+newQueryString.substring(1):'');
	} else {
		if (newQueryString !== "" && newQueryString != '?')
			newQueryString += "&";
		newQueryString += parameterName + "=" + (parameterValue?parameterValue:'');
	}
	return urlParts[0] + newQueryString + urlhash;
}

// Define YT_ready function.
var YT_ready = (function() {
	var onReady_funcs = [], api_isReady = false;
	/* @param func function	 Function to execute on ready
	 * @param func Boolean	  If true, all qeued functions are executed
	 * @param b_before Boolean  If true, the func will added to the first
	 position in the queue*/
	return function(func, b_before) {
		if (func === true) {
			api_isReady = true;
			while (onReady_funcs.length) {
				// Removes the first func from the array, and execute func
				onReady_funcs.shift()();
			}
		} else if (typeof func == "function") {
			if (api_isReady) func();
			else onReady_funcs[b_before?"unshift":"push"](func);
		}
	};
})();



function register_youtube_players() {
	if ( Number( js_local_vars.status_yt ) && window.yt_vid_exists === true ) {
		window.$youtube_players = [];

		jQuery( '.tfs-slider' ).each( function() {
			var $slider = jQuery( this );

			$slider.find( '[data-youtube-video-id]' ).find( 'iframe' ).each( function() {
				var $iframe = jQuery( this );

				YT_ready( function() {
					window.$youtube_players[$iframe.attr( 'id' )] = new YT.Player( $iframe.attr( 'id' ), {
						events: {
							'onReady': onPlayerReady( $iframe.parents( 'li' ) ),
							'onStateChange': onPlayerStateChange( $iframe.attr( 'id' ), $slider )
						}
					});
				});
			});
		});
	}
}

// Load the YouTube iFrame API
function load_youtube_iframe_api() {
	if ( Number( js_local_vars.status_yt ) && window.yt_vid_exists === true ) {
		var tag = document.createElement( 'script' );
		tag.src = "https://www.youtube.com/iframe_api";
		var firstScriptTag = document.getElementsByTagName( 'script' )[0];
		firstScriptTag.parentNode.insertBefore( tag, firstScriptTag );
	}
}

// This function will be called when the API is fully loaded
function onYouTubePlayerAPIReady() {YT_ready(true);}

function onPlayerStateChange( $frame, $slider ) {
	return function( $event ) {
		if ( $event.data == YT.PlayerState.PLAYING ) {
			jQuery( $slider ).flexslider( 'pause' );
		}

		if ( $event.data == YT.PlayerState.PAUSED ) {
			jQuery( $slider ).flexslider( 'play' );
		}

		if ( $event.data == YT.PlayerState.BUFFERING ) {
			jQuery( $slider ).flexslider( 'pause' );
		}

		if ( $event.data == YT.PlayerState.ENDED ) {
			if ( jQuery( $slider ).data( 'autoplay' ) == '1' ) {
				jQuery( $slider ).flexslider( 'play' );
			}
		}
	};
}
function onPlayerReady( $slide ) {
	return function( $event ) {
		if ( jQuery( $slide ).data( 'mute' ) == 'yes' ) {
			$event.target.mute();
		}
	};
}

function ytVidId(url) {
	var p = /^(?:https?:)?(\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
	return (url.match(p)) ? RegExp.$1 : false;
	//return (url.match(p)) ? true : false;
}

function playVideoAndPauseOthers( slider ) {
	// Play the youtube video inside the current slide
	var $current_slider_iframes = jQuery( slider ).find( '[data-youtube-video-id]' ).find( 'iframe' ),
		$current_slide = jQuery( slider ).data( 'flexslider' ).slides.eq( jQuery( slider ).data( 'flexslider' ).currentSlide ),
		$current_slide_iframe = $current_slide.find( '[data-youtube-video-id]' ).find( 'iframe' );

	// Stop all youtube videos
	$current_slider_iframes.each( function(i) {
		// Don't stop current video, but all others
		if ( jQuery( this ).attr( 'id' ) != $current_slide_iframe.attr( 'id' ) ) {
			window.$youtube_players[jQuery( this ).attr( 'id' )].stopVideo(); // stop instead of pause for preview images
		}
	});

	if ( $current_slide_iframe.length ) {
		if( ! $current_slide_iframe.parents('li').hasClass('clone') && $current_slide_iframe.parents('li').hasClass('flex-active-slide') && $current_slide_iframe.parents('li').attr('data-autoplay') == 'yes' ) { // play only if autoplay is setup

			window.$youtube_players[$current_slide_iframe.attr( 'id' )].playVideo();
		}

		if( $current_slide.attr( 'data-mute' ) == 'yes' ) {
			window.$youtube_players[$current_slide_iframe.attr( 'id' )].mute();
		}
	}

	jQuery(slider).find('video').each(function(i) {
		if( typeof jQuery(this)[0].pause === "function" ) {
			jQuery(this)[0].pause();
		}
		if(!jQuery(this).parents('li').hasClass('clone') && jQuery(this).parents('li').hasClass('flex-active-slide') && jQuery(this).parents('li').attr('data-autoplay') == 'yes') {
			if( typeof jQuery(this)[0].play === "function" ) {
				jQuery(this)[0].play();
			}
		}
	});
}

jQuery(document).ready(function() {

	jQuery('.fusion-fullwidth.video-background').each(function() {
		if(jQuery(this).find('> div').attr('data-youtube-video-id')) {
			window.yt_vid_exists = true;
		}
	});

	var iframes = jQuery('iframe');
	jQuery.each(iframes, function(i, v) {
		var src = jQuery(this).attr('src');
		if(src) {
			if(Number(js_local_vars.status_vimeo) && src.indexOf('vimeo') >= 1) {
				jQuery(this).attr('id', 'player_'+(i+1));
				var new_src = insertParam(src, 'api', '1', false);
				var new_src_2 = insertParam(new_src, 'player_id', 'player_'+(i+1), false);
				var new_src_3 = insertParam(new_src_2, 'wmode', 'opaque', false);

				jQuery(this).attr('src', new_src_3);
			}

			if(Number(js_local_vars.status_yt) && ytVidId(src)) {
				jQuery(this).attr('id', 'player_'+(i+1));

				var new_src = insertParam(src, 'enablejsapi', '1', false);
				var new_src_2 = insertParam(new_src, 'wmode', 'opaque', false);

				jQuery(this).attr('src', new_src_2);

				window.yt_vid_exists = true;
			}
		}
	});

	jQuery('.full-video, .video-shortcode, .wooslider .slide-content, .fusion-recent-works-carousel .fusion-video').not('#bbpress-forums .full-video, #bbpress-forums .video-shortcode, #bbpress-forums .wooslider .slide-content, #bbpress-forums .fusion-recent-works-carousel .fusion-video').fitVids();
	jQuery('#bbpress-forums').fitVids();

	register_youtube_players();

	load_youtube_iframe_api();
});

jQuery(window).load(function() {
	jQuery('.fusion-youtube-flash-fix').remove();
});

// Control header-v1 and sticky on tfs parallax pages

// Setting some global vars. Those are also needed for the correct header resizing on none parallax slider pages
var orig_logo_height = jQuery('.header-wrapper' ).find( '.logo' ).height();
var orig_logo_container_margin_top = String( jQuery('.header-wrapper' ).find( '.logo' ).data( 'margin-top' ) );
var orig_logo_container_margin_bottom = String( jQuery('.header-wrapper' ).find( '.logo' ).data( 'margin-bottom' ) );
var orig_menu_height = jQuery( '.header-wrapper .fusion-navbar-nav > li > a' ).outerHeight();
if( jQuery( '#wrapper' ).length >= 1 ) {
	var wrapper_position = jQuery( '#wrapper' ).position().left;
} else {
	var wrapper_position;
}
var is_parallax_tfs_slider = false;

if ( ! orig_logo_container_margin_top ) {
	orig_logo_container_margin_top = '0px';
}

if ( ! orig_logo_container_margin_bottom ) {
	orig_logo_container_margin_bottom = '0px';
}

jQuery(window).load(function() {
	var headerHeight = jQuery( '.fusion-header-wrapper' ).height();

	if(jQuery('.sidebar').is(':visible')) {
		jQuery('.post-content .fusion-portfolio').each(function() {
			var columns = jQuery(this).data('columns');
			jQuery(this).addClass('fusion-portfolio-'+columns+'-sidebar');
		});
	}

	// Portfolio isotope loading
	if ( jQuery().isotope && jQuery( '.fusion-portfolio .fusion-portfolio-wrapper' ).length ) {
		jQuery( '.fusion-portfolio .fusion-portfolio-wrapper' ).each( function() {
			jQuery( this ).next( '.fusion-load-more-button' ).fadeIn();

			// Resize the placeholder images correctly in "fixed" picture size carousels
			if ( jQuery( this ).data( 'picturesize' ) == 'fixed' ) {
				jQuery( this ).find( '.fusion-placeholder-image' ).each( function() {
					jQuery( this ).css(	{
						'height': jQuery( this ).parents( '.fusion-portfolio-post' ).siblings().find( 'img' ).first().height(),
						'width': jQuery( this ).parents( '.fusion-portfolio-post' ).siblings().find( 'img' ).first().width()
					});

				});
			} else {
				jQuery( this ).find( '.fusion-placeholder-image' ).each( function() {
					jQuery( this ).css(	{
						'width': jQuery( this ).parents( '.fusion-portfolio-post' ).siblings().first().find( 'img' ).width()
					});

				});
			}

			var $isotope_filter = '',
				$filters_container = jQuery( this ).parents( '.fusion-portfolio' ).find( '.fusion-filters' );

			// Check if filters are displayed
			if ( $filters_container.length ) {

				// Set needed variables
				var $filters = $filters_container.find( '.fusion-filter' ),
					$filter_active = $filters_container.find( '.fusion-active' ),
					$filter_active_link = $filter_active.children( 'a' ),
					$filter_active_data_slug = $filter_active_link.attr( 'data-filter' ).substr( 1 ),
					$posts = jQuery( this ).find( '.fusion-portfolio-post' ),
					$lightbox_instances = [];

				// Loop through filters
				if ( $filters ) {
					$filters.each( function() {
						var $filter = jQuery( this ),
							$filter_name = $filter.children( 'a' ).data( 'filter' );

						// Loop through initial post set
						if ( $posts ) {
							// If "All" filter is deactivated, hide posts for later check for active filter
							if ( $filter_active_data_slug.length ) {
								$posts.hide();
							}

							jQuery( '.fusion-filters' ).show();

							$posts.each( function() {
								var $post = jQuery( this ),
									$post_gallery_name = $post.find( '.fusion-rollover-gallery' ).data( 'rel' );

								// If a post belongs to an invisible filter, fade filter in
								if ( $post.hasClass( $filter_name.substr( 1 ) ) ) {
									if ( $filter.hasClass( 'fusion-hidden' ) ) {
										$filter.removeClass( 'fusion-hidden' );
									}
								}

								// If "All" filter is deactivated, only show the items of the first filter (which is auto activated)
								if ( $filter_active_data_slug.length && $post.hasClass( $filter_active_data_slug ) ) {
									$post.show();

									// Set the lightbox gallery
									if ( $post_gallery_name ) {
										var $lightbox_filter = $post_gallery_name.replace( 'gallery', $filter_active_data_slug );

										$post.find( '.fusion-rollover-gallery' ).attr( 'data-rel', $lightbox_filter );
										if ( jQuery.inArray( $lightbox_filter, $lightbox_instances ) === -1 ) {
											$lightbox_instances.push( $lightbox_filter );
										}
									}
								}
							});
						}
					});
				}

				if ( $filter_active_data_slug.length ) {
					// If "All" filter is deactivated set the sotope filter to the first active element
					$isotope_filter = '.' + $filter_active_data_slug;

					// Create new lightbox instance for the new galleries
					jQuery.each( $lightbox_instances, function( $key, $value ) {
						$il_instances.push( jQuery( '[data-rel="' + $value + '"], [rel="' + $value + '"]' ).iLightBox( $avada_lightbox.prepare_options( $value ) ) );
					});

					// Refresh the lightbox
					$avada_lightbox.refresh_lightbox();

					// Set active filter to lightbox created
					$filter_active_link.data( 'lightbox', 'created' );
				}
			}

			// Refresh the scrollspy script for one page layouts
			jQuery( '[data-spy="scroll"]' ).each(function () {
				var $spy = jQuery( this ).scrollspy( 'refresh' );
			});

			var $portfolio_wrapper = jQuery( this ),
				$portfolio_wrapper_id = $portfolio_wrapper.attr( 'id' );

			// Done for multiple instances of recent works shortcode. Isotope needs ids to distinguish between instances
			if ( $portfolio_wrapper_id ) {
				$portfolio_wrapper = jQuery( '#' + $portfolio_wrapper_id );
			}

			setTimeout( function() {
				// Initialize isotope depending on the portfolio layout
				if ( $portfolio_wrapper.parent().hasClass( 'fusion-portfolio-one' ) ) {
					window.$portfolio_isotope = $portfolio_wrapper;
					window.$portfolio_isotope.isotope({
						// Isotope options
						itemSelector: '.fusion-portfolio-post',
						layoutMode: 'vertical',
						transformsEnabled: false,
						isOriginLeft: jQuery( '.rtl' ).length ? false : true,
						filter: $isotope_filter
					});
				} else {
					window.$portfolio_isotope = $portfolio_wrapper;
					window.$portfolio_isotope.isotope({
						// Isotope options
						itemSelector: '.fusion-portfolio-post',
						resizable: true,
						layoutMode: js_local_vars.isotope_type,
						transformsEnabled: false,
						isOriginLeft: jQuery( '.rtl' ).length ? false : true,
						filter: $isotope_filter
					});
				}
			}, 1 );

			// Fade in placeholder images
			var $placeholder_images = jQuery( this ).find( '.fusion-portfolio-post .fusion-placeholder-image' );
			$placeholder_images.each( function() {
				jQuery( this ).parents( '.fusion-portfolio-content-wrapper, .fusion-image-wrapper' ).animate({ opacity: 1 });
			});

			// Fade in videos
			var $videos = jQuery( this ).find( '.fusion-portfolio-post .fusion-video' );
			$videos.each( function() {
				jQuery( this ).animate({ opacity: 1 });
				jQuery( this ).parents( '.fusion-portfolio-content-wrapper' ).animate({opacity: 1});
			});

			$videos.fitVids();

			// Portfolio Images Loaded Check
			window.$portfolio_images_index = 0;

			jQuery( this ).imagesLoaded().progress( function( $instance, $image ) {
				if( jQuery( $image.img ).parents( '.fusion-portfolio-content-wrapper' ).length >= 1 ) {
					jQuery( $image.img, $placeholder_images ).parents( '.fusion-portfolio-content-wrapper' ).delay( 100 * window.$portfolio_images_index ).animate({
						opacity: 1
					});
				} else {
					jQuery( $image.img, $placeholder_images ).parents( '.fusion-image-wrapper' ).delay( 100 * window.$portfolio_images_index ).animate({
						opacity: 1
					});
				}

				window.$portfolio_images_index++;
			});

			setTimeout(
				function() {
					jQuery( window ).trigger( 'resize' );
				}, 250
			);
		});
	}

	if(jQuery().flexslider) {
		var avada_ytplayer;

		if(Number(js_local_vars.status_vimeo)) {
			function ready(player_id) {
				var froogaloop = $f(player_id);

				var slide = jQuery('#' + player_id).parents('li');

				froogaloop.addEvent('play', function (data) {
					jQuery('#' + player_id).parents('li').parent().parent().flexslider("pause");
				});

				froogaloop.addEvent('pause', function (data) {
					if(jQuery(slide).attr('data-loop') == 'yes') {
						jQuery('#' + player_id).parents('li').parent().parent().flexslider("pause");
					} else {
						jQuery('#' + player_id).parents('li').parent().parent().flexslider("play");
					}
				});
			}

			var vimeoPlayers = jQuery('.flexslider').find('iframe'), player;

			jQuery('.flexslider').find('iframe').each(function () {
				var id = jQuery(this).attr('id');

				if(id) {
					$f(id).addEvent('ready', ready);
				}
			});

			function addEvent(element, eventName, callback) {
				if (element.addEventListener) {
					element.addEventListener(eventName, callback, false);
				} else {
					element.attachEvent(eventName, callback, false);
				}
			}
		}

		jQuery('.tfs-slider').each(function() {
			var this_tfslider = this;

			var first_slide = jQuery(this_tfslider).find('li').get(0);

			if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
				jQuery(this_tfslider).data('parallax', 0);
				jQuery(this_tfslider).data('full_screen', 0);
			}

			if(cssua.ua.tablet_pc) {
				jQuery(this_tfslider).data('parallax', 0);
			}

			if(cssua.ua.mobile || Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)')) {
				jQuery(this_tfslider).data('parallax', 0);
			}

			wpadminbarHeight = 0;
			if(jQuery('#wpadminbar').length >= 1) {
				var wpadminbarHeight = jQuery('#wpadminbar').height();
			}

			if(jQuery(this_tfslider).parents('#sliders-container').length >= 1 && jQuery(this_tfslider).data('parallax') === 1) {
				jQuery('.fusion-header').addClass('fusion-header-backface');
			}

			if(jQuery(this_tfslider).data('full_screen') == 1) {
				var sliderHeight = jQuery(window).height();

				if(jQuery(this_tfslider).parents('#sliders-container').next().hasClass('fusion-header-wrapper')) {
					sliderHeight = sliderHeight + (headerHeight - wpadminbarHeight);
				}

				if ( jQuery( this_tfslider ).data( 'parallax' ) === 0 ) {
					if ( js_local_vars.header_transparency == 1 || js_local_vars.slider_position == 'above' ) {
						sliderHeight = jQuery( window ).height() - wpadminbarHeight;
					} else {
						sliderHeight = jQuery( window ).height() - ( headerHeight + wpadminbarHeight );
					}
				}

				if(  Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
					if ( js_local_vars.slider_position == 'below' ) {
						var sliderHeight = jQuery( window ).height() - ( headerHeight + wpadminbarHeight );
					} else {
						var sliderHeight = jQuery( window ).height() - wpadminbarHeight;
					}
				}

				jQuery( this_tfslider ).find( 'video' ).each(function() {
					var aspect_ratio = jQuery( this ).width() / jQuery( this ).height(),
						arc_sliderWidth = aspect_ratio * sliderHeight,
						arc_sliderLeft = '-' + ( ( arc_sliderWidth - jQuery( this_tfslider ).width() ) / 2 ) + 'px',
						compare_width = jQuery( this_tfslider ).parent().parent().parent().width();
					if ( jQuery( this_tfslider ).parents( '.post-content' ).length ) {
						compare_width = jQuery( this_tfslider ).width();
					}

					if ( compare_width > arc_sliderWidth ) {
						arc_sliderWidth = '100%';
						arc_sliderLeft = 0;
						$position = 'static';
					} else {
						$position = 'absolute';
					}
					jQuery( this ).width( arc_sliderWidth );
					jQuery( this ).css({
						'left': arc_sliderLeft,
						'position': $position
					});
				});
			} else {
				var sliderWidth = jQuery(this_tfslider).data('slider_width');

				if(sliderWidth.indexOf('%') != -1) {
					sliderWidth = jQuery(first_slide).find('.background-image').data('imgwidth');
					if( ! sliderWidth && ! cssua.ua.mobile ) {
						sliderWidth = jQuery(first_slide).find('video').width();
					}

					if( ! sliderWidth ) {
						sliderWidth = 940;
					}

					jQuery(this_tfslider).data('first_slide_width', sliderWidth);

					if(sliderWidth < jQuery(this_tfslider).data('slider_width')) {
						sliderWidth = jQuery(this_tfslider).data('slider_width');
					}

					var percentage_width = true;
				} else {
					sliderWidth = parseInt(jQuery(this_tfslider).data('slider_width'));
				}

				var sliderHeight = parseInt(jQuery(this_tfslider).data('slider_height'));
				var aspect_ratio = sliderHeight / sliderWidth;

				if(aspect_ratio < 0.5) {
					aspect_ratio = 0.5;
				}

				var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
				if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
					compare_width = jQuery(this_tfslider).width();
				}
				var sliderHeight = aspect_ratio * compare_width;

				if(sliderHeight > parseInt(jQuery(this_tfslider).data('slider_height'))) {
					sliderHeight = parseInt(jQuery(this_tfslider).data('slider_height'));
				}

				if(sliderHeight < 200) {
					sliderHeight = 200;
				}
			}

			if(jQuery(this_tfslider).data('full_screen') == 1) {
				jQuery(this_tfslider).css('max-width', '100%');
				jQuery(this_tfslider).find('.slides, .background').css('width', '100%');
			}

			if((js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right') && ! jQuery(this_tfslider).hasClass('fixed-width-slider') && jQuery(this_tfslider).data('parallax') == 1) {
				jQuery(this_tfslider).css('max-width', jQuery('#wrapper').width());
				if(jQuery('body').hasClass('side-header-left')) {
					jQuery(this_tfslider).css('left', jQuery('#side-header').width() + 1);
				} else if(jQuery('body').hasClass('side-header-right')) {
					jQuery(this_tfslider).css('right', jQuery('#side-header').width() + 1);
				}
			}

			jQuery(this_tfslider).parents('.fusion-slider-container').css('height', sliderHeight);
			jQuery(this_tfslider).css('height', sliderHeight);
			jQuery(this_tfslider).find('.background, .mobile_video_image').css('height', sliderHeight);

			if(jQuery('.layout-boxed-mode').length >= 1) {
				var boxed_mode_width = jQuery('.layout-boxed-mode #wrapper').width();
				jQuery(this_tfslider).css('width', boxed_mode_width);
				jQuery(this_tfslider).css('margin-left', 'auto');
				jQuery(this_tfslider).css('margin-right', 'auto');

				if(jQuery(this_tfslider).data('parallax') == 1 && ! Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)')) {
					jQuery(this_tfslider).css('left', '50%');
					if( js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right' ) {
						boxed_mode_width = jQuery('.layout-boxed-mode #wrapper').width() - jQuery('.layout-boxed-mode #side-header').width();
						if( js_local_vars.header_position == 'Right' ) {
							boxed_mode_width = jQuery('.layout-boxed-mode #wrapper').width() + jQuery('.layout-boxed-mode #side-header').width();
						}
						jQuery(this_tfslider).css('margin-left', '-' + Math.floor( boxed_mode_width / 2 ) + 'px');
					} else {
						jQuery(this_tfslider).css('margin-left', '-' + (boxed_mode_width / 2) + 'px');
					}
				}
				jQuery(this_tfslider).find('.slides, .background').css('width', '100%');
			}

			if(cssua.ua.mobile) {
				jQuery(this_tfslider).find('.fusion-button').each(function() {
					jQuery(this).removeClass('button-xlarge button-large button-medium');
					jQuery(this).addClass('button-small');
				});
				jQuery(this_tfslider).find('li').each(function() {
					jQuery(this).attr('data-autoplay', 'no');
					jQuery(this).data('autoplay', 'no');
				});
			}

			jQuery(this_tfslider).find('a.button').each(function() {
				jQuery(this).data('old', jQuery(this).attr('class'));
			});

			if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.content_break_point + 'px)' ) ) {
				jQuery(this_tfslider).find('.fusion-button').each(function() {
					jQuery(this).data('old', jQuery(this).attr('class'));
					jQuery(this).removeClass('button-xlarge button-large button-medium');
					jQuery(this).addClass('button-small');
				});
			} else {
				jQuery(this_tfslider).find('a.button').each(function() {
					jQuery(this).attr('class', jQuery(this).data('old'));
				});
			}

			if(jQuery(this_tfslider).data('parallax') == 1) {

				if ( Modernizr.mq( 'only screen and (min-width: ' + js_local_vars.side_header_break_point + 'px)' ) && js_local_vars.header_transparency == 0 && js_local_vars.slider_position == 'below' ) {
					var slideContent = jQuery( this_tfslider ).find( '.slide-content-container' );

					jQuery( slideContent ).each( function() {
						jQuery( this ).css( 'padding-top',  headerHeight + 'px' );
					});
				}

				jQuery(window).scroll(function () {
					if(jQuery(window).scrollTop() >= jQuery(this_tfslider).parents('#sliders-container').position().top + jQuery(this_tfslider).parents('#sliders-container').height()) {
						jQuery(this_tfslider).css('display', 'none');
					} else {
						jQuery(this_tfslider).css('display', 'block');
					}
				});
			}

			var resize_width = jQuery(window).width();
			var resize_height = jQuery(window).height();

			jQuery(window).on('resize', function() { // start_tfslider_resize
				if( jQuery(window).width() != resize_width || jQuery(window).height() != resize_height ) {
					var headerHeight = jQuery( '.fusion-header-wrapper' ).height();
					var wpadminbarHeight = 0;

					if(jQuery('#wpadminbar').length >= 1) {
						var wpadminbarHeight = jQuery('#wpadminbar').height();
					}

					if(jQuery(this_tfslider).data('full_screen') == 1) {
						var sliderHeight = jQuery(window).height();

						if(  Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) && jQuery( '#side-header' ).length ) {
							var headerHeight = jQuery( '#side-header' ).outerHeight();
						}

						if( js_local_vars.header_transparency == 1 ){
							if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) && js_local_vars.slider_position != 'above' ) {
								var sliderHeight = jQuery( window ).height() - ( headerHeight + wpadminbarHeight );
							}else{
								var sliderHeight = jQuery( window ).height() - wpadminbarHeight;
							}
						}else{
							if ( js_local_vars.slider_position != 'above' ) {
								var sliderHeight = jQuery( window ).height() - ( headerHeight + wpadminbarHeight );
							}else{
								var sliderHeight = jQuery( window ).height() - wpadminbarHeight;
							}
						}

						var maxHeight = Math.max.apply(
							null,
							jQuery(this_tfslider).find('.slide-content').map(function() {
								return jQuery(this).outerHeight();
							}).get()
						);

						maxHeight = maxHeight + 40;

						if( sliderHeight < maxHeight ) {
							sliderHeight = maxHeight;
						}

						// timeout to prevent self hosted video position breaking on re-size with sideheader.
						setTimeout(
							function() {
								jQuery( this_tfslider ).find( 'video' ).each(function() {
									var aspect_ratio = jQuery( this ).width() / jQuery( this ).height(),
										arc_sliderWidth = aspect_ratio * sliderHeight,
										arc_sliderLeft = '-' + ( ( arc_sliderWidth - jQuery( this_tfslider ).width() ) / 2 ) + 'px',
										compare_width = jQuery( this_tfslider ).parent().parent().parent().width();
									if ( jQuery( this_tfslider ).parents( '.post-content' ).length ) {
										compare_width = jQuery( this_tfslider ).width();
									}

									if ( compare_width > arc_sliderWidth ) {
										arc_sliderWidth = '100%';
										arc_sliderLeft = 0;
										$position = 'static';
									} else {
										$position = 'absolute';
									}
									jQuery( this ).width( arc_sliderWidth );
									jQuery( this ).css({
										'left': arc_sliderLeft,
										'position': $position
									});
								});

							}, 100
						);
					} else {
						var sliderWidth = jQuery(this_tfslider).data('slider_width');

						if(sliderWidth.indexOf('%') != -1) {
							sliderWidth = jQuery(this_tfslider).data('first_slide_width');

							if( sliderWidth < jQuery(this_tfslider).data('slider_width') ) {
								sliderWidth = jQuery(this_tfslider).data('slider_width');
							}

							var percentage_width = true;
						} else {
							sliderWidth = parseInt(jQuery(this_tfslider).data('slider_width'));
						}

						var sliderHeight = parseInt(jQuery(this_tfslider).data('slider_height'));
						var aspect_ratio = sliderHeight / sliderWidth;

						if(aspect_ratio < 0.5) {
							aspect_ratio = 0.5;
						}

						var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
						if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
							compare_width = jQuery(this_tfslider).width();
						}
						var sliderHeight = aspect_ratio * compare_width;

						if(sliderHeight > parseInt(jQuery(this_tfslider).data('slider_height'))) {
							sliderHeight = parseInt(jQuery(this_tfslider).data('slider_height'));
						}

						if(sliderHeight < 200) {
							sliderHeight = 200;
						}

						jQuery(this_tfslider).find('video').each(function() {
							var aspect_ratio = jQuery(this).width() / jQuery(this).height();
							var arc_sliderWidth = aspect_ratio * sliderHeight;

							if(arc_sliderWidth < sliderWidth && !jQuery(this_tfslider).hasClass('full-width-slider')) {
								arc_sliderWidth = sliderWidth;
							}

							var arc_sliderLeft = '-' + ((arc_sliderWidth - jQuery(this_tfslider).width()) / 2) + 'px';
							var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
							if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
								compare_width = jQuery(this_tfslider).width();
							}
							if(compare_width > arc_sliderWidth && percentage_width === true && jQuery(this_tfslider).data('full_screen') != 1) {
								arc_sliderWidth = '100%';
								arc_sliderLeft = 0;
							}
							jQuery(this).width(arc_sliderWidth);
							jQuery(this).css('left', arc_sliderLeft);
						});
					}

					if ( Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.content_break_point + 'px)' ) ) {
						jQuery(this_tfslider).find('.fusion-button').each(function() {
							jQuery(this).removeClass('button-xlarge button-large button-medium');
							jQuery(this).addClass('button-small');
						});
					} else {
						jQuery(this_tfslider).find('.fusion-button').each(function() {
							jQuery(this).attr('class', jQuery(this).data('old'));
						});
					}

					if(jQuery(this_tfslider).data('full_screen') == 1 && jQuery(this_tfslider).data('animation') == "fade" ) {
						jQuery(this_tfslider).css('max-width', '100%');
						jQuery(this_tfslider).find('.slides, .background').css('width', '100%');
					}

					if((js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right') && ! jQuery(this_tfslider).hasClass('fixed-width-slider') && jQuery(this_tfslider).data('parallax') == 1) {
						jQuery(this_tfslider).css('max-width', jQuery('#wrapper').width());
						if(jQuery('body').hasClass('side-header-left')) {
							jQuery(this_tfslider).css('left', jQuery('#side-header').width() + 1);
						} else if(jQuery('body').hasClass('side-header-right')) {
							jQuery(this_tfslider).css('right', jQuery('#side-header').width() + 1);
						}
					}

					jQuery(this_tfslider).parents('.fusion-slider-container').css('height', sliderHeight);
					jQuery(this_tfslider).parents('.fusion-slider-container').css('max-height', sliderHeight );
					jQuery(this_tfslider).css('height', sliderHeight);
					jQuery(this_tfslider).find('.background, .mobile_video_image').css('height', sliderHeight);

					if(jQuery('.layout-boxed-mode').length >= 1 && jQuery(this_tfslider).parents('.post-content').length === 0) {
						var boxed_mode_width = jQuery('.layout-boxed-mode #wrapper').width();
						jQuery(this_tfslider).css('width', boxed_mode_width);
						jQuery(this_tfslider).css('margin-left', 'auto');
						jQuery(this_tfslider).css('margin-right', 'auto');

						if(jQuery(this_tfslider).data('parallax') == 1 && ! Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)')) {
							jQuery(this_tfslider).css('left', '50%');
							if( js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right' ) {
								boxed_mode_width = jQuery('.layout-boxed-mode #wrapper').width() - jQuery('.layout-boxed-mode #side-header').width();
								if( js_local_vars.header_position == 'Right' ) {
									boxed_mode_width = jQuery('.layout-boxed-mode #wrapper').width() + jQuery('.layout-boxed-mode #side-header').width();
								}
								jQuery(this_tfslider).css('margin-left', '-' + Math.floor( boxed_mode_width / 2 ) + 'px');
							} else {
								jQuery(this_tfslider).css('margin-left', '-' + (boxed_mode_width / 2) + 'px');
							}
						}

						if(jQuery(this_tfslider).data('animation') != 'slide') {
							jQuery(this_tfslider).find('.slides').css('width', '100%');
						}
						jQuery(this_tfslider).find('.background').css('width', '100%');
					}

					if ( 1 === jQuery( this_tfslider ).data( 'parallax' ) && ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
						jQuery( this_tfslider ).css( 'position', 'fixed' );
						if ( 'absolute' != jQuery( '.fusion-header-wrapper' ).css( 'position' ) ) {
							jQuery( '.fusion-header-wrapper' ).css( 'position', 'relative' );

							var $navigationArrowsTranslate = 'translate(0, ' + ( headerHeight / 2 ) + 'px)';

							if ( js_local_vars.slider_position == 'below' ) {
								jQuery( this_tfslider ).parents( '.fusion-slider-container' ).css( 'margin-top', '-' + headerHeight + 'px' );
							}
						} else {
							var $navigationArrowsTranslate = 'translate(0, 0)';
						}

						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( '-webkit-transform', $navigationArrowsTranslate );
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( '-ms-transform', $navigationArrowsTranslate );
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( '-o-transform', $navigationArrowsTranslate );
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( '-moz-transform', $navigationArrowsTranslate );;
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( 'transform', $navigationArrowsTranslate );

						jQuery('#main, .fusion-footer-widget-area, .fusion-footer-copyright-area, .fusion-page-title-bar').css('position', 'relative');
						jQuery('#main, .fusion-footer-widget-area, .fusion-footer-copyright-area, .fusion-page-title-bar').css('z-index', '3');
						jQuery('.fusion-header-wrapper').css('z-index', '5');
						jQuery('.fusion-header-wrapper').css('height', headerHeight);


						if(jQuery(this_tfslider).hasClass('fixed-width-slider')) {
							if( js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right' ) {
								if( jQuery(this_tfslider).parents( '#sliders-container' ).length ) {
									var wrapping_container = jQuery( '#sliders-container' );
								} else {
									var wrapping_container = jQuery( '#main' );
								}

								if( wrapping_container.width() < parseFloat( jQuery(this_tfslider).parent().css( 'max-width' ) ) ) {
									jQuery(this_tfslider).css( 'max-width', wrapping_container.width() );
								} else {
									jQuery(this_tfslider).css( 'max-width', jQuery(this_tfslider).parent().css( 'max-width' ) );
								}

								if( wrapping_container.width() < parseFloat( jQuery(this_tfslider).parent().css( 'max-width' ) ) ) {
									jQuery(this_tfslider).css( 'max-width', wrapping_container.width() );
								} else {
									jQuery(this_tfslider).css( 'max-width', jQuery(this_tfslider).parent().css( 'max-width' ) );
								}

								if( js_local_vars.header_position == 'Left' ) {
									var fixed_width_center = '-' + ((jQuery(this_tfslider).width() - jQuery( '#side-header' ).width() ) / 2) + 'px';
								} else {
									var fixed_width_center = '-' + ((jQuery(this_tfslider).width() + jQuery( '#side-header' ).width() ) / 2) + 'px';
								}

								if( ( -1 ) * fixed_width_center > jQuery(this_tfslider).width() ) {
									fixed_width_center = ( -1 ) * jQuery(this_tfslider).width();
								}
							} else {
								var fixed_width_center = '-' + (jQuery(this_tfslider).width() / 2) + 'px';
							}
							jQuery(this_tfslider).css('left', '50%');
							jQuery(this_tfslider).css('margin-left', fixed_width_center);
						}

						jQuery(this_tfslider).find('.flex-control-nav').css('bottom', (headerHeight / 2));

						if ( js_local_vars.header_transparency == 0 && js_local_vars.slider_position == 'below' ) {
							var slideContent = jQuery( this_tfslider ).find( '.slide-content-container' );
							jQuery( slideContent ).each( function() {
								jQuery( this ).css( 'padding-top',  headerHeight + 'px' );
							});
						}
					} else if(jQuery(this_tfslider).data('parallax') == 1 && Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)')) {
						jQuery(this_tfslider).css('position', 'relative');
						jQuery(this_tfslider).css('left', '0');
						jQuery(this_tfslider).css('margin-left', '0');
						if( jQuery( '.fusion-header-wrapper' ).css( 'position' ) != 'absolute' ) {
							jQuery('.fusion-header-wrapper').css('position', 'relative');
						}
						jQuery('#main, .fusion-footer-widget-area, .fusion-footer-copyright-area, .fusion-page-title-bar').css('position', 'relative');
						jQuery('#main, .fusion-footer-widget-area, .fusion-footer-copyright-area, .fusion-page-title-bar').css('z-index', '3');
						jQuery('.fusion-header-wrapper').css('z-index', '5');
						jQuery('.fusion-header-wrapper').css('height', 'auto');
						jQuery(this_tfslider).parents('.fusion-slider-container').css('margin-top', '');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('-webkit-transform', 'translate(0, 0)');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('-ms-transform', 'translate(0, 0)');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('-o-transform', 'translate(0, 0)');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('-moz-transform', 'translate(0, 0)');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('transform', 'translate(0, 0)');

						jQuery(this_tfslider).find('.flex-control-nav').css('bottom', 0);

						if ( js_local_vars.header_transparency == 0 && js_local_vars.slider_position == 'below' ) {
							var slideContent = jQuery( this_tfslider ).find( '.slide-content-container' );
							jQuery( slideContent ).each( function() {
								jQuery( this ).css( 'padding-top',  '' );
							});
						}
					}

					if(Modernizr.mq('only screen and (max-width: 640px)')) {
						jQuery(this_tfslider).parents('.fusion-slider-container').css('height', sliderHeight);
						jQuery(this_tfslider).css('height', sliderHeight);
						jQuery(this_tfslider).find('.background, .mobile_video_image').css('height', sliderHeight);
					} else if(Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)')) {
						jQuery(this_tfslider).parents('.fusion-slider-container').css('height', sliderHeight);
						jQuery(this_tfslider).css('height', sliderHeight);
						jQuery(this_tfslider).find('.background, .mobile_video_image').css('height', sliderHeight);
					} else {
						jQuery(this_tfslider).parents('.fusion-slider-container').css('height', sliderHeight);
						jQuery(this_tfslider).css('height', sliderHeight);
						jQuery(this_tfslider).find('.background, .mobile_video_image').css('height', sliderHeight);
					}

					var slideContent = jQuery(this_tfslider).find('.slide-content-container');

					if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
						jQuery(this_tfslider).parents('.fusion-slider-container').css('height', 'auto');
						jQuery(this_tfslider).css('height', 'auto');
						jQuery(this_tfslider).parents('.fusion-slider-container').css('max-height', 'none');
						jQuery(this_tfslider).find('.mobile_video_image').each(function() {
							var img_url = jQuery('.mobile_video_image').css('background-image').replace('url(', '').replace(')', '');
							if(img_url) {
								var preview_image = new Image();
								preview_image.name = img_url;
								preview_image.src = img_url;
								preview_image.onload = function() {
									var ar = this.height / this.width;
									var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
									if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
										compare_width = jQuery(this_tfslider).width();
									}
									var mobile_preview_height = ar * compare_width;
									if(mobile_preview_height < sliderHeight) {
										jQuery(this_tfslider).find('.mobile_video_image').css('height', mobile_preview_height);
										jQuery(this_tfslider).css('height', mobile_preview_height);
									}
								};
							}
						});
					}

					if(js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right') {
						if( jQuery(this_tfslider).parents('#sliders-container').length >= 1 ) {
							var slideContent = jQuery(this_tfslider).parents('#sliders-container').find('.slide-content-container');
							jQuery(slideContent).each(function() {
								if( ! Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)') ) {
									if(jQuery(this).hasClass('slide-content-right')) {
										jQuery(this).find('.slide-content').css('margin-right', '100px');
									} else if(jQuery(this).hasClass('slide-content-left')) {
										jQuery(this).find('.slide-content').css('margin-left', '100px');
									}
								} else {
									jQuery(this).find('.slide-content').css('margin-left', '');
									jQuery(this).find('.slide-content').css('margin-right', '');
								}
							});
						}
					}

					if(Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)')) {
							jQuery('.fusion-header-wrapper').css('height', '' );
					}

					resize_width = jQuery(window).width();
					resize_height = jQuery(window).height();
				}
			}); // // end_tfslider_resize

			if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
				jQuery(this_tfslider).css('max-width', '100%');
				if(jQuery(this_tfslider).data('animation') != 'slide') {
					jQuery(this_tfslider).find('.slides').css('max-width', '100%');
				}
			}

			jQuery(this_tfslider).find('video').each(function() {
				if( typeof jQuery(this)[0].pause === "function" ) {
					jQuery(this)[0].pause();
				}
			});

			jQuery(this_tfslider).flexslider({
				animation: jQuery(this_tfslider).data('animation'),
				slideshow: jQuery(this_tfslider).data('autoplay'),
				slideshowSpeed: jQuery(this_tfslider).data('slideshow_speed'),
				animationSpeed: jQuery(this_tfslider).data('animation_speed'),
				controlNav: Boolean(Number(jQuery(this_tfslider).data('pagination_circles'))),
				directionNav: Boolean(Number(jQuery(this_tfslider).data('nav_arrows'))),
				animationLoop: Boolean(Number(jQuery(this_tfslider).data('loop'))),
				smoothHeight: true,
				pauseOnHover: false,
				useCSS: true,
				video: true,
				touch: true,
				prevText: '&#xe61e;',
				nextText: '&#xe620;',
				start: function(slider) {
					jQuery( this_tfslider ).parent().find( '.fusion-slider-loading' ).remove();

					wpadminbarHeight = 0;
					if(jQuery('#wpadminbar').length >= 1) {
						var wpadminbarHeight = jQuery('#wpadminbar').height();
					}

					jQuery(slider.slides.eq(slider.currentSlide)).find('.slide-content-container').show();

					// Remove title separators and padding, when there is not enough space
					jQuery( slider.slides.eq( slider.currentSlide ) ).find( '.fusion-title' ).fusion_responsive_title_shortcode();

					var maxHeight = Math.max.apply(
						null,
						jQuery(this_tfslider).find('.slide-content').map(function() {
					    	return jQuery(this).outerHeight();
					    }).get()
					);

					maxHeight = maxHeight + 40;

					if(jQuery(this_tfslider).data('full_screen') == 1) {
						var sliderHeight = jQuery(window).height();

						if(jQuery(this_tfslider).parents('#sliders-container').next().hasClass('fusion-header-wrapper')) {
							sliderHeight = sliderHeight + (headerHeight - wpadminbarHeight);
						}

						if ( jQuery( this_tfslider ).data( 'parallax' ) === 0 ) {
							if ( js_local_vars.header_transparency == 1 || js_local_vars.slider_position == 'above' ) {
								sliderHeight = jQuery( window ).height() - wpadminbarHeight;
							} else {
								sliderHeight = jQuery( window ).height() - ( headerHeight + wpadminbarHeight );
							}
						}

 						if(  Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
							if ( js_local_vars.slider_position == 'below' ) {
								if ( jQuery( "#side-header" ).length ) {
									var sideHeight = jQuery("#side-header").outerHeight(),
										sliderHeight = jQuery( window ).height() - ( sideHeight + wpadminbarHeight );
								}else{
									var sliderHeight = jQuery( window ).height() - ( headerHeight + wpadminbarHeight );
								}
							} else {
								var sliderHeight = jQuery( window ).height() - wpadminbarHeight;
							}
						}

						if( sliderHeight < maxHeight ) {
							sliderHeight = maxHeight;
						}

						jQuery(this_tfslider).find('video').each(function() {
							var aspect_ratio = jQuery(this).width() / jQuery(this).height();
							var arc_sliderWidth = aspect_ratio * sliderHeight;
							var arc_sliderLeft = '-' + ((arc_sliderWidth - jQuery(this_tfslider).width()) / 2) + 'px';
							var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
							if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
								compare_width = jQuery(this_tfslider).width();
							}
							if(compare_width > arc_sliderWidth) {
								arc_sliderWidth = '100%';
								arc_sliderLeft = 0;
							}
							jQuery(this).width(arc_sliderWidth);
							jQuery(this).css('left', arc_sliderLeft);
						});
					} else {
						var sliderWidth = jQuery(this_tfslider).data('slider_width');

						if(sliderWidth.indexOf('%') != -1) {
							sliderWidth = jQuery(first_slide).find('.background-image').data('imgwidth');
							if( ! sliderWidth && ! cssua.ua.mobile ) {
								sliderWidth = jQuery(first_slide).find('video').width();
							}

							if( ! sliderWidth ) {
								sliderWidth = 940;
							}

							jQuery(this_tfslider).data('first_slide_width', sliderWidth);

							if(sliderWidth < jQuery(this_tfslider).data('slider_width')) {
								sliderWidth = jQuery(this_tfslider).data('slider_width');
							}

							var percentage_width = true;
						} else {
							sliderWidth = parseInt(jQuery(this_tfslider).data('slider_width'));
						}

						var sliderHeight = parseInt(jQuery(this_tfslider).data('slider_height'));
						var aspect_ratio = sliderHeight / sliderWidth;

						if(aspect_ratio < 0.5) {
							aspect_ratio = 0.5;
						}

						var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
						if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
							compare_width = jQuery(this_tfslider).width();
						}
						var sliderHeight = aspect_ratio * compare_width;

						if(sliderHeight > parseInt(jQuery(this_tfslider).data('slider_height'))) {
							sliderHeight = parseInt(jQuery(this_tfslider).data('slider_height'));
						}

						if(sliderHeight < 200) {
							sliderHeight = 200;
						}

						if( sliderHeight < maxHeight ) {
							sliderHeight = maxHeight;
						}

						jQuery(this_tfslider).find('video').each(function() {
							var aspect_ratio = jQuery(this).width() / jQuery(this).height();
							var arc_sliderWidth = aspect_ratio * sliderHeight;

							if(arc_sliderWidth < sliderWidth && !jQuery(this_tfslider).hasClass('full-width-slider')) {
								arc_sliderWidth = sliderWidth;
							}

							var arc_sliderLeft = '-' + ((arc_sliderWidth - jQuery(this_tfslider).width()) / 2) + 'px';
							var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
							if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
								compare_width = jQuery(this_tfslider).width();
							}
							if(compare_width > arc_sliderWidth && percentage_width === true && jQuery(this_tfslider).data('full_screen') != 1) {
								arc_sliderWidth = '100%';
								arc_sliderLeft = 0;
							}
							jQuery(this).width(arc_sliderWidth);
							jQuery(this).css('left', arc_sliderLeft);
						});
					}

					jQuery(this_tfslider).parents('.fusion-slider-container').css('max-height', sliderHeight);
					jQuery(this_tfslider).parents('.fusion-slider-container').css('height', sliderHeight);
					jQuery(this_tfslider).css('height', sliderHeight);
					jQuery(this_tfslider).find('.background, .mobile_video_image').css('height', sliderHeight);

					/*if(jQuery(this_tfslider).data('full_screen') == 0 && (cssua.ua.mobile && cssua.ua.mobile != 'ipad') || jQuery(this_tfslider).parents('.post-content').length >= 1) {
						jQuery(this_tfslider).parents('.fusion-slider-container').css('height', 'auto');
						jQuery(this_tfslider).find('.mobile_video_image').each(function() {
							var img_url = jQuery('.mobile_video_image').css('background-image').replace('url(', '').replace(')', '');
							if(img_url) {
								var preview_image = new Image();
								preview_image.name = img_url;
								preview_image.src = img_url;
								preview_image.onload = function() {
									var ar = this.height / this.width;
									var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
									if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
										compare_width = jQuery(this_tfslider).width();
									}
									var mobile_preview_height = ar * compare_width;
									if(mobile_preview_height < sliderHeight) {
										jQuery(this_tfslider).find('.mobile_video_image').css('height', mobile_preview_height);
										jQuery(this_tfslider).find('.mobile_video_image').css('height', mobile_preview_height);
									}
								};
							}
						});
						if(jQuery(slider.slides.eq(slider.currentSlide)).find('video').length >= 1 && jQuery(slider.slides.eq(slider.currentSlide)).find('.mobile_video_image').length >= 1) {
							var img_url = jQuery(slider.slides.eq(slider.currentSlide)).find('.mobile_video_image').css('background-image').replace('url(', '').replace(')', '');
							if(img_url) {
								var preview_image = new Image();
								preview_image.name = img_url;
								preview_image.src = img_url;
								preview_image.onload = function() {
									var ar = sliderHeight / this.width;
									var compare_width = jQuery(this_tfslider).parent().parent().parent().width();
									if(jQuery(this_tfslider).parents('.post-content').length >= 1) {
										compare_width = jQuery(this_tfslider).width();
									}
									var mobile_preview_height = ar * compare_width;
									if(mobile_preview_height < sliderHeight) {
										jQuery(this_tfslider).find('.mobile_video_image').css('height', mobile_preview_height);
										jQuery(this_tfslider).css('height', mobile_preview_height);
									}
								};
							}
						}
					}*/

					if ( 1 === jQuery( this_tfslider ).data( 'parallax' ) && ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)' ) ) {
						jQuery( this_tfslider ).css( 'position', 'fixed' );
						if ( 'absolute' != jQuery( '.fusion-header-wrapper' ).css( 'position' ) ) {
							jQuery( '.fusion-header-wrapper' ).css( 'position', 'relative' );

							var $navigationArrowsTranslate = 'translate(0, ' + ( headerHeight / 2 ) + 'px)';

							if ( js_local_vars.slider_position == 'below' ) {
								jQuery( this_tfslider ).parents( '.fusion-slider-container' ).css( 'margin-top', '-' + headerHeight + 'px' );
							}
						} else {
							var $navigationArrowsTranslate = 'translate(0, 0)';
						}
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( '-webkit-transform', $navigationArrowsTranslate );
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( '-ms-transform', $navigationArrowsTranslate );
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( '-o-transform', $navigationArrowsTranslate );
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( '-moz-transform', $navigationArrowsTranslate );;
						jQuery( this_tfslider ).find( '.flex-direction-nav li a' ).css( 'transform', $navigationArrowsTranslate );

						jQuery('#main, .fusion-footer-widget-area, .fusion-footer-copyright-area, .fusion-page-title-bar').css('position', 'relative');
						jQuery('#main, .fusion-footer-widget-area, .fusion-footer-copyright-area, .fusion-page-title-bar').css('z-index', '3');
						jQuery('.fusion-header-wrapper').css('z-index', '5');
						jQuery('.fusion-header-wrapper').css('height', headerHeight);

						if(jQuery(this_tfslider).data('full_screen') == 1) {
							jQuery(slider).find('.flex-control-nav').css('bottom', (headerHeight / 2));
						} else {
							jQuery(slider).find('.flex-control-nav').css('bottom', 0);
						}

						if(jQuery(this_tfslider).hasClass('fixed-width-slider')) {
							if( js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right' ) {
								if( jQuery(this_tfslider).parents( '#sliders-container' ).length ) {
									var wrapping_container = jQuery( '#sliders-container' );
								} else {
									var wrapping_container = jQuery( '#main' );
								}

								if( wrapping_container.width() < parseFloat( jQuery(this_tfslider).parent().css( 'max-width' ) ) ) {
									jQuery(this_tfslider).css( 'max-width', wrapping_container.width() );
								} else {
									jQuery(this_tfslider).css( 'max-width', jQuery(this_tfslider).parent().css( 'max-width' ) );
								}

								if( js_local_vars.header_position == 'Left' ) {
									var fixed_width_center = '-' + ((jQuery(this_tfslider).width() - jQuery( '#side-header' ).width() ) / 2) + 'px';
								} else {
									var fixed_width_center = '-' + ((jQuery(this_tfslider).width() + jQuery( '#side-header' ).width() ) / 2) + 'px';
								}

								if( ( -1 ) * fixed_width_center > jQuery(this_tfslider).width() ) {
									fixed_width_center = ( -1 ) * jQuery(this_tfslider).width();
								}
							} else {
								var fixed_width_center = '-' + (jQuery(this_tfslider).width() / 2) + 'px';
							}
							jQuery(this_tfslider).css('left', '50%');
							jQuery(this_tfslider).css('margin-left', fixed_width_center);
						}

						if ( js_local_vars.header_transparency == 0 && js_local_vars.slider_position == 'below' ) {
							var slideContent = jQuery( this_tfslider ).find( '.slide-content-container' );
							jQuery( slideContent ).each( function() {
								jQuery( this ).css( 'padding-top',  headerHeight + 'px' );
							});
						}

					} else if(jQuery(this_tfslider).data('parallax') == 1 && Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)')) {
						jQuery(this_tfslider).css('position', 'relative');
						jQuery(this_tfslider).css('left', '0');
						jQuery(this_tfslider).css('margin-left', '0');
						if( jQuery( '.fusion-header-wrapper' ).css( 'position' ) != 'absolute' ) {
							jQuery('.fusion-header-wrapper').css('position', 'relative');
						}
						jQuery('#main, .fusion-footer-widget-area, .fusion-footer-copyright-area, .fusion-page-title-bar').css('position', 'relative');
						jQuery('#main, .fusion-footer-widget-area, .fusion-footer-copyright-area, .fusion-page-title-bar').css('z-index', '3');
						jQuery('.fusion-header-wrapper').css('z-index', '5');
						jQuery('.fusion-header-wrapper').css('height', 'auto');
						jQuery(this_tfslider).parents('.fusion-slider-container').css('margin-top', '');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('-webkit-transform', 'translate(0, 0)');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('-ms-transform', 'translate(0, 0)');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('-o-transform', 'translate(0, 0)');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('-moz-transform', 'translate(0, 0)');
						jQuery(this_tfslider).find('.flex-direction-nav li a').css('transform', 'translate(0, 0)');

						jQuery(this_tfslider).find('.flex-control-nav').css('bottom', 0);

						if ( js_local_vars.header_transparency == 0 && js_local_vars.slider_position == 'below' ) {
							var slideContent = jQuery( this_tfslider ).find( '.slide-content-container' );
							jQuery( slideContent ).each( function() {
								jQuery( this ).css( 'padding-top',  '' );
							});
						}
					}

					var slideContent = jQuery(this_tfslider).find('.slide-content-container');

					jQuery(slider.slides.eq(slider.currentSlide)).find('video').each(function() {
						if(jQuery(this).parents('li').attr('data-autoplay') == 'yes') {
							if( typeof jQuery(this)[0].play === "function" ) {
								jQuery(this)[0].play();
							}
						}
					});
/*
					jQuery(slider.slides.eq(slider.currentSlide)).find('iframe').each(function() {
						if(jQuery(this).parents('li').attr('data-autoplay') == 'yes') {
							jQuery(this_tfslider).flexslider('pause');
							var video = this;
							setTimeout(function() {
								video.contentWindow.postMessage('{"event":"command","func":"' + 'playVideo' + '","args":""}', '*');
							}, 1000);
						}
					});
*/
					if(js_local_vars.header_position == 'Left' || js_local_vars.header_position == 'Right') {
						if( jQuery(this_tfslider).parents('#sliders-container').length >= 1 ) {
							var slideContent = jQuery(this_tfslider).parents('#sliders-container').find('.slide-content-container');
							jQuery(slideContent).each(function() {
								if( ! Modernizr.mq('only screen and (max-width: ' + js_local_vars.side_header_break_point + 'px)') ) {
									if(jQuery(this).hasClass('slide-content-right')) {
										jQuery(this).find('.slide-content').css('margin-right', '100px');
									} else if(jQuery(this).hasClass('slide-content-left')) {
										jQuery(this).find('.slide-content').css('margin-left', '100px');
									}
								}
							});
						}
					}

					fusion_reanimate_slider( slideContent );

					// Control Videos
					if(typeof(slider.slides) !== 'undefined' && slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
						// Vimeo
						if(Number(js_local_vars.status_vimeo)) {
							$f(slider.slides.eq(slider.currentSlide).find('iframe')[0]).api('pause');

							if(jQuery(slider.slides.eq(slider.currentSlide)).data('autoplay') == 'yes') {
								$f(slider.slides.eq(slider.currentSlide).find('iframe')[0]).api('play');
							}
							if(jQuery(slider.slides.eq(slider.currentSlide)).data('mute') == 'yes') {
								$f(slider.slides.eq(slider.currentSlide).find('iframe')[0]).api('setVolume', 0);
							}
						}

						playVideoAndPauseOthers(slider);
					}

					jQuery(this_tfslider).find('.overlay-link').hide();
					jQuery(slider.slides.eq(slider.currentSlide)).find('.overlay-link').show();

					// Resize videos
					jQuery(this_tfslider).find( '[data-youtube-video-id], [data-vimeo-video-id]' ).each(
						function() {
							var $this = jQuery( this );
							setTimeout(
								function() {
									resizeVideo( $this );
								}, 500
							);
						}
					);

					// Reinitialize waypoint
					jQuery.waypoints( 'viewportHeight' );
					jQuery.waypoints( 'refresh' );

				},
				before: function(slider) {
					jQuery(this_tfslider).find('.slide-content-container').hide();


					// Control Videos
					if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
						// Vimeo
						if(Number(js_local_vars.status_vimeo)) {
							jQuery(this_tfslider).find('iframe').each(function() {
								$f(jQuery(this)[0]).api('pause');
							});

							if(jQuery(slider.slides.eq(slider.currentSlide)).data('autoplay') == 'yes') {
								$f(slider.slides.eq(slider.currentSlide).find('iframe')[0]).api('play');
							}
							if(jQuery(slider.slides.eq(slider.currentSlide)).data('mute') == 'yes') {
								$f(slider.slides.eq(slider.currentSlide).find('iframe')[0]).api('setVolume', 0);
							}
						}
					}

					playVideoAndPauseOthers(slider);
				},
				after: function(slider) {
					jQuery(slider.slides.eq(slider.currentSlide)).find('.slide-content-container').show();

					// Remove title separators and padding, when there is not enough space
					jQuery(slider.slides.eq(slider.currentSlide)).find( '.fusion-title' ).fusion_responsive_title_shortcode();

					var slideContent = jQuery(this_tfslider).find('.slide-content-container');

					fusion_reanimate_slider( slideContent );

					// Control Videos
					if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
						// Vimeo
						if(Number(js_local_vars.status_vimeo)) {
							jQuery(this_tfslider).find('iframe').each(function() {
								$f(jQuery(this)[0]).api('pause');
							});

							if(jQuery(slider.slides.eq(slider.currentSlide)).data('autoplay') == 'yes') {
								$f(slider.slides.eq(slider.currentSlide).find('iframe')[0]).api('play');
							}
							if(jQuery(slider.slides.eq(slider.currentSlide)).data('mute') == 'yes') {
								$f(slider.slides.eq(slider.currentSlide).find('iframe')[0]).api('setVolume', 0);
							}
						}
					}

					jQuery(this_tfslider).find('.overlay-link').hide();
					jQuery(slider.slides.eq(slider.currentSlide)).find('.overlay-link').show();

					jQuery( slider.slides.eq( slider.currentSlide ) ).find( '[data-youtube-video-id], [data-vimeo-video-id]' ).each(
						function() {
							resizeVideo( jQuery( this ) );
						}
					);

					playVideoAndPauseOthers(slider);

					jQuery('[data-spy="scroll"]').each(function () {
					  var $spy = jQuery(this).scrollspy('refresh');
					});
				}
			});
		});

		if(js_local_vars.page_smoothHeight === 'false') {
			page_smoothHeight = false;
		} else {
			page_smoothHeight = true;
		}

		jQuery('.fusion-blog-layout-grid .flexslider').flexslider({
			slideshow: Boolean(Number(js_local_vars.slideshow_autoplay)),
			slideshowSpeed: Number(js_local_vars.slideshow_speed),
			video: true,
			smoothHeight: page_smoothHeight,
			pauseOnHover: false,
			useCSS: false,
			prevText: '&#xf104;',
			nextText: '&#xf105;',
			start: function(slider) {
				jQuery( slider ).removeClass( 'fusion-flexslider-loading' );

				if(typeof(slider.slides) !== 'undefined' && slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '-20px');
					} else {
						jQuery(slider).find('.flex-control-nav').hide();
					}
					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}
				} else {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '0px');
					} else {
						jQuery(slider).find('.flex-control-nav').show();
					}
				}

				// Reinitialize waypoints
				jQuery.waypoints( 'viewportHeight' );
				jQuery.waypoints('refresh');
			},
			before: function(slider) {
				if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.status_vimeo)) {
						$f(slider.slides.eq(slider.currentSlide).find('iframe')[0] ).api('pause');
					}

					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}

					/* ------------------  YOUTUBE FOR AUTOSLIDER ------------------ */
					playVideoAndPauseOthers(slider);
				}
			},
			after: function(slider) {
				if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '-20px');
					} else {
						jQuery(slider).find('.flex-control-nav').hide();
					}

					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}
				} else {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '0px');
					} else {
						jQuery(slider).find('.flex-control-nav').show();
					}
				}
				jQuery('[data-spy="scroll"]').each(function () {
				  var $spy = jQuery(this).scrollspy('refresh');
				});
			}
		});

		if(js_local_vars.flex_smoothHeight === 'false') {
			flex_smoothHeight = false;
		} else {
			flex_smoothHeight = true;
		}

		jQuery('.fusion-flexslider').flexslider({
			slideshow: Boolean(Number(js_local_vars.slideshow_autoplay)),
			slideshowSpeed: js_local_vars.slideshow_speed,
			video: true,
			smoothHeight: flex_smoothHeight,
			pauseOnHover: false,
			useCSS: false,
			prevText: '&#xf104;',
			nextText: '&#xf105;',
			start: function(slider) {
				// Remove Loading
				slider.removeClass('fusion-flexslider-loading');

				// For dynamic content, like equalHeights
				jQuery( window ).trigger( 'resize' );

				if(typeof(slider.slides) !== 'undefined' && slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '-20px');
					} else {
						jQuery(slider).find('.flex-control-nav').hide();
					}
					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}
				} else {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '0px');
					} else {
						jQuery(slider).find('.flex-control-nav').show();
					}
				}

				// Reinitialize waypoint
				jQuery.waypoints( 'viewportHeight' );
				jQuery.waypoints( 'refresh' );
			},
			before: function(slider) {
				if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.status_vimeo)) {
						$f( slider.slides.eq(slider.currentSlide).find('iframe')[0] ).api('pause');
					}

					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}

					/* ------------------  YOUTUBE FOR AUTOSLIDER ------------------ */
					playVideoAndPauseOthers(slider);
				}
			},
			after: function(slider) {
				if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '-20px');
					} else {
						jQuery(slider).find('.flex-control-nav').hide();
					}

					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}
				} else {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '0px');
					} else {
						jQuery(slider).find('.flex-control-nav').show();
					}
				}
				jQuery('[data-spy="scroll"]').each(function () {
				  var $spy = jQuery(this).scrollspy('refresh');
				});
			}
		});

		jQuery( '.flexslider:not(.tfs-slider)' ).flexslider({
			slideshow: Boolean(Number(js_local_vars.slideshow_autoplay)),
			slideshowSpeed: js_local_vars.slideshow_speed,
			video: true,
			smoothHeight: flex_smoothHeight,
			pauseOnHover: false,
			useCSS: false,
			prevText: '&#xf104;',
			nextText: '&#xf105;',
			start: function(slider) {
				// Remove Loading
				slider.removeClass('fusion-flexslider-loading');

				if(typeof(slider.slides) !== 'undefined' && slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '-20px');
					} else {
						jQuery(slider).find('.flex-control-nav').hide();
					}
					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}
				} else {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '0px');
					} else {
						jQuery(slider).find('.flex-control-nav').show();
					}
				}

				// Reinitialize waypoint
				jQuery.waypoints( 'viewportHeight' );
				jQuery.waypoints( 'refresh' );
			},
			before: function(slider) {
				if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.status_vimeo)) {
						$f( slider.slides.eq(slider.currentSlide).find('iframe')[0] ).api('pause');
					}
					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}

					/* ------------------  YOUTUBE FOR AUTOSLIDER ------------------ */
					playVideoAndPauseOthers(slider);
				}
			},
			after: function(slider) {
				if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '-20px');
					} else {
						jQuery(slider).find('.flex-control-nav').hide();
					}
					if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
						YT_ready(function() {
							new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
								events: {
									'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
								}
							});
						});
					}
				} else {
					if(Number(js_local_vars.pagination_video_slide)) {
						jQuery(slider).find('.flex-control-nav').css('bottom', '0px');
					} else {
						jQuery(slider).find('.flex-control-nav').show();
					}
				}
				jQuery('[data-spy="scroll"]').each(function () {
				  var $spy = jQuery(this).scrollspy('refresh');
				});
			}
		});

		/* ------------------ PREV & NEXT BUTTON FOR FLEXSLIDER (YOUTUBE) ------------------ */
		jQuery('.flex-next, .flex-prev').click(function() {
			//playVideoAndPauseOthers(jQuery(this).parents('.flexslider'));
		});
	}

	if(jQuery().isotope) {

		jQuery( '.fusion-blog-layout-grid' ).each(function() {
			$grid_container = jQuery( this );

			var columns = 2;
			for( i = 1; i < 7; i++ ) {
				if( jQuery ( this ).hasClass( 'fusion-blog-layout-grid-' + i ) ) {
					columns = i;
				}
			}

			var grid_width = Math.floor( 100 / columns * 100 ) / 100  + '%';
			$grid_container.find( '.fusion-post-grid' ).css( 'width', grid_width );
			$grid_container.isotope({
				layoutMode: 'masonry',
				itemSelector: '.fusion-post-grid',
				transformsEnabled: false,
				isOriginLeft: jQuery( 'body.rtl' ).length ? false : true,
				resizable: true,

			});


			if( ( $grid_container.hasClass( 'fusion-blog-layout-grid-4') || $grid_container.hasClass( 'fusion-blog-layout-grid-5') || $grid_container.hasClass( 'fusion-blog-layout-grid-6') ) && Modernizr.mq('only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait)')) {
				var grid_width = Math.floor( 100 / 3 * 100 ) / 100  + '%';
				$grid_container.find( '.fusion-post-grid' ).css( 'width', grid_width );
				$grid_container.isotope({
					layoutMode: 'masonry',
					itemSelector: '.fusion-post-grid',
					transformsEnabled: false,
					isOriginLeft: jQuery( 'body.rtl' ).length ? false : true,
					resizable: true,

				});
			}

			setTimeout(
				function() {
					jQuery( window ).trigger( 'resize' );
					$grid_container.isotope();
				}, 250
			);
		});
	}

	if ( Boolean( Number( js_local_vars.avada_rev_styles ) ) ) {
		jQuery( '.rev_slider_wrapper' ).each(function() {
			var rev_slider_wrapper = jQuery( this );

			if ( rev_slider_wrapper.length >=1 && rev_slider_wrapper.attr( 'class' ).indexOf( 'tp-shadow' ) == -1 ) {
				jQuery( '<div class="shadow-left">' ).appendTo( this );
				jQuery( '<div class="shadow-right">' ).appendTo( this );

				rev_slider_wrapper.addClass( 'avada-skin-rev' );
			}

			if( ! jQuery(this).find( '.tp-leftarrow' ).hasClass( 'preview1' ) && ! jQuery(this).find( '.tp-leftarrow' ).hasClass( 'preview2' ) && ! jQuery(this).find( '.tp-leftarrow' ).hasClass( 'preview3' ) && ! jQuery(this).find( '.tp-leftarrow' ).hasClass( 'preview4' ) ) {
				jQuery(this).addClass('avada-skin-rev-nav');

				if( rev_slider_wrapper.find( '.tp-leftarrow' ).height() > rev_slider_wrapper.height() / 4 && rev_slider_wrapper.find( '.tp-leftarrow' ).height() < rev_slider_wrapper.height() ) {
					var rev_slider_id = rev_slider_wrapper.attr('id');
					var new_dimension = rev_slider_wrapper.height() / 4;
					if( rev_slider_wrapper.children( '.avada-rev-arrows' ).length ) {
						rev_slider_wrapper.children( '.avada-rev-arrows' ).empty();
						rev_slider_wrapper.children( '.avada-rev-arrows' ).append( '<style type="text/css">#' + rev_slider_id + ' .tp-leftarrow, #' + rev_slider_id + ' .tp-rightarrow{margin-top:-' + new_dimension / 2 + 'px !important;width:' + new_dimension + 'px !important;height:' + new_dimension + 'px !important;}#' + rev_slider_id + ' .tp-leftarrow:before, #' + rev_slider_id + ' .tp-rightarrow:before{line-height:' + new_dimension  + 'px;font-size:' + new_dimension / 2 + 'px;}</style>' );
					} else {
						rev_slider_wrapper.prepend( '<div class="avada-rev-arrows"><style type="text/css">#' + rev_slider_id + ' .tp-leftarrow, #' + rev_slider_id + ' .tp-rightarrow{margin-top:-' + new_dimension / 2 + 'px !important;width:' + new_dimension + 'px !important;height:' + new_dimension + 'px !important;}#' + rev_slider_id + ' .tp-leftarrow:before, #' + rev_slider_id + ' .tp-rightarrow:before{line-height:' + new_dimension  + 'px;font-size:' + new_dimension / 2 + 'px;}</style></div>' );
					}
				}

				jQuery(window).on('resize', function() {
					if( rev_slider_wrapper.find( '.tp-leftarrow' ).height() > rev_slider_wrapper.height() / 4 && rev_slider_wrapper.find( '.tp-leftarrow' ).height() < rev_slider_wrapper.height() ) {
						var rev_slider_id = rev_slider_wrapper.attr('id');
						var new_dimension = rev_slider_wrapper.height() / 4;
						if( rev_slider_wrapper.children( '.avada-rev-arrows' ).length ) {
							rev_slider_wrapper.children( '.avada-rev-arrows' ).empty();
							rev_slider_wrapper.children( '.avada-rev-arrows' ).append( '<style type="text/css">#' + rev_slider_id + ' .tp-leftarrow, #' + rev_slider_id + ' .tp-rightarrow{margin-top:-' + new_dimension / 2 + 'px !important;width:' + new_dimension + 'px !important;height:' + new_dimension + 'px !important;}#' + rev_slider_id + ' .tp-leftarrow:before, #' + rev_slider_id + ' .tp-rightarrow:before{line-height:' + new_dimension  + 'px;font-size:' + new_dimension / 2 + 'px;}</style>' );
						} else {
							rev_slider_wrapper.prepend( '<div class="avada-rev-arrows"><style type="text/css">#' + rev_slider_id + ' .tp-leftarrow, #' + rev_slider_id + ' .tp-rightarrow{margin-top:-' + new_dimension / 2 + 'px !important;width:' + new_dimension + 'px !important;height:' + new_dimension + 'px !important;}#' + rev_slider_id + ' .tp-leftarrow:before, #' + rev_slider_id + ' .tp-rightarrow:before{line-height:' + new_dimension  + 'px;font-size:' + new_dimension / 2 + 'px;}</style></div>' );
						}
					} else {
						rev_slider_wrapper.children( '.avada-rev-arrows' ).remove();
					}
				});
			}

		});
	}
});

jQuery( document ).ready( function() {
	if(jQuery().flexslider && jQuery('.woocommerce .images #carousel').length >= 1) {
		var WooThumbWidth = 100;
		if(jQuery('body.woocommerce .sidebar').is(':visible')) {
			wooThumbWidth = 100;
		} else {
			wooThumbWidth = 118;
		}

		if(typeof jQuery('.woocommerce .images #carousel').data('flexslider') !== 'undefined') {
			jQuery('.woocommerce .images #carousel').flexslider('destroy');
			jQuery('.woocommerce .images #slider').flexslider('destroy');
		}

		jQuery('.woocommerce .images #carousel').flexslider({
			animation: 'slide',
			controlNav: false,
			directionNav: false,
			animationLoop: false,
			slideshow: false,
			itemWidth: wooThumbWidth,
			itemMargin: 9,
			touch: false,
			useCSS: false,
			asNavFor: '.woocommerce .images #slider',
			smoothHeight: false,
			prevText: '&#xf104;',
			nextText: '&#xf105;',
			start: function(slider) {
				jQuery( slider ).removeClass( 'fusion-flexslider-loading' );
			}
		});

		jQuery('.woocommerce .images #slider').flexslider({
			animation: 'slide',
			controlNav: false,
			animationLoop: false,
			slideshow: false,
			smoothHeight: true,
			touch: true,
			useCSS: false,
			sync: '.woocommerce .images #carousel',
			prevText: '&#xf104;',
			nextText: '&#xf105;',
			start: function(slider) {
				jQuery( slider ).removeClass( 'fusion-flexslider-loading' );
			}
		});
	}

	if(jQuery().flexslider && jQuery('.flexslider-attachments').length >= 1) {
		if(typeof jQuery('.flexslider-attachments').data('flexslider') !== 'undefined') {
			jQuery('.flexslider-attachments').flexslider('destroy');
		}

		jQuery('.flexslider-attachments').flexslider({
			slideshow: Boolean(Number(js_local_vars.slideshow_autoplay)),
			slideshowSpeed: js_local_vars.slideshow_speed,
			video: false,
			smoothHeight: false,
			pauseOnHover: false,
			useCSS: false,
			prevText: '&#xf104;',
			nextText: '&#xf105;',
			controlNav: 'thumbnails',
			start: function(slider) {
				jQuery( slider ).find( '.fusion-slider-loading' ).remove();

				// Remove Loading
				slider.removeClass('fusion-flexslider-loading');
			}
		});
	}
});

jQuery( window ).load( function() {
	if( js_local_vars.sidenav_behavior == 'Click' ) {
		jQuery('.side-nav li a').on('click', function(e) {
			if( jQuery(this).parent('.page_item_has_children').length ) {
				if(jQuery(this).parent().find('> .children').length  && ! jQuery(this).parent().find('> .children').is(':visible') ) {
					jQuery(this).parent().find('> .children').stop(true, true).slideDown('slow');
				} else {
					jQuery(this).parent().find('> .children').stop(true, true).slideUp('slow');
				}
			}

			if( jQuery(this).parent('.page_item_has_children.current_page_item').length ) {
				return false;
			}
		});
	} else {
		jQuery('.side-nav li').hoverIntent({
		over: function() {
			if( jQuery(this).find('> .children').length ) {
				jQuery(this).find('> .children').stop(true, true).slideDown('slow');
			}
		},
		out: function() {
			if(jQuery(this).find('.current_page_item').length === 0 && jQuery(this).hasClass('current_page_item') === false) {
				jQuery(this).find('.children').stop(true, true).slideUp('slow');
			}
		},
		timeout: 500
		});
	}

	if(jQuery().eislideshow) {
		var eislideshow_args = {
			autoplay: Boolean(Number(js_local_vars.tfes_autoplay))
		};

		if(js_local_vars.tfes_animation) {
			eislideshow_args.animation = js_local_vars.tfes_animation;
		}
		if(js_local_vars.tfes_interval) {
			eislideshow_args.slideshow_interval = js_local_vars.tfes_interval;
		}
		if(js_local_vars.tfes_speed) {
			eislideshow_args.speed = js_local_vars.tfes_speed;
		}
		if(js_local_vars.tfes_width) {
			eislideshow_args.thumbMaxWidth = js_local_vars.tfes_width;
		}

		jQuery('#ei-slider').eislideshow(eislideshow_args);
	}

	// Timeline vars and click events for infinite scroll
	var last_timeline_date = jQuery( '.fusion-blog-layout-timeline' ).find( '.fusion-timeline-date' ).last().text();
	var collapse_month_visible = true;

	jQuery( '.fusion-blog-layout-timeline' ).find( '.fusion-timeline-date' ).click( function() {
		jQuery( this ).next( '.fusion-collapse-month' ).slideToggle();
	});

	jQuery( '.fusion-timeline-icon' ).find( '.fusion-icon-bubbles' ).click( function() {
		if ( collapse_month_visible ) {
			jQuery( this ).parent().next( '.fusion-blog-layout-timeline' ).find( '.fusion-collapse-month' ).slideUp();
			collapse_month_visible = false;
		} else {
			jQuery( this ).parent().next( '.fusion-blog-layout-timeline' ).find( '.fusion-collapse-month' ).slideDown();
			collapse_month_visible = true;
		}
	});

	// Setup infinite scroll for each blog instance; main blog page and blog shortcodes
	jQuery( '.fusion-posts-container-infinite' ).each( function() {
		// Set the correct container for blog shortcode infinite scroll
		var $blog_infinite_container = jQuery( this ),
			$original_posts = jQuery( this ).find( '.post' );
		if ( jQuery( this ).find( '.fusion-blog-layout-timeline' ).length ) {
			$blog_infinite_container = jQuery( this ).find( '.fusion-blog-layout-timeline' );
		}

		// If more than one blog shortcode is on the page, make sure the infinite scroll selectors are correct
		$parent_wrapper_classes = '';
		if ( $blog_infinite_container.parents( '.fusion-blog-shortcode' ).length ) {
			$parent_wrapper_classes = '.' + $blog_infinite_container.parents( '.fusion-blog-shortcode' ).attr( 'class' ).replace( /\ /g, '.' ) + ' ';
		}

		// Infite scroll for main blog page and blog shortcode
		jQuery( $blog_infinite_container ).infinitescroll({
			navSelector  : $parent_wrapper_classes + 'div.pagination',
						   // selector for the paged navigation (it will be hidden)
			nextSelector : $parent_wrapper_classes + 'a.pagination-next',
						   // selector for the NEXT link (to page 2)
			itemSelector : $parent_wrapper_classes + 'div.pagination .current, ' + $parent_wrapper_classes + 'div.post:not( .fusion-archive-description ), ' + $parent_wrapper_classes + '.fusion-collapse-month, ' + $parent_wrapper_classes + '.fusion-timeline-date',
						   // selector for all items you'll retrieve
			loading	  : {
							finishedMsg: js_local_vars.infinite_finished_msg,
							msg: jQuery( '<div class="fusion-loading-container fusion-clearfix"><div class="fusion-loading-spinner"><div class="fusion-spinner-1"></div><div class="fusion-spinner-2"></div><div class="fusion-spinner-3"></div></div><div class="fusion-loading-msg">'+js_local_vars.infinite_blog_text+'</div>' )
			},
			errorCallback: function() {
				if ( jQuery( $blog_infinite_container ).hasClass( 'isotope' ) ) {
					jQuery( $blog_infinite_container ).isotope();
				}
			}
		}, function( posts ) {
			// Timeline layout specific actions
			if ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-layout-timeline' ) ) {
				// Check if the last already displayed moth is the same as the first newly loaded; if so, delete one label
				if ( jQuery( posts ).first( '.fusion-timeline-date' ).text() == last_timeline_date ) {
					jQuery( posts ).first( '.fusion-timeline-date' ).remove();
				}
				// Set the last timeline date to lat of the currently loaded
				last_timeline_date = jQuery( $blog_infinite_container ).find( '.fusion-timeline-date' ).last().text();

				// Append newly loaded items of the same month to the container that is already there
				jQuery( $blog_infinite_container ).find( '.fusion-timeline-date' ).each( function() {
					jQuery( this ).next( '.fusion-collapse-month' ).append( jQuery( this ).nextUntil( '.fusion-timeline-date', '.fusion-post-timeline' ) );
				});

				// If all month containers are collapsed, also collapse the new ones
				if ( ! collapse_month_visible ) {
					setTimeout( function() {
						jQuery( $blog_infinite_container ).find ( '.fusion-collapse-month' ).hide();
					}, 200 );
				}

				// Delete empty collapse-month containers
				setTimeout( function() {
					jQuery( $blog_infinite_container ).find ( '.fusion-collapse-month' ).each( function() {
						if ( ! jQuery( this ).children().length ) {
							jQuery( this ).remove();
						}
					});
				}, 10 );

				// Reset the click event for the collapse-month toggle
				jQuery( $blog_infinite_container ).find( '.fusion-timeline-date' ).unbind( 'click' );
				jQuery( $blog_infinite_container ).find( '.fusion-timeline-date' ).click( function() {
					jQuery( this ).next( '.fusion-collapse-month' ).slideToggle();
				});
			}

			// Grid layout specific actions
			if ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-layout-grid' ) &&
				 jQuery().isotope
			) {
				jQuery( posts ).hide();

				// Get the amount of columns
				var columns = 2;
				for ( i = 1; i < 7; i++ ) {
					if ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-layout-grid-' + i ) ) {
						columns = i;
					}
				}

				// Calculate grid with
				var grid_width = Math.floor( 100 / columns * 100 ) / 100  + '%';
				jQuery( $blog_infinite_container ).find( '.post' ).css( 'width', grid_width );

				// Add and fade in new posts when all images are loaded
				imagesLoaded( posts, function() {
					jQuery( posts ).fadeIn();

					// Relayout isotope
					if ( jQuery( $blog_infinite_container ).hasClass( 'isotope' ) ) {
						jQuery( $blog_infinite_container ).isotope( 'appended', jQuery( posts ) );
						jQuery( $blog_infinite_container ).isotope();
					}

					// Refresh the scrollspy script for one page layouts
					jQuery( '[data-spy="scroll"]' ).each( function () {
						  var $spy = jQuery( this ).scrollspy( 'refresh' );
					});
				});
			}

			// Initialize flexslider for post slideshows
			jQuery( $blog_infinite_container ).find( '.flexslider' ).flexslider({
				slideshow: Boolean(Number(js_local_vars.slideshow_autoplay)),
				slideshowSpeed: js_local_vars.slideshow_speed,
				video: true,
				pauseOnHover: false,
				useCSS: false,
				prevText: '&#xf104;',
				nextText: '&#xf105;',
				start: function( slider ) {
					// Remove Loading
					slider.removeClass('fusion-flexslider-loading');

					if(typeof(slider.slides) !== 'undefined' && slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
						if(Number(js_local_vars.pagination_video_slide)) {
							jQuery(slider).find('.flex-control-nav').css('bottom', '-20px');
						} else {
							jQuery(slider).find('.flex-control-nav').hide();
						}
						if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
							YT_ready(function() {
								new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
									events: {
										'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
									}
								});
							});
						}
					} else {
						if(Number(js_local_vars.pagination_video_slide)) {
							jQuery(slider).find('.flex-control-nav').css('bottom', '0px');
						} else {
							jQuery(slider).find('.flex-control-nav').show();
						}
					}

					// Reinitialize waypoints
					jQuery.waypoints( 'viewportHeight' );
					jQuery.waypoints('refresh');
				},
				before: function(slider) {
					if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
						if(Number(js_local_vars.status_vimeo)) {
							$f( slider.slides.eq(slider.currentSlide).find('iframe')[0] ).api('pause');
						}

						if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
							YT_ready(function() {
								new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
									events: {
										'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
									}
								});
							});
						}

						/* ------------------  YOUTUBE FOR AUTOSLIDER ------------------ */
						//playVideoAndPauseOthers(slider);
					}
				},
				after: function(slider) {
					if(slider.slides.eq(slider.currentSlide).find('iframe').length !== 0) {
						if(Number(js_local_vars.pagination_video_slide)) {
							jQuery(slider).find('.flex-control-nav').css('bottom', '-20px');
						} else {
							jQuery(slider).find('.flex-control-nav').hide();
						}

						if(Number(js_local_vars.status_yt) && window.yt_vid_exists === true) {
							YT_ready(function() {
								new YT.Player(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), {
									events: {
										'onStateChange': onPlayerStateChange(slider.slides.eq(slider.currentSlide).find('iframe').attr('id'), slider)
									}
								});
							});
						}
					} else {
						if(Number(js_local_vars.pagination_video_slide)) {
							jQuery(slider).find('.flex-control-nav').css('bottom', '0px');
						} else {
							jQuery(slider).find('.flex-control-nav').show();
						}
					}
					jQuery('[data-spy="scroll"]').each(function () {
					  var $spy = jQuery(this).scrollspy('refresh');
					});
				}
			});

			// Trigger fitvids
			jQuery( posts ).each( function() {
				jQuery( this ).find( '.full-video, .video-shortcode, .wooslider .slide-content' ).fitVids();
			});

			// Hide the load more button, if the currently loaded page is already the last page
			$fusion_posts_container = $blog_infinite_container;
			if ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-layout-timeline' ) ) {
				$fusion_posts_container = jQuery( $blog_infinite_container ).parents( '.fusion-posts-container-infinite' );
			}

			$current_page = $fusion_posts_container.find( '.current' ).html();
			$fusion_posts_container.find( '.current' ).remove();

			if ( $fusion_posts_container.data( 'pages' ) == $current_page ) {
				$fusion_posts_container.parent().find( '.fusion-loading-container' ).hide();
           		$fusion_posts_container.parent().find( '.fusion-load-more-button' ).hide();
			}

			// Activate lightbox for the newly added posts
			if( js_local_vars.lightbox_behavior == 'individual' || ! $original_posts.find( '.fusion-post-slideshow' ).length ) {
				$avada_lightbox.activate_lightbox( jQuery( posts ) );

				$original_posts = $blog_infinite_container.find( '.post' );
			}

			// Refresh the lightbox, needed in any case
			$avada_lightbox.refresh_lightbox();
		});

		// Setup infinite scroll manual loading
		if ( ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-archive' ) && js_local_vars.blog_pagination_type == 'load_more_button' ) ||
			 jQuery( $blog_infinite_container ).hasClass( 'fusion-posts-container-load-more' ) ||
			 ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-layout-timeline' ) && jQuery( $blog_infinite_container ).parent().hasClass( 'fusion-posts-container-load-more' ) )
		) {
			jQuery( $blog_infinite_container ).infinitescroll( 'unbind' );

			// Load more posts button click
			if ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-archive' ) ) {
				$load_more_button = jQuery( $blog_infinite_container ).parent().find( '.fusion-load-more-button' );
			} else {
				$load_more_button = jQuery( $blog_infinite_container ).parents( '.fusion-blog-archive' ).find( '.fusion-load-more-button' );
			}

			$load_more_button.on( 'click', function(e) {
				e.preventDefault();

				// Use the retrieve method to get the next set of posts
				jQuery( $blog_infinite_container ).infinitescroll( 'retrieve' );

				// Trigger isotope for correct positioning
				if ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-layout-grid' ) ) {
					jQuery( $blog_infinite_container ).isotope();
				}
			});
		}

		// Hide the load more button, if there is only one page
		$fusion_posts_container = $blog_infinite_container;
		if ( jQuery( $blog_infinite_container ).hasClass( 'fusion-blog-layout-timeline' ) && jQuery( $blog_infinite_container ).parents( '.fusion-blog-layout-timeline-wrapper' ).length ) {
			$fusion_posts_container = jQuery( $blog_infinite_container ).parents( '.fusion-posts-container-infinite' );
		}

		if ( $fusion_posts_container.data( 'pages' ) == '1' ) {
			$fusion_posts_container.parent().find( '.fusion-loading-container' ).hide();
			$fusion_posts_container.parent().find( '.fusion-load-more-button' ).hide();
		}
	});

	// Portfolio infinite scroll
	if ( js_local_vars.portfolio_pagination_type == 'Infinite Scroll' || js_local_vars.portfolio_pagination_type == 'load_more_button' ) {
		$infinte_scroll_container = jQuery( '.fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper' );

		// Initialize the infinite scroll object
		$infinte_scroll_container.infinitescroll({
			navSelector  : ".pagination",
						   // selector for the paged navigation (it will be hidden)
			nextSelector : ".pagination-next",
						   // selector for the NEXT link (to page 2)
			itemSelector : 'div.pagination .current, .fusion-portfolio-post',
						   // selector for all items you'll retrieve
			loading	  : {
							finishedMsg: js_local_vars.infinite_finished_msg,
							msg: jQuery('<div class="fusion-loading-container fusion-clearfix"><div class="fusion-loading-spinner"><div class="fusion-spinner-1"></div><div class="fusion-spinner-2"></div><div class="fusion-spinner-3"></div></div><div class="fusion-loading-msg">'+js_local_vars.infinite_blog_text+'</div>')
			},
			errorCallback: function() {
				jQuery( '.fusion-portfolio .fusion-portfolio-wrapper' ).isotope();
			},

		}, function( $posts ) {

			if ( jQuery().isotope ) {

				var $filters = jQuery( '.fusion-filters' ).find( '.fusion-filter' ),
					$posts = jQuery( $posts );

				// Hide posts while loading
				$posts.hide();

				// Make sure images are loaded before the posts get shown
				imagesLoaded( $posts, function() {
					// Fade in placeholder images
					var $placeholder_images = jQuery( $posts ).find( '.fusion-placeholder-image' );
					$placeholder_images.parents( '.fusion-portfolio-content-wrapper, .fusion-image-wrapper' ).animate({ opacity: 1 });

					// Fade in videos
					var $videos = jQuery( $posts ).find( '.fusion-video' );
					$videos.each( function() {
						jQuery( this ).animate({ opacity: 1 });
						jQuery( this ).parents( '.fusion-portfolio-content-wrapper' ).animate({opacity: 1});
					});

					$videos.fitVids();

					// Portfolio Images Loaded Check
					window.$portfolio_images_index = 0;
					jQuery( $posts ).imagesLoaded().progress( function( $instance, $image ) {
						if( jQuery( $image.img ).parents( '.fusion-portfolio-content-wrapper' ).length >= 1 ) {
							jQuery( $image.img, $placeholder_images ).parents( '.fusion-portfolio-content-wrapper' ).delay( 100 * window.$portfolio_images_index ).animate({
								opacity: 1
							});
						} else {
							jQuery( $image.img, $placeholder_images ).parents( '.fusion-image-wrapper' ).delay( 100 * window.$portfolio_images_index ).animate({
								opacity: 1
							});
						}

						window.$portfolio_images_index++;
					});

					if ( $filters ) {
						// Loop through all filters
						$filters.each( function() {
							var $filter = jQuery( this ),
								$filter_name = $filter.children( 'a' ).data( 'filter' );

							if ( $posts ) {
								// Loop through the newly loaded posts
								$posts.each( function() {
									$post = jQuery( this );

									// Check if one of the new posts has the class of a still hidden filter
									if ( $post.hasClass( $filter_name.substr( 1 ) ) ) {
										if ( $filter.hasClass( 'fusion-hidden' ) ) {


											if ( ! Modernizr.mq( 'only screen and (max-width: ' + js_local_vars.content_break_point + 'px)' ) ) {
												// Animate the filter to make it visible
												var $filter_width = $filter.css( 'width' ),
													$filter_margin_right = $filter.css( 'margin-right' );

												$filter.css( 'width', 0 );
												$filter.css( 'margin-right', 0 );
												$filter.removeClass( 'fusion-hidden' );

												$filter.animate({
													'width' : $filter_width,
													'margin-right' : $filter_margin_right
												}, 400, function() {
													// Finally remove animation style values
													$filter.removeAttr( 'style');
												});
											} else {
												$filter.fadeIn( 400, function() {
													$filter.removeClass( 'fusion-hidden' );
												});
											}
										}
									}
								});
							}
						});
					}

					// Check if filters are displayed
				 	if ( jQuery( '.fusion-filters' ).length ) {
						// Display new posts based on filter selection
						var $filter_active_element = jQuery( '.fusion-portfolio .fusion-filters' ).find( '.fusion-filter.fusion-active a' ),
							$filter_active = $filter_active_element.attr( 'data-filter' ).substr( 1 );

						// If active filter is not the "All" filter
						if ( $filter_active.length ) {
							// Show the new posts matching the active filter
							$posts.each( function() {
								var $post = jQuery( this ),
									$post_gallery_name = $post.find( '.fusion-rollover-gallery' ).data( 'rel' );

								if ( $post.hasClass( $filter_active ) ) {
									$post.fadeIn();

									// Set the lightbox gallery
									if ( $post_gallery_name ) {
										$post.find( '.fusion-rollover-gallery' ).attr( 'data-rel', $post_gallery_name.replace( 'gallery', $filter_active ) );
									}
								}
							});

							// Check if we need to create a new gallery
							if ( $filter_active_element.data( 'lightbox' ) != 'created' ) {

								// Create new lightbox instance for the new gallery
								$il_instances.push( jQuery( '[data-rel^="iLightbox[' + $filter_active + ']"]' ).iLightBox( $avada_lightbox.prepare_options( 'iLightbox[' + $filter_active + ']' ) ) );

								// Set active filter to lightbox created
								$filter_active_element.data( 'lightbox', 'created' );
							}

							// Refresh the lightbox, needed in any case
							$avada_lightbox.refresh_lightbox();

						} else {
							$posts.fadeIn();
						}
					} else {
						$posts.fadeIn();
					}

					// Trigger isotope for correct positioning
					$infinte_scroll_container.isotope( 'appended', $posts );

					// Trigger fitvids
					$posts.each(function() {
						jQuery( this ).find( '.full-video, .video-shortcode, .wooslider .slide-content' ).fitVids();
					});

					// Refresh the scrollspy script for one page layouts
					jQuery( '[data-spy="scroll"]' ).each(function () {
						  var $spy = jQuery( this ).scrollspy( 'refresh' );
					});

					// Hide the load more button, if the currently loaded page is already the last page
					$current_page = $infinte_scroll_container.find( '.current' ).html();
					$infinte_scroll_container.find( '.current' ).remove();

					if ( $infinte_scroll_container.data( 'pages' ) == $current_page ) {
						$infinte_scroll_container.parent().find( '.fusion-loading-container' ).hide();
						$infinte_scroll_container.parent().find( '.fusion-load-more-button' ).hide();
					}
				});
			}
		});

		// Hide the load more button, if there is only one page
		if ( $infinte_scroll_container.data( 'pages' ) == '1' ) {
			$infinte_scroll_container.parent().find( '.fusion-loading-container' ).hide();
			$infinte_scroll_container.parent().find( '.fusion-load-more-button' ).hide();
		}

		// Setup infinite scroll manual loading
		if ( js_local_vars.portfolio_pagination_type == 'load_more_button' ) {
			$infinte_scroll_container.infinitescroll( 'unbind' );

			jQuery( '.fusion-portfolio' ).find( '.fusion-load-more-button' ).on( 'click', function(e) {
				e.preventDefault();

				// Use the retrieve method to get the next set of posts
				$infinte_scroll_container.infinitescroll( 'retrieve' );

				// Trigger isotope for correct positioning
				$infinte_scroll_container.isotope();
			});
		}
	}
});


// Prevent anchor jumping on page load
if ( location.hash && location.hash.substring( 0, 2 ) === '#_' ) {
	var $hash = location.hash.substring( 2 );

	// Add the anchor link to the hidden a tag
	jQuery( '.fusion-page-load-link' ).attr( 'href', '#' + $hash );

	// Scroll the page
	jQuery( window ).load( function() {
		if ( jQuery( '.fusion-blog-shortcode' ).length ) {
			setTimeout( function() {
				jQuery( '.fusion-page-load-link' ).fusion_scroll_to_anchor_target();
			}, 300 );
		} else {
			jQuery( '.fusion-page-load-link' ).fusion_scroll_to_anchor_target();
		}
	});
}
