/* Minification failed. Returning unminified contents.
(1499,143-150): run-time error JS1019: Can't have 'break' outside of loop: break n
(1498,452-459): run-time error JS1019: Can't have 'break' outside of loop: break n
 */
/**
* Modified September 2015 (by Bee)
* Set up to use specific media atributes to avoid conflicts with other data atributes, and fix bug with * * inline image option.  Datat atributes required are as follows:
* data-media (default - mobile)
* data-media-sm (samll -  768px)
* data-media-md (medium - 1024px)
* data-media-lg (large -1440px)
* Will fallback to next size down if not set. data-media is minimum requirement to work.

* Note - Previously modified to use data-imagetype to switch between background image on the element or injecting an image tag.  Appears to fallback to background image if not provided.  Not sure who by/when this was added.

 * June 2013
 * MODIFIED TO WORK IN IE7 & IE8 - LittleBigTank.com
 *
 * jQuery Picture
 * http://jquerypicture.com
 * http://github.com/Abban/jQuery-Picture
 *
 * May 2012
 *
 * @version 0.9
 * @author Abban Dunne http://abandon.ie
 * @license MIT
 *
 * jQuery Picture is a plugin to add support for responsive images to your layouts.
 * It supports both figure elements with some custom data attributes and the new
 * proposed picture format. This plugin will be made redundant when the format is
 * approved and implemented by browsers. Lets hope that happens soon. In the meantime
 * this plugin will be kept up to date with latest developments.
 *
 */
(function ($) {
    $.fn.picture = function (args) {
        var defaults = {
            container: null,
            ignorePixelRatio: true, /* ignore retinal screen */
            useLarger: false,
            insertElement: '>a',
            inlineDimensions: false,
            background: false,
            breakSM: 480, /*default breakpoints*/
            breakMD: 768,
            breakLG: 1024
        };

        var settings = $.extend({}, defaults, args);

        this.each(function () {

            var mediaObj;

            var breakpoints = [0, settings.breakSM, settings.breakMD, settings.breakLG];
            var windowWidth, currentMedia, element, timeoutOffset;

            // Check the device pixel ratio
            var PixelRatio = 1;
            if (!settings.ignorePixelRatio && window.devicePixelRatio !== undefined) PixelRatio = window.devicePixelRatio;

            // Save off the element so it can be easily used inside a function
            element = $(this);

            //Delete the noscript we don't need it now anyway
            element.find('noscript').remove();

            // Initialise the images
            getCurrentMedia(true);

            // Only call the image resize function 200ms after window stops being resized
            timeoutOffset = false;

            $(window).resize(function () {
                if (timeoutOffset !== false)
                    clearTimeout(timeoutOffset);
                timeoutOffset = setTimeout(getCurrentMedia, 200);
            });



            /*
            * getCurrentMedia
            * Checks the window width off the media query types and selects the current one.
            * Calls the setPicture or setFigure function to set the image.
            */
            function getCurrentMedia(init) {

                if (init) {
                    mediaObj = element.data();
                    breakpoints.sort(function (a, b) { return a - b }); //make sure the largest breakpoint is the last
                }

                var c = 0;


                // Check if user defined container, otherwise take window
                if (settings.container == null) {
                    windowWidth = ($(window).width()) * PixelRatio;
                } else {
                    windowWidth = ($(settings.container).width()) * PixelRatio;
                }

                // Set the c variable to the current media width
                $.each(breakpoints, function (i, v) {
                    if (parseInt(windowWidth) >= parseInt(v) && parseInt(c) <= parseInt(v))
                        c = v;
                });

                if (settings.useLarger) {
                    idx = breakpoints.indexOf(c);
                    if (idx < breakpoints.length - 1) //make sure we're not already using the largest breakpoint
                        c = breakpoints[idx + 1];
                }

                if (currentMedia !== c) {
                    currentMedia = c;

                    if(mediaObj.imagetype == "inline"){
                        setImage();
                    }else if(mediaObj.imagetype == "background"){
                        setBackground();
                    }else{
                        if (!settings.background)
                            setImage();
                        else
                            setBackground();
                    }


                }
            }


            /*
            * setImage
            * Pulls the image src and and media values from the data attributes
            * and sets the src of the enclosed img tag to the appropriate one.
            */
            function setImage() {
                var sizes = getSizeList();

                if (element.find('img.reponsive-placeholder').length == 0) {
                    var prep = '<img class="reponsive-placeholder" src="' + sizes[currentMedia] + '"';
                    if (element.attr('style')) prep += ' style="' + element.attr('style') + '"';
                    if (element.attr('title')) prep += ' alt="' + element.attr('title') + '"';
                    prep += '>';

                    if ($(settings.insertElement, element).length == 0) {
                        element.prepend(prep);
                    } else {
                        $(settings.insertElement, element).prepend(prep);
                    }
                } else {
                    $('img.reponsive-placeholder', element).attr('src', sizes[currentMedia]);
                }

                if (settings.inlineDimensions) {
                    $("<img/>").attr("src", $('img.reponsive-placeholder', element).attr("src")).load(function () {
                        $('img', element).attr('height', this.height);
                        $('img', element).attr('width', this.width);
                    });
                }
            }


            /*
            * setBackground
            * Pulls the image src and and media values from the data attributes
            * and sets the src of the enclosed img tag to the appropriate one.
            */
            function setBackground() {
                var sizes = getSizeList();
                element.css("background-image", "url(" + sizes[currentMedia] + ")");
                element.css("background-repeat", "no-repeat");
            }


            /*
            * getSizeList
            * gets list of media sizes
            */
            function getSizeList() {
                var sizes = new Object();
                var mediaObj = element.data();

                sizes[0] = mediaObj.media;
                sizes[settings.breakSM] = mediaObj['mediaSm'] || mediaObj.media;
                sizes[settings.breakMD] = mediaObj['mediaMd'] || mediaObj['mediaSm'] || mediaObj.media;
                sizes[settings.breakLG] = mediaObj['mediaLg'] || mediaObj['mediaMd'] || mediaObj['mediaSm'] || mediaObj.media;

                return sizes;
            }
        });
    };
})(jQuery);
;
/*! jQuery Validation Plugin - v1.15.0 - 2/24/2016
 * http://jqueryvalidation.org/
 * Copyright (c) 2016 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.settings.submitHandler?(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){if(this.length){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||-1!==a.inArray(c.keyCode,d)||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable]",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=h&&g.check(e)))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)a[b]&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0]),d in c||!b.objectLength(a(this).rules())?!1:(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);if("function"==typeof f.normalizer){if(i=f.normalizer.call(b,i),"string"!=typeof i)throw new TypeError("The normalizer should return a string value.");delete f.normalizer}for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j instanceof TypeError&&(j.message+=".  Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]},defaultMessage:function(b,c){var d=this.findDefined(this.customMessage(b.name,c.method),this.customDataMessage(b,c.method),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c.method],"<strong>Warning: No message defined for "+b.name+"</strong>"),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e=a(c).attr("type"),f="Step attribute on input type "+e+" is not supported.",g=["text","number","range"],h=new RegExp("\\b"+e+"\\b"),i=e&&!h.test(g.join());if(i)throw new Error(f);return this.optional(c)||b%d===0},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)})});;
// Unobtrusive validation support library for jQuery and jQuery Validate
// Copyright (C) Microsoft Corporation. All rights reserved.
// @version <placeholder>

/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */

(function ($) {
    var $jQval = $.validator,
        adapters,
        data_validation = "unobtrusiveValidation";

    function setValidationValues(options, ruleName, value) {
        options.rules[ruleName] = value;
        if (options.message) {
            options.messages[ruleName] = options.message;
        }
    }

    function splitAndTrim(value) {
        return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
    }

    function escapeAttributeValue(value) {
        // As mentioned on http://api.jquery.com/category/selectors/
        return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
    }

    function getModelPrefix(fieldName) {
        return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
    }

    function appendModelPrefix(value, prefix) {
        if (value.indexOf("*.") === 0) {
            value = value.replace("*.", prefix);
        }
        return value;
    }

    function onError(error, inputElement) {  // 'this' is the form element
        var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
            replaceAttrValue = container.attr("data-valmsg-replace"),
            replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;

        container.removeClass("field-validation-valid").addClass("field-validation-error");
        error.data("unobtrusiveContainer", container);

        if (replace) {
            container.empty();
            error.removeClass("input-validation-error").appendTo(container);
        }
        else {
            error.hide();
        }
    }

    function onErrors(event, validator) {  // 'this' is the form element
        var container = $(this).find("[data-valmsg-summary=true]"),
            list = container.find("ul");

        if (list && list.length && validator.errorList.length) {
            list.empty();
            container.addClass("validation-summary-errors").removeClass("validation-summary-valid");

            $.each(validator.errorList, function () {
                $("<li />").html(this.message).appendTo(list);
            });
        }
    }

    function onSuccess(error) {  // 'this' is the form element
        var container = error.data("unobtrusiveContainer");

        if (container) {
            var replaceAttrValue = container.attr("data-valmsg-replace"),
                replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;

            container.addClass("field-validation-valid").removeClass("field-validation-error");
            error.removeData("unobtrusiveContainer");

            if (replace) {
                container.empty();
            }
        }
    }

    function onReset(event) {  // 'this' is the form element
        var $form = $(this),
            key = '__jquery_unobtrusive_validation_form_reset';
        if ($form.data(key)) {
            return;
        }
        // Set a flag that indicates we're currently resetting the form.
        $form.data(key, true);
        try {
            $form.data("validator").resetForm();
        } finally {
            $form.removeData(key);
        }

        $form.find(".validation-summary-errors")
            .addClass("validation-summary-valid")
            .removeClass("validation-summary-errors");
        $form.find(".field-validation-error")
            .addClass("field-validation-valid")
            .removeClass("field-validation-error")
            .removeData("unobtrusiveContainer")
            .find(">*")  // If we were using valmsg-replace, get the underlying error
                .removeData("unobtrusiveContainer");
    }

    function validationInfo(form) {
        var $form = $(form),
            result = $form.data(data_validation),
            onResetProxy = $.proxy(onReset, form),
            defaultOptions = $jQval.unobtrusive.options || {},
            execInContext = function (name, args) {
                var func = defaultOptions[name];
                func && $.isFunction(func) && func.apply(form, args);
            }

        if (!result) {
            result = {
                options: {  // options structure passed to jQuery Validate's validate() method
                    errorClass: defaultOptions.errorClass || "input-validation-error",
                    errorElement: defaultOptions.errorElement || "span",
                    errorPlacement: function () {
                        onError.apply(form, arguments);
                        execInContext("errorPlacement", arguments);
                    },
                    invalidHandler: function () {
                        onErrors.apply(form, arguments);
                        execInContext("invalidHandler", arguments);
                    },
                    messages: {},
                    rules: {},
                    success: function () {
                        onSuccess.apply(form, arguments);
                        execInContext("success", arguments);
                    }
                },
                attachValidation: function () {
                    $form
                        .off("reset." + data_validation, onResetProxy)
                        .on("reset." + data_validation, onResetProxy)
                        .validate(this.options);
                },
                validate: function () {  // a validation function that is called by unobtrusive Ajax
                    $form.validate();
                    return $form.valid();
                }
            };
            $form.data(data_validation, result);
        }

        return result;
    }

    $jQval.unobtrusive = {
        adapters: [],

        parseElement: function (element, skipAttach) {
            /// <summary>
            /// Parses a single HTML element for unobtrusive validation attributes.
            /// </summary>
            /// <param name="element" domElement="true">The HTML element to be parsed.</param>
            /// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
            /// validation to the form. If parsing just this single element, you should specify true.
            /// If parsing several elements, you should specify false, and manually attach the validation
            /// to the form when you are finished. The default is false.</param>
            var $element = $(element),
                form = $element.parents("form")[0],
                valInfo, rules, messages;

            if (!form) {  // Cannot do client-side validation without a form
                return;
            }

            valInfo = validationInfo(form);
            valInfo.options.rules[element.name] = rules = {};
            valInfo.options.messages[element.name] = messages = {};

            $.each(this.adapters, function () {
                var prefix = "data-val-" + this.name,
                    message = $element.attr(prefix),
                    paramValues = {};

                if (message !== undefined) {  // Compare against undefined, because an empty message is legal (and falsy)
                    prefix += "-";

                    $.each(this.params, function () {
                        paramValues[this] = $element.attr(prefix + this);
                    });

                    this.adapt({
                        element: element,
                        form: form,
                        message: message,
                        params: paramValues,
                        rules: rules,
                        messages: messages
                    });
                }
            });

            $.extend(rules, { "__dummy__": true });

            if (!skipAttach) {
                valInfo.attachValidation();
            }
        },

        parse: function (selector) {
            /// <summary>
            /// Parses all the HTML elements in the specified selector. It looks for input elements decorated
            /// with the [data-val=true] attribute value and enables validation according to the data-val-*
            /// attribute values.
            /// </summary>
            /// <param name="selector" type="String">Any valid jQuery selector.</param>

            // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
            // element with data-val=true
            var $selector = $(selector),
                $forms = $selector.parents()
                                  .addBack()
                                  .filter("form")
                                  .add($selector.find("form"))
                                  .has("[data-val=true]");

            $selector.find("[data-val=true]").each(function () {
                $jQval.unobtrusive.parseElement(this, true);
            });

            $forms.each(function () {
                var info = validationInfo(this);
                if (info) {
                    info.attachValidation();
                }
            });
        }
    };

    adapters = $jQval.unobtrusive.adapters;

    adapters.add = function (adapterName, params, fn) {
        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
        /// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
        /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
        /// mmmm is the parameter name).</param>
        /// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
        /// attributes into jQuery Validate rules and/or messages.</param>
        /// <returns type="jQuery.validator.unobtrusive.adapters" />
        if (!fn) {  // Called with no params, just a function
            fn = params;
            params = [];
        }
        this.push({ name: adapterName, params: params, adapt: fn });
        return this;
    };

    adapters.addBool = function (adapterName, ruleName) {
        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
        /// the jQuery Validate validation rule has no parameter values.</summary>
        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
        /// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
        /// of adapterName will be used instead.</param>
        /// <returns type="jQuery.validator.unobtrusive.adapters" />
        return this.add(adapterName, function (options) {
            setValidationValues(options, ruleName || adapterName, true);
        });
    };

    adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
        /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
        /// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
        /// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
        /// have a minimum value.</param>
        /// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
        /// have a maximum value.</param>
        /// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
        /// have both a minimum and maximum value.</param>
        /// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
        /// contains the minimum value. The default is "min".</param>
        /// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
        /// contains the maximum value. The default is "max".</param>
        /// <returns type="jQuery.validator.unobtrusive.adapters" />
        return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
            var min = options.params.min,
                max = options.params.max;

            if (min && max) {
                setValidationValues(options, minMaxRuleName, [min, max]);
            }
            else if (min) {
                setValidationValues(options, minRuleName, min);
            }
            else if (max) {
                setValidationValues(options, maxRuleName, max);
            }
        });
    };

    adapters.addSingleVal = function (adapterName, attribute, ruleName) {
        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
        /// the jQuery Validate validation rule has a single value.</summary>
        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
        /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
        /// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
        /// The default is "val".</param>
        /// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
        /// of adapterName will be used instead.</param>
        /// <returns type="jQuery.validator.unobtrusive.adapters" />
        return this.add(adapterName, [attribute || "val"], function (options) {
            setValidationValues(options, ruleName || adapterName, options.params[attribute]);
        });
    };

    $jQval.addMethod("__dummy__", function (value, element, params) {
        return true;
    });

    $jQval.addMethod("regex", function (value, element, params) {
        var match;
        if (this.optional(element)) {
            return true;
        }

        match = new RegExp(params).exec(value);
        return (match && (match.index === 0) && (match[0].length === value.length));
    });

    $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
        var match;
        if (nonalphamin) {
            match = value.match(/\W/g);
            match = match && match.length >= nonalphamin;
        }
        return match;
    });

    if ($jQval.methods.extension) {
        adapters.addSingleVal("accept", "mimtype");
        adapters.addSingleVal("extension", "extension");
    } else {
        // for backward compatibility, when the 'extension' validation method does not exist, such as with versions
        // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
        // validating the extension, and ignore mime-type validations as they are not supported.
        adapters.addSingleVal("extension", "extension", "accept");
    }

    adapters.addSingleVal("regex", "pattern");
    adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
    adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
    adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
    adapters.add("equalto", ["other"], function (options) {
        var prefix = getModelPrefix(options.element.name),
            other = options.params.other,
            fullOtherName = appendModelPrefix(other, prefix),
            element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];

        setValidationValues(options, "equalTo", element);
    });
    adapters.add("required", function (options) {
        // jQuery Validate equates "required" with "mandatory" for checkbox elements
        if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
            setValidationValues(options, "required", true);
        }
    });
    adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
        var value = {
            url: options.params.url,
            type: options.params.type || "GET",
            data: {}
        },
            prefix = getModelPrefix(options.element.name);

        $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
            var paramName = appendModelPrefix(fieldName, prefix);
            value.data[paramName] = function () {
                var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
                // For checkboxes and radio buttons, only pick up values from checked fields.
                if (field.is(":checkbox")) {
                    return field.filter(":checked").val() || field.filter(":hidden").val() || '';
                }
                else if (field.is(":radio")) {
                    return field.filter(":checked").val() || '';
                }
                return field.val();
            };
        });

        setValidationValues(options, "remote", value);
    });
    adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
        if (options.params.min) {
            setValidationValues(options, "minlength", options.params.min);
        }
        if (options.params.nonalphamin) {
            setValidationValues(options, "nonalphamin", options.params.nonalphamin);
        }
        if (options.params.regex) {
            setValidationValues(options, "regex", options.params.regex);
        }
    });

    $(function () {
        $jQval.unobtrusive.parse(document);
    });
}(jQuery));;
/*! modernizr 3.5.0 (Custom Build) | MIT *
 * https://modernizr.com/download/?-csstransforms-csstransforms3d-filereader-svg-touchevents-setclasses !*/
!function (e, t, n) { function r(e, t) { return typeof e === t } function s() { var e, t, n, s, o, i, a; for (var l in w) if (w.hasOwnProperty(l)) { if (e = [], t = w[l], t.name && (e.push(t.name.toLowerCase()), t.options && t.options.aliases && t.options.aliases.length)) for (n = 0; n < t.options.aliases.length; n++)e.push(t.options.aliases[n].toLowerCase()); for (s = r(t.fn, "function") ? t.fn() : t.fn, o = 0; o < e.length; o++)i = e[o], a = i.split("."), 1 === a.length ? Modernizr[a[0]] = s : (!Modernizr[a[0]] || Modernizr[a[0]] instanceof Boolean || (Modernizr[a[0]] = new Boolean(Modernizr[a[0]])), Modernizr[a[0]][a[1]] = s), S.push((s ? "" : "no-") + a.join("-")) } } function o(e) { var t = x.className, n = Modernizr._config.classPrefix || ""; if (_ && (t = t.baseVal), Modernizr._config.enableJSClass) { var r = new RegExp("(^|\\s)" + n + "no-js(\\s|$)"); t = t.replace(r, "$1" + n + "js$2") } Modernizr._config.enableClasses && (t += " " + n + e.join(" " + n), _ ? x.className.baseVal = t : x.className = t) } function i() { return "function" != typeof t.createElement ? t.createElement(arguments[0]) : _ ? t.createElementNS.call(t, "http://www.w3.org/2000/svg", arguments[0]) : t.createElement.apply(t, arguments) } function a() { var e = t.body; return e || (e = i(_ ? "svg" : "body"), e.fake = !0), e } function l(e, n, r, s) { var o, l, f, u, d = "modernizr", c = i("div"), p = a(); if (parseInt(r, 10)) for (; r--;)f = i("div"), f.id = s ? s[r] : d + (r + 1), c.appendChild(f); return o = i("style"), o.type = "text/css", o.id = "s" + d, (p.fake ? p : c).appendChild(o), p.appendChild(c), o.styleSheet ? o.styleSheet.cssText = e : o.appendChild(t.createTextNode(e)), c.id = d, p.fake && (p.style.background = "", p.style.overflow = "hidden", u = x.style.overflow, x.style.overflow = "hidden", x.appendChild(p)), l = n(c, e), p.fake ? (p.parentNode.removeChild(p), x.style.overflow = u, x.offsetHeight) : c.parentNode.removeChild(c), !!l } function f(e, t) { return !!~("" + e).indexOf(t) } function u(e) { return e.replace(/([a-z])-([a-z])/g, function (e, t, n) { return t + n.toUpperCase() }).replace(/^-/, "") } function d(e, t) { return function () { return e.apply(t, arguments) } } function c(e, t, n) { var s; for (var o in e) if (e[o] in t) return n === !1 ? e[o] : (s = t[e[o]], r(s, "function") ? d(s, n || t) : s); return !1 } function p(e) { return e.replace(/([A-Z])/g, function (e, t) { return "-" + t.toLowerCase() }).replace(/^ms-/, "-ms-") } function m(t, n, r) { var s; if ("getComputedStyle" in e) { s = getComputedStyle.call(e, t, n); var o = e.console; if (null !== s) r && (s = s.getPropertyValue(r)); else if (o) { var i = o.error ? "error" : "log"; o[i].call(o, "getComputedStyle returning null, its possible modernizr test results are inaccurate") } } else s = !n && t.currentStyle && t.currentStyle[r]; return s } function v(t, r) { var s = t.length; if ("CSS" in e && "supports" in e.CSS) { for (; s--;)if (e.CSS.supports(p(t[s]), r)) return !0; return !1 } if ("CSSSupportsRule" in e) { for (var o = []; s--;)o.push("(" + p(t[s]) + ":" + r + ")"); return o = o.join(" or "), l("@supports (" + o + ") { #modernizr { position: absolute; } }", function (e) { return "absolute" == m(e, null, "position") }) } return n } function h(e, t, s, o) { function a() { d && (delete A.style, delete A.modElem) } if (o = r(o, "undefined") ? !1 : o, !r(s, "undefined")) { var l = v(e, s); if (!r(l, "undefined")) return l } for (var d, c, p, m, h, g = ["modernizr", "tspan", "samp"]; !A.style && g.length;)d = !0, A.modElem = i(g.shift()), A.style = A.modElem.style; for (p = e.length, c = 0; p > c; c++)if (m = e[c], h = A.style[m], f(m, "-") && (m = u(m)), A.style[m] !== n) { if (o || r(s, "undefined")) return a(), "pfx" == t ? m : !0; try { A.style[m] = s } catch (y) { } if (A.style[m] != h) return a(), "pfx" == t ? m : !0 } return a(), !1 } function g(e, t, n, s, o) { var i = e.charAt(0).toUpperCase() + e.slice(1), a = (e + " " + N.join(i + " ") + i).split(" "); return r(t, "string") || r(t, "undefined") ? h(a, t, s, o) : (a = (e + " " + j.join(i + " ") + i).split(" "), c(a, t, n)) } function y(e, t, r) { return g(e, n, n, t, r) } var S = [], w = [], C = { _version: "3.5.0", _config: { classPrefix: "", enableClasses: !0, enableJSClass: !0, usePrefixes: !0 }, _q: [], on: function (e, t) { var n = this; setTimeout(function () { t(n[e]) }, 0) }, addTest: function (e, t, n) { w.push({ name: e, fn: t, options: n }) }, addAsyncTest: function (e) { w.push({ name: null, fn: e }) } }, Modernizr = function () { }; Modernizr.prototype = C, Modernizr = new Modernizr, Modernizr.addTest("svg", !!t.createElementNS && !!t.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGRect); var x = t.documentElement, _ = "svg" === x.nodeName.toLowerCase(), b = C._config.usePrefixes ? " -webkit- -moz- -o- -ms- ".split(" ") : ["", ""]; C._prefixes = b; var T = "CSS" in e && "supports" in e.CSS, z = "supportsCSS" in e; Modernizr.addTest("supports", T || z); var P = C.testStyles = l; Modernizr.addTest("touchevents", function () { var n; if ("ontouchstart" in e || e.DocumentTouch && t instanceof DocumentTouch) n = !0; else { var r = ["@media (", b.join("touch-enabled),("), "heartz", ")", "{#modernizr{top:9px;position:absolute}}"].join(""); P(r, function (e) { n = 9 === e.offsetTop }) } return n }); var E = "Moz O ms Webkit", N = C._config.usePrefixes ? E.split(" ") : []; C._cssomPrefixes = N; var j = C._config.usePrefixes ? E.toLowerCase().split(" ") : []; C._domPrefixes = j, Modernizr.addTest("filereader", !!(e.File && e.FileList && e.FileReader)); var k = { elem: i("modernizr") }; Modernizr._q.push(function () { delete k.elem }); var A = { style: k.elem.style }; Modernizr._q.unshift(function () { delete A.style }), C.testAllProps = g, C.testAllProps = y, Modernizr.addTest("csstransforms", function () { return -1 === navigator.userAgent.indexOf("Android 2.") && y("transform", "scale(1)", !0) }), Modernizr.addTest("csstransforms3d", function () { var e = !!y("perspective", "1px", !0), t = Modernizr._config.usePrefixes; if (e && (!t || "webkitPerspective" in x.style)) { var n, r = "#modernizr{width:0;height:0}"; Modernizr.supports ? n = "@supports (perspective: 1px)" : (n = "@media (transform-3d)", t && (n += ",(-webkit-transform-3d)")), n += "{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}", P(r + n, function (t) { e = 7 === t.offsetWidth && 18 === t.offsetHeight }) } return e }), s(), o(S), delete C.addTest, delete C.addAsyncTest; for (var L = 0; L < Modernizr._q.length; L++)Modernizr._q[L](); e.Modernizr = Modernizr }(window, document);;
(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
	typeof define === 'function' && define.amd ? define(factory) :
	(factory());
}(this, (function () { 'use strict';

/**
 * @this {Promise}
 */
function finallyConstructor(callback) {
  var constructor = this.constructor;
  return this.then(
    function(value) {
      // @ts-ignore
      return constructor.resolve(callback()).then(function() {
        return value;
      });
    },
    function(reason) {
      // @ts-ignore
      return constructor.resolve(callback()).then(function() {
        // @ts-ignore
        return constructor.reject(reason);
      });
    }
  );
}

// Store setTimeout reference so promise-polyfill will be unaffected by
// other code modifying setTimeout (like sinon.useFakeTimers())
var setTimeoutFunc = setTimeout;

function isArray(x) {
  return Boolean(x && typeof x.length !== 'undefined');
}

function noop() {}

// Polyfill for Function.prototype.bind
function bind(fn, thisArg) {
  return function() {
    fn.apply(thisArg, arguments);
  };
}

/**
 * @constructor
 * @param {Function} fn
 */
function Promise(fn) {
  if (!(this instanceof Promise))
    throw new TypeError('Promises must be constructed via new');
  if (typeof fn !== 'function') throw new TypeError('not a function');
  /** @type {!number} */
  this._state = 0;
  /** @type {!boolean} */
  this._handled = false;
  /** @type {Promise|undefined} */
  this._value = undefined;
  /** @type {!Array<!Function>} */
  this._deferreds = [];

  doResolve(fn, this);
}

function handle(self, deferred) {
  while (self._state === 3) {
    self = self._value;
  }
  if (self._state === 0) {
    self._deferreds.push(deferred);
    return;
  }
  self._handled = true;
  Promise._immediateFn(function() {
    var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
    if (cb === null) {
      (self._state === 1 ? resolve : reject)(deferred.promise, self._value);
      return;
    }
    var ret;
    try {
      ret = cb(self._value);
    } catch (e) {
      reject(deferred.promise, e);
      return;
    }
    resolve(deferred.promise, ret);
  });
}

function resolve(self, newValue) {
  try {
    // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
    if (newValue === self)
      throw new TypeError('A promise cannot be resolved with itself.');
    if (
      newValue &&
      (typeof newValue === 'object' || typeof newValue === 'function')
    ) {
      var then = newValue.then;
      if (newValue instanceof Promise) {
        self._state = 3;
        self._value = newValue;
        finale(self);
        return;
      } else if (typeof then === 'function') {
        doResolve(bind(then, newValue), self);
        return;
      }
    }
    self._state = 1;
    self._value = newValue;
    finale(self);
  } catch (e) {
    reject(self, e);
  }
}

function reject(self, newValue) {
  self._state = 2;
  self._value = newValue;
  finale(self);
}

function finale(self) {
  if (self._state === 2 && self._deferreds.length === 0) {
    Promise._immediateFn(function() {
      if (!self._handled) {
        Promise._unhandledRejectionFn(self._value);
      }
    });
  }

  for (var i = 0, len = self._deferreds.length; i < len; i++) {
    handle(self, self._deferreds[i]);
  }
  self._deferreds = null;
}

/**
 * @constructor
 */
function Handler(onFulfilled, onRejected, promise) {
  this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
  this.onRejected = typeof onRejected === 'function' ? onRejected : null;
  this.promise = promise;
}

/**
 * Take a potentially misbehaving resolver function and make sure
 * onFulfilled and onRejected are only called once.
 *
 * Makes no guarantees about asynchrony.
 */
function doResolve(fn, self) {
  var done = false;
  try {
    fn(
      function(value) {
        if (done) return;
        done = true;
        resolve(self, value);
      },
      function(reason) {
        if (done) return;
        done = true;
        reject(self, reason);
      }
    );
  } catch (ex) {
    if (done) return;
    done = true;
    reject(self, ex);
  }
}

Promise.prototype['catch'] = function(onRejected) {
  return this.then(null, onRejected);
};

Promise.prototype.then = function(onFulfilled, onRejected) {
  // @ts-ignore
  var prom = new this.constructor(noop);

  handle(this, new Handler(onFulfilled, onRejected, prom));
  return prom;
};

Promise.prototype['finally'] = finallyConstructor;

Promise.all = function(arr) {
  return new Promise(function(resolve, reject) {
    if (!isArray(arr)) {
      return reject(new TypeError('Promise.all accepts an array'));
    }

    var args = Array.prototype.slice.call(arr);
    if (args.length === 0) return resolve([]);
    var remaining = args.length;

    function res(i, val) {
      try {
        if (val && (typeof val === 'object' || typeof val === 'function')) {
          var then = val.then;
          if (typeof then === 'function') {
            then.call(
              val,
              function(val) {
                res(i, val);
              },
              reject
            );
            return;
          }
        }
        args[i] = val;
        if (--remaining === 0) {
          resolve(args);
        }
      } catch (ex) {
        reject(ex);
      }
    }

    for (var i = 0; i < args.length; i++) {
      res(i, args[i]);
    }
  });
};

Promise.resolve = function(value) {
  if (value && typeof value === 'object' && value.constructor === Promise) {
    return value;
  }

  return new Promise(function(resolve) {
    resolve(value);
  });
};

Promise.reject = function(value) {
  return new Promise(function(resolve, reject) {
    reject(value);
  });
};

Promise.race = function(arr) {
  return new Promise(function(resolve, reject) {
    if (!isArray(arr)) {
      return reject(new TypeError('Promise.race accepts an array'));
    }

    for (var i = 0, len = arr.length; i < len; i++) {
      Promise.resolve(arr[i]).then(resolve, reject);
    }
  });
};

// Use polyfill for setImmediate for performance gains
Promise._immediateFn =
  // @ts-ignore
  (typeof setImmediate === 'function' &&
    function(fn) {
      // @ts-ignore
      setImmediate(fn);
    }) ||
  function(fn) {
    setTimeoutFunc(fn, 0);
  };

Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
  if (typeof console !== 'undefined' && console) {
    console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
  }
};

/** @suppress {undefinedVars} */
var globalNS = (function() {
  // the only reliable means to get the global object is
  // `Function('return this')()`
  // However, this causes CSP violations in Chrome apps.
  if (typeof self !== 'undefined') {
    return self;
  }
  if (typeof window !== 'undefined') {
    return window;
  }
  if (typeof global !== 'undefined') {
    return global;
  }
  throw new Error('unable to locate global object');
})();

if (!('Promise' in globalNS)) {
  globalNS['Promise'] = Promise;
} else if (!globalNS.Promise.prototype['finally']) {
  globalNS.Promise.prototype['finally'] = finallyConstructor;
}

})));
;
/* eslint-disable indent, strict */
// https://github.com/lifaon74/url-polyfill
(function(global) {
  /**
   * Polyfill URLSearchParams
   *
   * Inspired from : https://github.com/WebReflection/url-search-params/blob/master/src/url-search-params.js
   */

  var checkIfIteratorIsSupported = function() {
    try {
      return !!Symbol.iterator;
    } catch (error) {
      return false;
    }
  };


  var iteratorSupported = checkIfIteratorIsSupported();

  var createIterator = function(items) {
    var iterator = {
      next: function() {
        var value = items.shift();
        return { done: value === void 0, value: value };
      }
    };

    if (iteratorSupported) {
      // eslint-disable-next-line no-undef
      iterator[Symbol.iterator] = function() {
        return iterator;
      };
    }

    return iterator;
  };

  /**
   * Search param name and values should be encoded according to https://url.spec.whatwg.org/#urlencoded-serializing
   * encodeURIComponent() produces the same result except encoding spaces as `%20` instead of `+`.
   */
  var serializeParam = function(value) {
    return encodeURIComponent(value).replace(/%20/g, '+');
  };

  var deserializeParam = function(value) {
    return decodeURIComponent(String(value).replace(/\+/g, ' '));
  };

  var polyfillURLSearchParams = function() {

    var URLSearchParams = function(searchString) {
      Object.defineProperty(this, '_entries', { writable: true, value: {} });
      var typeofSearchString = typeof searchString;

      if (typeofSearchString === 'undefined') {
        // do nothing
      } else if (typeofSearchString === 'string') {
        if (searchString !== '') {
          this._fromString(searchString);
        }
      } else if (searchString instanceof URLSearchParams) {
        var _this = this;
        searchString.forEach(function(value, name) {
          _this.append(name, value);
        });
      } else if ((searchString !== null) && (typeofSearchString === 'object')) {
        if (Object.prototype.toString.call(searchString) === '[object Array]') {
          for (var i = 0; i < searchString.length; i++) {
            var entry = searchString[i];
            if ((Object.prototype.toString.call(entry) === '[object Array]') || (entry.length !== 2)) {
              this.append(entry[0], entry[1]);
            } else {
              throw new TypeError('Expected [string, any] as entry at index ' + i + ' of URLSearchParams\'s input');
            }
          }
        } else {
          for (var key in searchString) {
            if (searchString.hasOwnProperty(key)) {
              this.append(key, searchString[key]);
            }
          }
        }
      } else {
        throw new TypeError('Unsupported input\'s type for URLSearchParams');
      }
    };

    var proto = URLSearchParams.prototype;

    proto.append = function(name, value) {
      if (name in this._entries) {
        this._entries[name].push(String(value));
      } else {
        this._entries[name] = [String(value)];
      }
    };

    proto.delete = function(name) {
      delete this._entries[name];
    };

    proto.get = function(name) {
      return (name in this._entries) ? this._entries[name][0] : null;
    };

    proto.getAll = function(name) {
      return (name in this._entries) ? this._entries[name].slice(0) : [];
    };

    proto.has = function(name) {
      return (name in this._entries);
    };

    proto.set = function(name, value) {
      this._entries[name] = [String(value)];
    };

    proto.forEach = function(callback, thisArg) {
      var entries;
      for (var name in this._entries) {
        if (this._entries.hasOwnProperty(name)) {
          entries = this._entries[name];
          for (var i = 0; i < entries.length; i++) {
            callback.call(thisArg, entries[i], name, this);
          }
        }
      }
    };

    proto.keys = function() {
      var items = [];
      this.forEach(function(value, name) {
        items.push(name);
      });
      return createIterator(items);
    };

    proto.values = function() {
      var items = [];
      this.forEach(function(value) {
        items.push(value);
      });
      return createIterator(items);
    };

    proto.entries = function() {
      var items = [];
      this.forEach(function(value, name) {
        items.push([name, value]);
      });
      return createIterator(items);
    };

    if (iteratorSupported) {
      proto[Symbol.iterator] = proto.entries;
    }

    proto.toString = function() {
      var searchArray = [];
      this.forEach(function(value, name) {
        searchArray.push(serializeParam(name) + '=' + serializeParam(value));
      });
      return searchArray.join('&');
    };


    global.URLSearchParams = URLSearchParams;
  };

  var checkIfURLSearchParamsSupported = function() {
    try {
      var URLSearchParams = global.URLSearchParams;

      return (
        (new URLSearchParams('?a=1').toString() === 'a=1') &&
        (typeof URLSearchParams.prototype.set === 'function') &&
        (typeof URLSearchParams.prototype.entries === 'function')
      );
    } catch (e) {
      return false;
    }
  };

  if (!checkIfURLSearchParamsSupported()) {
    polyfillURLSearchParams();
  }

  var proto = global.URLSearchParams.prototype;

  if (typeof proto.sort !== 'function') {
    proto.sort = function() {
      var _this = this;
      var items = [];
      this.forEach(function(value, name) {
        items.push([name, value]);
        if (!_this._entries) {
          _this.delete(name);
        }
      });
      items.sort(function(a, b) {
        if (a[0] < b[0]) {
          return -1;
        } else if (a[0] > b[0]) {
          return +1;
        } else {
          return 0;
        }
      });
      if (_this._entries) { // force reset because IE keeps keys index
        _this._entries = {};
      }
      for (var i = 0; i < items.length; i++) {
        this.append(items[i][0], items[i][1]);
      }
    };
  }

  if (typeof proto._fromString !== 'function') {
    Object.defineProperty(proto, '_fromString', {
      enumerable: false,
      configurable: false,
      writable: false,
      value: function(searchString) {
        if (this._entries) {
          this._entries = {};
        } else {
          var keys = [];
          this.forEach(function(value, name) {
            keys.push(name);
          });
          for (var i = 0; i < keys.length; i++) {
            this.delete(keys[i]);
          }
        }

        searchString = searchString.replace(/^\?/, '');
        var attributes = searchString.split('&');
        var attribute;
        for (var i = 0; i < attributes.length; i++) {
          attribute = attributes[i].split('=');
          this.append(
            deserializeParam(attribute[0]),
            (attribute.length > 1) ? deserializeParam(attribute[1]) : ''
          );
        }
      }
    });
  }

  // HTMLAnchorElement

})(
  (typeof global !== 'undefined') ? global
    : ((typeof window !== 'undefined') ? window
    : ((typeof self !== 'undefined') ? self : this))
);

(function(global) {
  /**
   * Polyfill URL
   *
   * Inspired from : https://github.com/arv/DOM-URL-Polyfill/blob/master/src/url.js
   */

  var checkIfURLIsSupported = function() {
    try {
      var u = new global.URL('b', 'http://a');
      u.pathname = 'c d';
      return (u.href === 'http://a/c%20d') && u.searchParams;
    } catch (e) {
      return false;
    }
  };


  var polyfillURL = function() {
    var _URL = global.URL;

    var URL = function(url, base) {
      if (typeof url !== 'string') url = String(url);

      // Only create another document if the base is different from current location.
      var doc = document, baseElement;
      if (base && (global.location === void 0 || base !== global.location.href)) {
        doc = document.implementation.createHTMLDocument('');
        baseElement = doc.createElement('base');
        baseElement.href = base;
        doc.head.appendChild(baseElement);
        try {
          if (baseElement.href.indexOf(base) !== 0) throw new Error(baseElement.href);
        } catch (err) {
          throw new Error('URL unable to set base ' + base + ' due to ' + err);
        }
      }

      var anchorElement = doc.createElement('a');
      anchorElement.href = url;
      if (baseElement) {
        doc.body.appendChild(anchorElement);
        anchorElement.href = anchorElement.href; // force href to refresh
      }

      var inputElement = doc.createElement('input');
      inputElement.type = 'url';
      inputElement.value = url;

      if (anchorElement.protocol === ':' || !/:/.test(anchorElement.href) || (!inputElement.checkValidity() && !base)) {
        throw new TypeError('Invalid URL');
      }

      Object.defineProperty(this, '_anchorElement', {
        value: anchorElement
      });


      // create a linked searchParams which reflect its changes on URL
      var searchParams = new global.URLSearchParams(this.search);
      var enableSearchUpdate = true;
      var enableSearchParamsUpdate = true;
      var _this = this;
      ['append', 'delete', 'set'].forEach(function(methodName) {
        var method = searchParams[methodName];
        searchParams[methodName] = function() {
          method.apply(searchParams, arguments);
          if (enableSearchUpdate) {
            enableSearchParamsUpdate = false;
            _this.search = searchParams.toString();
            enableSearchParamsUpdate = true;
          }
        };
      });

      Object.defineProperty(this, 'searchParams', {
        value: searchParams,
        enumerable: true
      });

      var search = void 0;
      Object.defineProperty(this, '_updateSearchParams', {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function() {
          if (this.search !== search) {
            search = this.search;
            if (enableSearchParamsUpdate) {
              enableSearchUpdate = false;
              this.searchParams._fromString(this.search);
              enableSearchUpdate = true;
            }
          }
        }
      });
    };

    var proto = URL.prototype;

    var linkURLWithAnchorAttribute = function(attributeName) {
      Object.defineProperty(proto, attributeName, {
        get: function() {
          return this._anchorElement[attributeName];
        },
        set: function(value) {
          this._anchorElement[attributeName] = value;
        },
        enumerable: true
      });
    };

    ['hash', 'host', 'hostname', 'port', 'protocol']
      .forEach(function(attributeName) {
        linkURLWithAnchorAttribute(attributeName);
      });

    Object.defineProperty(proto, 'search', {
      get: function() {
        return this._anchorElement['search'];
      },
      set: function(value) {
        this._anchorElement['search'] = value;
        this._updateSearchParams();
      },
      enumerable: true
    });

    Object.defineProperties(proto, {

      'toString': {
        get: function() {
          var _this = this;
          return function() {
            return _this.href;
          };
        }
      },

      'href': {
        get: function() {
          return this._anchorElement.href.replace(/\?$/, '');
        },
        set: function(value) {
          this._anchorElement.href = value;
          this._updateSearchParams();
        },
        enumerable: true
      },

      'pathname': {
        get: function() {
          return this._anchorElement.pathname.replace(/(^\/?)/, '/');
        },
        set: function(value) {
          this._anchorElement.pathname = value;
        },
        enumerable: true
      },

      'origin': {
        get: function() {
          // get expected port from protocol
          var expectedPort = { 'http:': 80, 'https:': 443, 'ftp:': 21 }[this._anchorElement.protocol];
          // add port to origin if, expected port is different than actual port
          // and it is not empty f.e http://foo:8080
          // 8080 != 80 && 8080 != ''
          var addPortToOrigin = this._anchorElement.port != expectedPort &&
            this._anchorElement.port !== '';

          return this._anchorElement.protocol +
            '//' +
            this._anchorElement.hostname +
            (addPortToOrigin ? (':' + this._anchorElement.port) : '');
        },
        enumerable: true
      },

      'password': { // TODO
        get: function() {
          return '';
        },
        set: function(value) {
        },
        enumerable: true
      },

      'username': { // TODO
        get: function() {
          return '';
        },
        set: function(value) {
        },
        enumerable: true
      },
    });

    URL.createObjectURL = function(blob) {
      return _URL.createObjectURL.apply(_URL, arguments);
    };

    URL.revokeObjectURL = function(url) {
      return _URL.revokeObjectURL.apply(_URL, arguments);
    };

    global.URL = URL;

  };

  if (!checkIfURLIsSupported()) {
    polyfillURL();
  }

  if ((global.location !== void 0) && !('origin' in global.location)) {
    var getOrigin = function() {
      return global.location.protocol + '//' + global.location.hostname + (global.location.port ? (':' + global.location.port) : '');
    };

    try {
      Object.defineProperty(global.location, 'origin', {
        get: getOrigin,
        enumerable: true
      });
    } catch (e) {
      setInterval(function() {
        global.location.origin = getOrigin();
      }, 100);
    }
  }

})(
  (typeof global !== 'undefined') ? global
    : ((typeof window !== 'undefined') ? window
    : ((typeof self !== 'undefined') ? self : this))
);
;
/*! https://mths.be/startswith v0.2.0 by @mathias */
if (!String.prototype.startsWith) {
	(function() {
		'use strict'; // needed to support `apply`/`call` with `undefined`/`null`
		var defineProperty = (function() {
			// IE 8 only supports `Object.defineProperty` on DOM elements
			try {
				var object = {};
				var $defineProperty = Object.defineProperty;
				var result = $defineProperty(object, object, object) && $defineProperty;
			} catch(error) {}
			return result;
		}());
		var toString = {}.toString;
		var startsWith = function(search) {
			if (this == null) {
				throw TypeError();
			}
			var string = String(this);
			if (search && toString.call(search) == '[object RegExp]') {
				throw TypeError();
			}
			var stringLength = string.length;
			var searchString = String(search);
			var searchLength = searchString.length;
			var position = arguments.length > 1 ? arguments[1] : undefined;
			// `ToInteger`
			var pos = position ? Number(position) : 0;
			if (pos != pos) { // better `isNaN`
				pos = 0;
			}
			var start = Math.min(Math.max(pos, 0), stringLength);
			// Avoid the `indexOf` call if no match is possible
			if (searchLength + start > stringLength) {
				return false;
			}
			var index = -1;
			while (++index < searchLength) {
				if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {
					return false;
				}
			}
			return true;
		};
		if (defineProperty) {
			defineProperty(String.prototype, 'startsWith', {
				'value': startsWith,
				'configurable': true,
				'writable': true
			});
		} else {
			String.prototype.startsWith = startsWith;
		}
	}());
};
/**
 * @license
 * Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
 */
;(function(){function n(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function t(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u<i;){var o=n[u];t(e,o,r(o),n)}return e}function r(n,t){for(var r=-1,e=null==n?0:n.length;++r<e&&false!==t(n[r],r,n););return n}function e(n,t){for(var r=null==n?0:n.length;r--&&false!==t(n[r],r,n););return n}function u(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(!t(n[r],r,n))return false;
	return true}function i(n,t){for(var r=-1,e=null==n?0:n.length,u=0,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[u++]=o)}return i}function o(n,t){return!(null==n||!n.length)&&-1<v(n,t,0)}function f(n,t,r){for(var e=-1,u=null==n?0:n.length;++e<u;)if(r(t,n[e]))return true;return false}function c(n,t){for(var r=-1,e=null==n?0:n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function a(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function l(n,t,r,e){var u=-1,i=null==n?0:n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);
	return r}function s(n,t,r,e){var u=null==n?0:n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function h(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(t(n[r],r,n))return true;return false}function p(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,false}),e}function _(n,t,r,e){var u=n.length;for(r+=e?1:-1;e?r--:++r<u;)if(t(n[r],r,n))return r;return-1}function v(n,t,r){if(t===t)n:{--r;for(var e=n.length;++r<e;)if(n[r]===t){n=r;break n}n=-1}else n=_(n,d,r);return n}function g(n,t,r,e){
	--r;for(var u=n.length;++r<u;)if(e(n[r],t))return r;return-1}function d(n){return n!==n}function y(n,t){var r=null==n?0:n.length;return r?m(n,t)/r:F}function b(n){return function(t){return null==t?T:t[n]}}function x(n){return function(t){return null==n?T:n[t]}}function j(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function w(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function m(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==T&&(r=r===T?i:r+i)}return r;
	}function A(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function E(n,t){return c(t,function(t){return[t,n[t]]})}function k(n){return function(t){return n(t)}}function S(n,t){return c(t,function(t){return n[t]})}function O(n,t){return n.has(t)}function I(n,t){for(var r=-1,e=n.length;++r<e&&-1<v(t,n[r],0););return r}function R(n,t){for(var r=n.length;r--&&-1<v(t,n[r],0););return r}function z(n){return"\\"+Un[n]}function W(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n];
	}),r}function B(n,t){return function(r){return n(t(r))}}function L(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function U(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function C(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function D(n){if(Rn.test(n)){for(var t=On.lastIndex=0;On.test(n);)++t;n=t}else n=Qn(n);return n}function M(n){return Rn.test(n)?n.match(On)||[]:n.split("");
	}var T,$=1/0,F=NaN,N=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],P=/\b__p\+='';/g,Z=/\b(__p\+=)''\+/g,q=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39);/g,K=/[&<>"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,En="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",kn=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+En+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={};
	Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object DataView]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false;
	var Ln={};Ln["[object Arguments]"]=Ln["[object Array]"]=Ln["[object ArrayBuffer]"]=Ln["[object DataView]"]=Ln["[object Boolean]"]=Ln["[object Date]"]=Ln["[object Float32Array]"]=Ln["[object Float64Array]"]=Ln["[object Int8Array]"]=Ln["[object Int16Array]"]=Ln["[object Int32Array]"]=Ln["[object Map]"]=Ln["[object Number]"]=Ln["[object Object]"]=Ln["[object RegExp]"]=Ln["[object Set]"]=Ln["[object String]"]=Ln["[object Symbol]"]=Ln["[object Uint8Array]"]=Ln["[object Uint8ClampedArray]"]=Ln["[object Uint16Array]"]=Ln["[object Uint32Array]"]=true,
	Ln["[object Error]"]=Ln["[object Function]"]=Ln["[object WeakMap]"]=false;var Un={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){
	try{var n=Nn&&Nn.f&&Nn.f("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I",
	"\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C",
	"\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i",
	"\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r",
	"\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij",
	"\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}),tt=x({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"}),rt=function x(mn){function An(n){if(yu(n)&&!ff(n)&&!(n instanceof Un)){if(n instanceof On)return n;if(oi.call(n,"__wrapped__"))return Fe(n)}return new On(n)}function En(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Un(n){this.__wrapped__=n,
	this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Fn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Fn;++t<r;)this.add(n[t]);
	}function Zn(n){this.size=(this.__data__=new Tn(n)).size}function qn(n,t){var r,e=ff(n),u=!e&&of(n),i=!e&&!u&&af(n),o=!e&&!u&&!i&&_f(n),u=(e=e||u||i||o)?A(n.length,ni):[],f=u.length;for(r in n)!t&&!oi.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Se(r,f))||u.push(r);return u}function Qn(n){var t=n.length;return t?n[ir(0,t-1)]:T}function et(n,t){return De(Ur(n),pt(t,0,n.length))}function ut(n){return De(Ur(n))}function it(n,t,r){(r===T||lu(n[t],r))&&(r!==T||t in n)||st(n,t,r);
	}function ot(n,t,r){var e=n[t];oi.call(n,t)&&lu(e,r)&&(r!==T||t in n)||st(n,t,r)}function ft(n,t){for(var r=n.length;r--;)if(lu(n[r][0],t))return r;return-1}function ct(n,t,r,e){return uo(n,function(n,u,i){t(e,n,r(n),i)}),e}function at(n,t){return n&&Cr(t,Wu(t),n)}function lt(n,t){return n&&Cr(t,Bu(t),n)}function st(n,t,r){"__proto__"==t&&Ai?Ai(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function ht(n,t){for(var r=-1,e=t.length,u=Ku(e),i=null==n;++r<e;)u[r]=i?T:Ru(n,t[r]);return u;
	}function pt(n,t,r){return n===n&&(r!==T&&(n=n<=r?n:r),t!==T&&(n=n>=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!du(n))return n;if(u=ff(n)){if(f=me(n),!c)return Ur(n,f)}else{var s=vo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(af(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Ln[s])return i?n:{};f=Ee(n,s,c)}}if(o||(o=new Zn),
	i=o.get(n))return i;o.set(n,f),pf(n)?n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}):sf(n)&&n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))});var a=l?a?ve:_e:a?Bu:Wu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=Wu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Qu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ti("Expected a function");
	return bo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,k(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++u<l;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(a&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function bt(n,t){var r=true;return uo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function xt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===T?o===o&&!wu(o):r(o,f)))var f=o,c=i;
	}return c}function jt(n,t){var r=[];return uo(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function wt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=ke),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?wt(f,t-1,r,e,u):a(u,f):e||(u[u.length]=f)}return u}function mt(n,t){return n&&oo(n,t,Wu)}function At(n,t){return n&&fo(n,t,Wu)}function Et(n,t){return i(t,function(t){return _u(n[t])})}function kt(n,t){t=Sr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[Me(t[r++])];return r&&r==e?n:T}function St(n,t,r){return t=t(n),
	ff(n)?t:a(t,r(n))}function Ot(n){if(null==n)n=n===T?"[object Undefined]":"[object Null]";else if(mi&&mi in Qu(n)){var t=oi.call(n,mi),r=n[mi];try{n[mi]=T;var e=true}catch(n){}var u=ai.call(n);e&&(t?n[mi]=r:delete n[mi]),n=u}else n=ai.call(n);return n}function It(n,t){return n>t}function Rt(n,t){return null!=n&&oi.call(n,t)}function zt(n,t){return null!=n&&t in Qu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Ku(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,k(t))),s=Ci(p.length,s),
	l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;if(v?!O(v,d):!e(h,d,r)){for(a=i;--a;){var y=l[a];if(y?!O(y,d):!e(n[a],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Bt(n,t,r){var e={};return mt(n,function(n,u,i){t(e,r(n),u,i)}),e}function Lt(t,r,e){return r=Sr(r,t),t=2>r.length?t:kt(t,hr(r,0,-1)),r=null==t?t:t[Me(Ve(r))],null==r?T:n(r,t,e)}function Ut(n){return yu(n)&&"[object Arguments]"==Ot(n)}function Ct(n){
	return yu(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return yu(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!yu(n)&&!yu(t))t=n!==n&&t!==t;else n:{var i=ff(n),o=ff(t),f=i?"[object Array]":vo(n),c=o?"[object Array]":vo(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&af(n)){if(!af(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||_f(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{
	if(!(1&r)&&(i=a&&oi.call(n,"__wrapped__"),f=o&&oi.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Zn),t=Mt(n,t,r,e,u);break n}if(c)t:if(u||(u=new Zn),i=1&r,f=_e(n),o=f.length,c=_e(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:oi.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++a<o;){var l=f[a],h=n[l],p=t[l];if(e)var _=i?e(p,h,l,t,n,u):e(h,p,l,n,t,u);if(_===T?h!==p&&!Mt(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l);
	}c&&!s&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)),u.delete(n),u.delete(t),t=c}}else t=false;else t=false}}return t}function Tt(n){return yu(n)&&"[object Map]"==vo(n)}function $t(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;for(n=Qu(n);u--;){var f=r[u];if(o&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return false}for(;++u<i;){var f=r[u],c=f[0],a=n[c],l=f[1];if(o&&f[2]){if(a===T&&!(c in n))return false;
	}else{if(f=new Zn,e)var s=e(a,l,c,n,t,f);if(s===T?!Mt(l,a,3,e,f):!s)return false}}return true}function Ft(n){return!(!du(n)||ci&&ci in n)&&(_u(n)?hi:dn).test(Te(n))}function Nt(n){return yu(n)&&"[object RegExp]"==Ot(n)}function Pt(n){return yu(n)&&"[object Set]"==vo(n)}function Zt(n){return yu(n)&&gu(n.length)&&!!Bn[Ot(n)]}function qt(n){return typeof n=="function"?n:null==n?$u:typeof n=="object"?ff(n)?Jt(n[0],n[1]):Ht(n):Zu(n)}function Vt(n){if(!ze(n))return Li(n);var t,r=[];for(t in Qu(n))oi.call(n,t)&&"constructor"!=t&&r.push(t);
	return r}function Kt(n,t){return n<t}function Gt(n,t){var r=-1,e=su(n)?Ku(n.length):[];return uo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Ht(n){var t=xe(n);return 1==t.length&&t[0][2]?We(t[0][0],t[0][1]):function(r){return r===n||$t(r,n,t)}}function Jt(n,t){return Ie(n)&&t===t&&!du(t)?We(Me(n),t):function(r){var e=Ru(r,n);return e===T&&e===t?zu(r,n):Mt(t,e,3)}}function Yt(n,t,r,e,u){n!==t&&oo(t,function(i,o){if(u||(u=new Zn),du(i)){var f=u,c=Le(n,o),a=Le(t,o),l=f.get(a);if(l)it(n,o,l);else{
	var l=e?e(c,a,o+"",n,t,f):T,s=l===T;if(s){var h=ff(a),p=!h&&af(a),_=!h&&!p&&_f(a),l=a;h||p||_?ff(c)?l=c:hu(c)?l=Ur(c):p?(s=false,l=Ir(a,true)):_?(s=false,l=zr(a,true)):l=[]:xu(a)||of(a)?(l=c,of(c)?l=Ou(c):du(c)&&!_u(c)||(l=Ae(a))):s=false}s&&(f.set(a,l),Yt(l,a,r,e,f),f.delete(a)),it(n,o,l)}}else f=e?e(Le(n,o),i,o+"",n,t,u):T,f===T&&(f=i),it(n,o,f)},Bu)}function Qt(n,t){var r=n.length;if(r)return t+=0>t?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[$u],k(ye())),n=Gt(n,function(n){return{
	a:c(t,function(t){return t(n)}),b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Wr(u[e],i[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return zu(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=kt(n,o);r(f,o)&&lr(i,Sr(o,n),f)}return i}function rr(n){return function(t){return kt(t,n)}}function er(n,t,r,e){var u=e?g:v,i=-1,o=t.length,f=n;for(n===t&&(t=Ur(t)),
	r&&(f=c(n,k(r)));++i<o;)for(var a=0,l=t[i],l=r?r(l):l;-1<(a=u(f,l,a,e));)f!==n&&xi.call(f,a,1),xi.call(n,a,1);return n}function ur(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Se(u)?xi.call(n,u,1):xr(n,u)}}}function ir(n,t){return n+Ii(Ti()*(t-n+1))}function or(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=Ii(t/2))&&(n+=n);while(t);return r}function fr(n,t){return xo(Be(n,t,$u),n+"")}function cr(n){return Qn(Uu(n))}function ar(n,t){var r=Uu(n);
	return De(r,pt(t,0,r.length))}function lr(n,t,r,e){if(!du(n))return n;t=Sr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=Me(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):T;a===T&&(a=du(l)?l:Se(t[u+1])?[]:{})}ot(f,c,a),f=f[c]}return n}function sr(n){return De(Uu(n))}function hr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Ku(u);++e<u;)r[e]=n[e+t];return r}function pr(n,t){var r;return uo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}
	function _r(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!wu(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return vr(n,t,$u,r)}function vr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=wu(t),a=t===T;u<i;){var l=Ii((u+i)/2),s=r(n[l]),h=s!==T,p=null===s,_=s===s,v=wu(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Ci(i,4294967294)}function gr(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){
	var o=n[r],f=t?t(o):o;if(!r||!lu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function dr(n){return typeof n=="number"?n:wu(n)?F:+n}function yr(n){if(typeof n=="string")return n;if(ff(n))return c(n,yr)+"";if(wu(n))return ro?ro.call(n):"";var t=n+"";return"0"==t&&1/n==-$?"-0":t}function br(n,t,r){var e=-1,u=o,i=n.length,c=true,a=[],l=a;if(r)c=false,u=f;else if(200<=i){if(u=t?null:so(n))return U(u);c=false,u=O,l=new Nn}else l=t?[]:a;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(c&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;
	t&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function xr(n,t){return t=Sr(t,n),n=2>t.length?n:kt(n,hr(t,0,-1)),null==n||delete n[Me(Ve(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?hr(n,e?0:i,e?i+1:u):hr(n,e?i+1:0,e?u:i)}function wr(n,t){var r=n;return r instanceof Un&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mr(n,t,r){var e=n.length;if(2>e)return e?br(n[0]):[];for(var u=-1,i=Ku(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=yt(i[u]||o,n[f],t,r));
	return br(wt(i,1),t,r)}function Ar(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:T);return o}function Er(n){return hu(n)?n:[]}function kr(n){return typeof n=="function"?n:$u}function Sr(n,t){return ff(n)?n:Ie(n,t)?[n]:jo(Iu(n))}function Or(n,t,r){var e=n.length;return r=r===T?e:r,!t&&r>=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=gi?gi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new vi(t).set(new vi(n)),
	t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length)}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=wu(n),o=t!==T,f=null===t,c=t===t,a=wu(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Br(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Ui(i-o,0),l=Ku(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];
	return l}function Lr(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Ui(i-f,0),s=Ku(l+a);for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Ur(n,t){var r=-1,e=n.length;for(t||(t=Ku(e));++r<e;)t[r]=n[r];return t}function Cr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):T;c===T&&(c=n[f]),u?st(r,f,c):ot(r,f,c)}return r}function Dr(n,t){return Cr(n,po(n),t)}function Mr(n,t){return Cr(n,_o(n),t);
	}function Tr(n,r){return function(e,u){var i=ff(e)?t:ct,o=r?r():{};return i(e,n,ye(u,2),o)}}function $r(n){return fr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:T,o=2<u?r[2]:T,i=3<n.length&&typeof i=="function"?(u--,i):T;for(o&&Oe(r[0],r[1],o)&&(i=3>u?T:i,u=1),t=Qu(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Fr(n,t){return function(r,e){if(null==r)return r;if(!su(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=Qu(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function Nr(n){return function(t,r,e){
	var u=-1,i=Qu(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break}return t}}function Pr(n,t,r){function e(){return(this&&this!==$n&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Vr(n);return e}function Zr(n){return function(t){t=Iu(t);var r=Rn.test(t)?M(t):T,e=r?r[0]:t.charAt(0);return t=r?Or(r,1).join(""):t.slice(1),e[n]()+t}}function qr(n){return function(t){return l(Mu(Du(t).replace(kn,"")),n,"")}}function Vr(n){return function(){var t=arguments;switch(t.length){
	case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=eo(n.prototype),t=n.apply(r,t);return du(t)?t:r}}function Kr(t,r,e){function u(){for(var o=arguments.length,f=Ku(o),c=o,a=de(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:L(f,a),
	o-=c.length,o<e?ue(t,r,Jr,u.placeholder,T,f,c,T,T,e-o):n(this&&this!==$n&&this instanceof u?i:t,this,f)}var i=Vr(t);return u}function Gr(n){return function(t,r,e){var u=Qu(t);if(!su(t)){var i=ye(r,3);t=Wu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:T}}function Hr(n){return pe(function(t){var r=t.length,e=r,u=On.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ti("Expected a function");if(u&&!o&&"wrapper"==ge(i))var o=new On([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=ge(i),f="wrapper"==u?ho(i):T,o=f&&Re(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[ge(f[0])].apply(o,f[3]):1==i.length&&Re(i)?o[u]():o.thru(i);
	return function(){var n=arguments,e=n[0];if(o&&1==n.length&&ff(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Jr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Ku(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=de(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Br(y,e,u,_)),i&&(y=Lr(y,i,o,_)),d-=x,_&&d<a)return j=L(y,j),ue(n,t,Jr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Ci(f.length,x),m=Ur(y);w--;){
	var A=f[w];y[w]=Se(A,x)?m[A]:T}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==$n&&this instanceof l&&(b=g||Vr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?T:Vr(n);return l}function Yr(n,t){return function(r,e){return Bt(r,n,t(e))}}function Qr(n,t){return function(r,e){var u;if(r===T&&e===T)return t;if(r!==T&&(u=r),e!==T){if(u===T)return e;typeof r=="string"||typeof e=="string"?(r=yr(r),e=yr(e)):(r=dr(r),e=dr(e)),u=n(r,e)}return u}}function Xr(t){return pe(function(r){
	return r=c(r,k(ye())),fr(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ne(n,t){t=t===T?" ":yr(t);var r=t.length;return 2>r?r?or(t,n):t:(r=or(t,Oi(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Ku(l+c),h=this&&this!==$n&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=1&r,f=Vr(t);return i}function re(n){return function(t,r,e){
	e&&typeof e!="number"&&Oe(t,r,e)&&(r=e=T),t=Au(t),r===T?(r=t,t=0):r=Au(r),e=e===T?t<r?1:-1:Au(e);var u=-1;r=Ui(Oi((r-t)/(e||1)),0);for(var i=Ku(r);r--;)i[n?r:++u]=t,t+=e;return i}}function ee(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Su(t),r=Su(r)),n(t,r)}}function ue(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:T;o=l?T:o;var h=l?i:T;return i=l?T:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(T,u),Re(n)&&yo(r,u),r.placeholder=e,Ue(r,n,t)}function ie(n){
	var t=Yu[n];return function(n,r){if(n=Su(n),(r=null==r?0:Ci(Eu(r),292))&&Wi(n)){var e=(Iu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Iu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function oe(n){return function(t){var r=vo(t);return"[object Map]"==r?W(t):"[object Set]"==r?C(t):E(t,n(t))}}function fe(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ti("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=T),o=o===T?o:Ui(Eu(o),0),f=f===T?f:Eu(f),a-=u?u.length:0,
	64&t){var l=e,s=u;e=u=T}var h=c?T:ho(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Br(e,r,h[4]):r,i[4]=e?L(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Lr(e,r,h[6]):r,i[6]=e?L(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ci(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],
	t=i[1],r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Ui(i[9]-a,0),!f&&24&t&&(t&=-25),Ue((h?co:yo)(t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),i),n,t)}function ce(n,t,r,e){return n===T||lu(n,ei[r])&&!oi.call(e,r)?t:n}function ae(n,t,r,e,u,i){return du(n)&&du(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return xu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;
	var c=-1,a=true,l=2&r?new Nn:T;for(i.set(n,t),i.set(t,n);++c<f;){var s=n[c],p=t[c];if(e)var _=o?e(p,s,c,t,n,i):e(s,p,c,n,t,i);if(_!==T){if(_)continue;a=false;break}if(l){if(!h(t,function(n,t){if(!O(l,t)&&(s===n||u(s,n,r,e,i)))return l.push(t)})){a=false;break}}else if(s!==p&&!u(s,p,r,e,i)){a=false;break}}return i.delete(n),i.delete(t),a}function he(n,t,r,e,u,i,o){switch(r){case"[object DataView]":if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)break;n=n.buffer,t=t.buffer;case"[object ArrayBuffer]":
	if(n.byteLength!=t.byteLength||!i(new vi(n),new vi(t)))break;return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return lu(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=W;case"[object Set]":if(f||(f=U),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=se(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(to)return to.call(n)==to.call(t)}
	return false}function pe(n){return xo(Be(n,T,Ze),n+"")}function _e(n){return St(n,Wu,po)}function ve(n){return St(n,Bu,_o)}function ge(n){for(var t=n.name+"",r=Gi[t],e=oi.call(Gi,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function de(n){return(oi.call(An,"placeholder")?An:n).placeholder}function ye(){var n=An.iteratee||Fu,n=n===Fu?qt:n;return arguments.length?n(arguments[0],arguments[1]):n}function be(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map;
	}function xe(n){for(var t=Wu(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,u===u&&!du(u)]}return t}function je(n,t){var r=null==n?T:n[t];return Ft(r)?r:T}function we(n,t,r){t=Sr(t,n);for(var e=-1,u=t.length,i=false;++e<u;){var o=Me(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&gu(u)&&Se(o,u)&&(ff(n)||of(n)))}function me(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&oi.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Ae(n){
	return typeof n.constructor!="function"||ze(n)?{}:eo(di(n))}function Ee(n,t,r){var e=n.constructor;switch(t){case"[object ArrayBuffer]":return Rr(n);case"[object Boolean]":case"[object Date]":return new e(+n);case"[object DataView]":return t=r?Rr(n.buffer):n.buffer,new n.constructor(t,n.byteOffset,n.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":
	case"[object Uint16Array]":case"[object Uint32Array]":return zr(n,r);case"[object Map]":return new e;case"[object Number]":case"[object String]":return new e(n);case"[object RegExp]":return t=new n.constructor(n.source,_n.exec(n)),t.lastIndex=n.lastIndex,t;case"[object Set]":return new e;case"[object Symbol]":return to?Qu(to.call(n)):{}}}function ke(n){return ff(n)||of(n)||!!(ji&&n&&n[ji])}function Se(n,t){var r=typeof n;return t=null==t?9007199254740991:t,!!t&&("number"==r||"symbol"!=r&&bn.test(n))&&-1<n&&0==n%1&&n<t;
	}function Oe(n,t,r){if(!du(r))return false;var e=typeof t;return!!("number"==e?su(r)&&Se(t,r.length):"string"==e&&t in r)&&lu(r[t],n)}function Ie(n,t){if(ff(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!wu(n))||(nn.test(n)||!X.test(n)||null!=t&&n in Qu(t))}function Re(n){var t=ge(n),r=An[t];return typeof r=="function"&&t in Un.prototype&&(n===r||(t=ho(r),!!t&&n===t[0]))}function ze(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||ei)}function We(n,t){
	return function(r){return null!=r&&(r[n]===t&&(t!==T||n in Qu(r)))}}function Be(t,r,e){return r=Ui(r===T?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Ui(u.length-r,0),f=Ku(o);++i<o;)f[i]=u[r+i];for(i=-1,o=Ku(r+1);++i<r;)o[i]=u[i];return o[r]=e(f),n(t,this,o)}}function Le(n,t){if(("constructor"!==t||"function"!=typeof n[t])&&"__proto__"!=t)return n[t]}function Ue(n,t,r){var e=t+"";t=xo;var u,i=$e;return u=(u=e.match(an))?u[1].split(ln):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],
	r=r.join(2<i?", ":" "),e=e.replace(cn,"{\n/* [wrapped with "+r+"] */\n")),t(n,e)}function Ce(n){var t=0,r=0;return function(){var e=Di(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(T,arguments)}}function De(n,t){var r=-1,e=n.length,u=e-1;for(t=t===T?e:t;++r<t;){var e=ir(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function Me(n){if(typeof n=="string"||wu(n))return n;var t=n+"";return"0"==t&&1/n==-$?"-0":t}function Te(n){if(null!=n){try{return ii.call(n)}catch(n){}
	return n+""}return""}function $e(n,t){return r(N,function(r){var e="_."+r[0];t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function Fe(n){if(n instanceof Un)return n.clone();var t=new On(n.__wrapped__,n.__chain__);return t.__actions__=Ur(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ne(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Eu(r),0>r&&(r=Ui(e+r,0)),_(n,ye(t,3),r)):-1}function Pe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=Eu(r),u=0>r?Ui(e+u,0):Ci(u,e-1)),
	_(n,ye(t,3),u,true)}function Ze(n){return(null==n?0:n.length)?wt(n,1):[]}function qe(n){return n&&n.length?n[0]:T}function Ve(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ke(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ge(n){return null==n?n:$i.call(n)}function He(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(hu(n))return t=Ui(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function Je(t,r){if(!t||!t.length)return[];var e=He(t);return null==r?e:c(e,function(t){
	return n(r,T,t)})}function Ye(n){return n=An(n),n.__chain__=true,n}function Qe(n,t){return t(n)}function Xe(){return this}function nu(n,t){return(ff(n)?r:uo)(n,ye(t,3))}function tu(n,t){return(ff(n)?e:io)(n,ye(t,3))}function ru(n,t){return(ff(n)?c:Gt)(n,ye(t,3))}function eu(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function uu(n,t){var r;if(typeof t!="function")throw new ti("Expected a function");return n=Eu(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),
	r}}function iu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=iu.placeholder,n}function ou(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=ou.placeholder,n}function fu(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Go();if(u(n))return o(n);var r,e=bo;r=n-_,n=t-(n-p),r=g?Ci(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Go(),r=u(n);if(c=arguments,
	a=this,p=n,r){if(h===T)return _=n=p,h=bo(i,t),v?e(n):s;if(g)return lo(h),h=bo(i,t),e(p)}return h===T&&(h=bo(i,t)),s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ti("Expected a function");return t=Su(t)||0,du(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Ui(Su(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&lo(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Go())},f}function cu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;
	return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ti("Expected a function");return r.cache=new(cu.Cache||Fn),r}function au(n){if(typeof n!="function")throw new ti("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function lu(n,t){return n===t||n!==n&&t!==t;
	}function su(n){return null!=n&&gu(n.length)&&!_u(n)}function hu(n){return yu(n)&&su(n)}function pu(n){if(!yu(n))return false;var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!xu(n)}function _u(n){return!!du(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function vu(n){return typeof n=="number"&&n==Eu(n)}function gu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n;
	}function du(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function yu(n){return null!=n&&typeof n=="object"}function bu(n){return typeof n=="number"||yu(n)&&"[object Number]"==Ot(n)}function xu(n){return!(!yu(n)||"[object Object]"!=Ot(n))&&(n=di(n),null===n||(n=oi.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ii.call(n)==li))}function ju(n){return typeof n=="string"||!ff(n)&&yu(n)&&"[object String]"==Ot(n)}function wu(n){return typeof n=="symbol"||yu(n)&&"[object Symbol]"==Ot(n);
	}function mu(n){if(!n)return[];if(su(n))return ju(n)?M(n):Ur(n);if(wi&&n[wi]){n=n[wi]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=vo(n),("[object Map]"==t?W:"[object Set]"==t?U:Uu)(n)}function Au(n){return n?(n=Su(n),n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Eu(n){n=Au(n);var t=n%1;return n===n?t?n-t:n:0}function ku(n){return n?pt(Eu(n),0,4294967295):0}function Su(n){if(typeof n=="number")return n;if(wu(n))return F;if(du(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,
	n=du(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n}function Ou(n){return Cr(n,Bu(n))}function Iu(n){return null==n?"":yr(n)}function Ru(n,t,r){return n=null==n?T:kt(n,t),n===T?r:n}function zu(n,t){return null!=n&&we(n,t,zt)}function Wu(n){return su(n)?qn(n):Vt(n)}function Bu(n){if(su(n))n=qn(n,true);else if(du(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&oi.call(n,t))&&e.push(t);n=e}else{if(t=[],
	null!=n)for(r in Qu(n))t.push(r);n=t}return n}function Lu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){return t(n,r[0])})}function Uu(n){return null==n?[]:S(n,Wu(n))}function Cu(n){return $f(Iu(n).toLowerCase())}function Du(n){return(n=Iu(n))&&n.replace(xn,Xn).replace(Sn,"")}function Mu(n,t,r){return n=Iu(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Tu(n){return function(){return n}}function $u(n){return n;
	}function Fu(n){return qt(typeof n=="function"?n:_t(n,1))}function Nu(n,t,e){var u=Wu(t),i=Et(t,u);null!=e||du(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=Et(t,Wu(t)));var o=!(du(e)&&"chain"in e&&!e.chain),f=_u(n);return r(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Ur(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Pu(){}
	function Zu(n){return Ie(n)?b(Me(n)):rr(n)}function qu(){return[]}function Vu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Ku=mn.Array,Gu=mn.Date,Hu=mn.Error,Ju=mn.Function,Yu=mn.Math,Qu=mn.Object,Xu=mn.RegExp,ni=mn.String,ti=mn.TypeError,ri=Ku.prototype,ei=Qu.prototype,ui=mn["__core-js_shared__"],ii=Ju.prototype.toString,oi=ei.hasOwnProperty,fi=0,ci=function(){var n=/[^.]+$/.exec(ui&&ui.keys&&ui.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ai=ei.toString,li=ii.call(Qu),si=$n._,hi=Xu("^"+ii.call(oi).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),pi=Pn?mn.Buffer:T,_i=mn.Symbol,vi=mn.Uint8Array,gi=pi?pi.g:T,di=B(Qu.getPrototypeOf,Qu),yi=Qu.create,bi=ei.propertyIsEnumerable,xi=ri.splice,ji=_i?_i.isConcatSpreadable:T,wi=_i?_i.iterator:T,mi=_i?_i.toStringTag:T,Ai=function(){
	try{var n=je(Qu,"defineProperty");return n({},"",{}),n}catch(n){}}(),Ei=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,ki=Gu&&Gu.now!==$n.Date.now&&Gu.now,Si=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Oi=Yu.ceil,Ii=Yu.floor,Ri=Qu.getOwnPropertySymbols,zi=pi?pi.isBuffer:T,Wi=mn.isFinite,Bi=ri.join,Li=B(Qu.keys,Qu),Ui=Yu.max,Ci=Yu.min,Di=Gu.now,Mi=mn.parseInt,Ti=Yu.random,$i=ri.reverse,Fi=je(mn,"DataView"),Ni=je(mn,"Map"),Pi=je(mn,"Promise"),Zi=je(mn,"Set"),qi=je(mn,"WeakMap"),Vi=je(Qu,"create"),Ki=qi&&new qi,Gi={},Hi=Te(Fi),Ji=Te(Ni),Yi=Te(Pi),Qi=Te(Zi),Xi=Te(qi),no=_i?_i.prototype:T,to=no?no.valueOf:T,ro=no?no.toString:T,eo=function(){
	function n(){}return function(t){return du(t)?yi?yi(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=En.prototype,An.prototype.constructor=An,On.prototype=eo(En.prototype),On.prototype.constructor=On,Un.prototype=eo(En.prototype),Un.prototype.constructor=Un,Mn.prototype.clear=function(){this.__data__=Vi?Vi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
	this.size-=n?1:0,n},Mn.prototype.get=function(n){var t=this.__data__;return Vi?(n=t[n],"__lodash_hash_undefined__"===n?T:n):oi.call(t,n)?t[n]:T},Mn.prototype.has=function(n){var t=this.__data__;return Vi?t[n]!==T:oi.call(t,n)},Mn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=Vi&&t===T?"__lodash_hash_undefined__":t,this},Tn.prototype.clear=function(){this.__data__=[],this.size=0},Tn.prototype.delete=function(n){var t=this.__data__;return n=ft(t,n),!(0>n)&&(n==t.length-1?t.pop():xi.call(t,n,1),
	--this.size,true)},Tn.prototype.get=function(n){var t=this.__data__;return n=ft(t,n),0>n?T:t[n][1]},Tn.prototype.has=function(n){return-1<ft(this.__data__,n)},Tn.prototype.set=function(n,t){var r=this.__data__,e=ft(r,n);return 0>e?(++this.size,r.push([n,t])):r[e][1]=t,this},Fn.prototype.clear=function(){this.size=0,this.__data__={hash:new Mn,map:new(Ni||Tn),string:new Mn}},Fn.prototype.delete=function(n){return n=be(this,n).delete(n),this.size-=n?1:0,n},Fn.prototype.get=function(n){return be(this,n).get(n);
	},Fn.prototype.has=function(n){return be(this,n).has(n)},Fn.prototype.set=function(n,t){var r=be(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Nn.prototype.add=Nn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Nn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.clear=function(){this.__data__=new Tn,this.size=0},Zn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Zn.prototype.get=function(n){
	return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Ni||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var uo=Fr(mt),io=Fr(At,true),oo=Nr(),fo=Nr(true),co=Ki?function(n,t){return Ki.set(n,t),n}:$u,ao=Ai?function(n,t){return Ai(n,"toString",{configurable:true,enumerable:false,value:Tu(t),writable:true})}:$u,lo=Ei||function(n){
	return $n.clearTimeout(n)},so=Zi&&1/U(new Zi([,-0]))[1]==$?function(n){return new Zi(n)}:Pu,ho=Ki?function(n){return Ki.get(n)}:Pu,po=Ri?function(n){return null==n?[]:(n=Qu(n),i(Ri(n),function(t){return bi.call(n,t)}))}:qu,_o=Ri?function(n){for(var t=[];n;)a(t,po(n)),n=di(n);return t}:qu,vo=Ot;(Fi&&"[object DataView]"!=vo(new Fi(new ArrayBuffer(1)))||Ni&&"[object Map]"!=vo(new Ni)||Pi&&"[object Promise]"!=vo(Pi.resolve())||Zi&&"[object Set]"!=vo(new Zi)||qi&&"[object WeakMap]"!=vo(new qi))&&(vo=function(n){
	var t=Ot(n);if(n=(n="[object Object]"==t?n.constructor:T)?Te(n):"")switch(n){case Hi:return"[object DataView]";case Ji:return"[object Map]";case Yi:return"[object Promise]";case Qi:return"[object Set]";case Xi:return"[object WeakMap]"}return t});var go=ui?_u:Vu,yo=Ce(co),bo=Si||function(n,t){return $n.setTimeout(n,t)},xo=Ce(ao),jo=function(n){n=cu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(tn,function(n,r,e,u){
	t.push(e?u.replace(hn,"$1"):r||n)}),t}),wo=fr(function(n,t){return hu(n)?yt(n,wt(t,1,hu,true)):[]}),mo=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),ye(r,2)):[]}),Ao=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),T,r):[]}),Eo=fr(function(n){var t=c(n,Er);return t.length&&t[0]===n[0]?Wt(t):[]}),ko=fr(function(n){var t=Ve(n),r=c(n,Er);return t===Ve(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),So=fr(function(n){var t=Ve(n),r=c(n,Er);return(t=typeof t=="function"?t:T)&&r.pop(),
	r.length&&r[0]===n[0]?Wt(r,T,t):[]}),Oo=fr(Ke),Io=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Ro=fr(function(n){return br(wt(n,1,hu,true))}),zo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),br(wt(n,1,hu,true),ye(t,2))}),Wo=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return br(wt(n,1,hu,true),T,t)}),Bo=fr(function(n,t){return hu(n)?yt(n,t):[]}),Lo=fr(function(n){return mr(i(n,hu))}),Uo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),
	mr(i(n,hu),ye(t,2))}),Co=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return mr(i(n,hu),T,t)}),Do=fr(He),Mo=fr(function(n){var t=n.length,t=1<t?n[t-1]:T,t=typeof t=="function"?(n.pop(),t):T;return Je(n,t)}),To=pe(function(n){function t(t){return ht(t,n)}var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return!(1<r||this.__actions__.length)&&u instanceof Un&&Se(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:Qe,args:[t],thisArg:T}),new On(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(T),
	n})):this.thru(t)}),$o=Tr(function(n,t,r){oi.call(n,r)?++n[r]:st(n,r,1)}),Fo=Gr(Ne),No=Gr(Pe),Po=Tr(function(n,t,r){oi.call(n,r)?n[r].push(t):st(n,r,[t])}),Zo=fr(function(t,r,e){var u=-1,i=typeof r=="function",o=su(t)?Ku(t.length):[];return uo(t,function(t){o[++u]=i?n(r,t,e):Lt(t,r,e)}),o}),qo=Tr(function(n,t,r){st(n,r,t)}),Vo=Tr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ko=fr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&Oe(n,t[0],t[1])?t=[]:2<r&&Oe(t[0],t[1],t[2])&&(t=[t[0]]),
	Xt(n,wt(t,1),[])}),Go=ki||function(){return $n.Date.now()},Ho=fr(function(n,t,r){var e=1;if(r.length)var u=L(r,de(Ho)),e=32|e;return fe(n,e,t,r,u)}),Jo=fr(function(n,t,r){var e=3;if(r.length)var u=L(r,de(Jo)),e=32|e;return fe(t,e,n,r,u)}),Yo=fr(function(n,t){return dt(n,1,t)}),Qo=fr(function(n,t,r){return dt(n,Su(t)||0,r)});cu.Cache=Fn;var Xo=fr(function(t,r){r=1==r.length&&ff(r[0])?c(r[0],k(ye())):c(wt(r,1),k(ye()));var e=r.length;return fr(function(u){for(var i=-1,o=Ci(u.length,e);++i<o;)u[i]=r[i].call(this,u[i]);
	return n(t,this,u)})}),nf=fr(function(n,t){return fe(n,32,T,t,L(t,de(nf)))}),tf=fr(function(n,t){return fe(n,64,T,t,L(t,de(tf)))}),rf=pe(function(n,t){return fe(n,256,T,T,T,t)}),ef=ee(It),uf=ee(function(n,t){return n>=t}),of=Ut(function(){return arguments}())?Ut:function(n){return yu(n)&&oi.call(n,"callee")&&!bi.call(n,"callee")},ff=Ku.isArray,cf=Vn?k(Vn):Ct,af=zi||Vu,lf=Kn?k(Kn):Dt,sf=Gn?k(Gn):Tt,hf=Hn?k(Hn):Nt,pf=Jn?k(Jn):Pt,_f=Yn?k(Yn):Zt,vf=ee(Kt),gf=ee(function(n,t){return n<=t}),df=$r(function(n,t){
	if(ze(t)||su(t))Cr(t,Wu(t),n);else for(var r in t)oi.call(t,r)&&ot(n,r,t[r])}),yf=$r(function(n,t){Cr(t,Bu(t),n)}),bf=$r(function(n,t,r,e){Cr(t,Bu(t),n,e)}),xf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),jf=pe(ht),wf=fr(function(n,t){n=Qu(n);var r=-1,e=t.length,u=2<e?t[2]:T;for(u&&Oe(t[0],t[1],u)&&(e=1);++r<e;)for(var u=t[r],i=Bu(u),o=-1,f=i.length;++o<f;){var c=i[o],a=n[c];(a===T||lu(a,ei[c])&&!oi.call(n,c))&&(n[c]=u[c])}return n}),mf=fr(function(t){return t.push(T,ae),n(Of,T,t)}),Af=Yr(function(n,t,r){
	null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),n[t]=r},Tu($u)),Ef=Yr(function(n,t,r){null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),oi.call(n,t)?n[t].push(r):n[t]=[r]},ye),kf=fr(Lt),Sf=$r(function(n,t,r){Yt(n,t,r)}),Of=$r(function(n,t,r,e){Yt(n,t,r,e)}),If=pe(function(n,t){var r={};if(null==n)return r;var e=false;t=c(t,function(t){return t=Sr(t,n),e||(e=1<t.length),t}),Cr(n,ve(n),r),e&&(r=_t(r,7,le));for(var u=t.length;u--;)xr(r,t[u]);return r}),Rf=pe(function(n,t){return null==n?{}:nr(n,t);
	}),zf=oe(Wu),Wf=oe(Bu),Bf=qr(function(n,t,r){return t=t.toLowerCase(),n+(r?Cu(t):t)}),Lf=qr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Uf=qr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Cf=Zr("toLowerCase"),Df=qr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),Mf=qr(function(n,t,r){return n+(r?" ":"")+$f(t)}),Tf=qr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),$f=Zr("toUpperCase"),Ff=fr(function(t,r){try{return n(t,T,r)}catch(n){return pu(n)?n:new Hu(n)}}),Nf=pe(function(n,t){
	return r(t,function(t){t=Me(t),st(n,t,Ho(n[t],n))}),n}),Pf=Hr(),Zf=Hr(true),qf=fr(function(n,t){return function(r){return Lt(r,n,t)}}),Vf=fr(function(n,t){return function(r){return Lt(n,r,t)}}),Kf=Xr(c),Gf=Xr(u),Hf=Xr(h),Jf=re(),Yf=re(true),Qf=Qr(function(n,t){return n+t},0),Xf=ie("ceil"),nc=Qr(function(n,t){return n/t},1),tc=ie("floor"),rc=Qr(function(n,t){return n*t},1),ec=ie("round"),uc=Qr(function(n,t){return n-t},0);return An.after=function(n,t){if(typeof t!="function")throw new ti("Expected a function");
	return n=Eu(n),function(){if(1>--n)return t.apply(this,arguments)}},An.ary=eu,An.assign=df,An.assignIn=yf,An.assignInWith=bf,An.assignWith=xf,An.at=jf,An.before=uu,An.bind=Ho,An.bindAll=Nf,An.bindKey=Jo,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return ff(n)?n:[n]},An.chain=Ye,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Ui(Eu(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Ku(Oi(r/t));e<r;)i[u++]=hr(n,e,e+=t);return i},An.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){
	var i=n[t];i&&(u[e++]=i)}return u},An.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Ku(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return a(ff(r)?Ur(r):[r],wt(t,1))},An.cond=function(t){var r=null==t?0:t.length,e=ye();return t=r?c(t,function(n){if("function"!=typeof n[1])throw new ti("Expected a function");return[e(n[0]),n[1]]}):[],fr(function(e){for(var u=-1;++u<r;){var i=t[u];if(n(i[0],this,e))return n(i[1],this,e)}})},An.conforms=function(n){return vt(_t(n,1))},An.constant=Tu,
	An.countBy=$o,An.create=function(n,t){var r=eo(n);return null==t?r:at(r,t)},An.curry=iu,An.curryRight=ou,An.debounce=fu,An.defaults=wf,An.defaultsDeep=mf,An.defer=Yo,An.delay=Qo,An.difference=wo,An.differenceBy=mo,An.differenceWith=Ao,An.drop=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),hr(n,0>t?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[];
	},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=Eu(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Eu(e),0>e&&(e+=u),e=r>e?0:ku(e);r<e;)n[r++]=t;return n},An.filter=function(n,t){return(ff(n)?i:jt)(n,ye(t,3))},An.flatMap=function(n,t){return wt(ru(n,t),1)},An.flatMapDeep=function(n,t){return wt(ru(n,t),$)},An.flatMapDepth=function(n,t,r){return r=r===T?1:Eu(r),
	wt(ru(n,t),r)},An.flatten=Ze,An.flattenDeep=function(n){return(null==n?0:n.length)?wt(n,$):[]},An.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===T?1:Eu(t),wt(n,t)):[]},An.flip=function(n){return fe(n,512)},An.flow=Pf,An.flowRight=Zf,An.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e},An.functions=function(n){return null==n?[]:Et(n,Wu(n))},An.functionsIn=function(n){return null==n?[]:Et(n,Bu(n))},An.groupBy=Po,An.initial=function(n){
	return(null==n?0:n.length)?hr(n,0,-1):[]},An.intersection=Eo,An.intersectionBy=ko,An.intersectionWith=So,An.invert=Af,An.invertBy=Ef,An.invokeMap=Zo,An.iteratee=Fu,An.keyBy=qo,An.keys=Wu,An.keysIn=Bu,An.map=ru,An.mapKeys=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,t(n,e,u),n)}),r},An.mapValues=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,e,t(n,e,u))}),r},An.matches=function(n){return Ht(_t(n,1))},An.matchesProperty=function(n,t){return Jt(n,_t(t,1))},An.memoize=cu,
	An.merge=Sf,An.mergeWith=Of,An.method=qf,An.methodOf=Vf,An.mixin=Nu,An.negate=au,An.nthArg=function(n){return n=Eu(n),fr(function(t){return Qt(t,n)})},An.omit=If,An.omitBy=function(n,t){return Lu(n,au(ye(t)))},An.once=function(n){return uu(2,n)},An.orderBy=function(n,t,r,e){return null==n?[]:(ff(t)||(t=null==t?[]:[t]),r=e?T:r,ff(r)||(r=null==r?[]:[r]),Xt(n,t,r))},An.over=Kf,An.overArgs=Xo,An.overEvery=Gf,An.overSome=Hf,An.partial=nf,An.partialRight=tf,An.partition=Vo,An.pick=Rf,An.pickBy=Lu,An.property=Zu,
	An.propertyOf=function(n){return function(t){return null==n?T:kt(n,t)}},An.pull=Oo,An.pullAll=Ke,An.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,ye(r,2)):n},An.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,T,r):n},An.pullAt=Io,An.range=Jf,An.rangeRight=Yf,An.rearg=rf,An.reject=function(n,t){return(ff(n)?i:jt)(n,au(ye(t,3)))},An.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=ye(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),
	u.push(e))}return ur(n,u),r},An.rest=function(n,t){if(typeof n!="function")throw new ti("Expected a function");return t=t===T?t:Eu(t),fr(n,t)},An.reverse=Ge,An.sampleSize=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Eu(t),(ff(n)?et:ar)(n,t)},An.set=function(n,t,r){return null==n?n:lr(n,t,r)},An.setWith=function(n,t,r,e){return e=typeof e=="function"?e:T,null==n?n:lr(n,t,r,e)},An.shuffle=function(n){return(ff(n)?ut:sr)(n)},An.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&Oe(n,t,r)?(t=0,
	r=e):(t=null==t?0:Eu(t),r=r===T?e:Eu(r)),hr(n,t,r)):[]},An.sortBy=Ko,An.sortedUniq=function(n){return n&&n.length?gr(n):[]},An.sortedUniqBy=function(n,t){return n&&n.length?gr(n,ye(t,2)):[]},An.split=function(n,t,r){return r&&typeof r!="number"&&Oe(n,t,r)&&(t=r=T),r=r===T?4294967295:r>>>0,r?(n=Iu(n))&&(typeof t=="string"||null!=t&&!hf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ti("Expected a function");return r=null==r?0:Ui(Eu(r),0),
	fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:Eu(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n),
	n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ti("Expected a function");return du(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),fu(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Qe,An.toArray=mu,An.toPairs=zf,An.toPairsIn=Wf,An.toPath=function(n){return ff(n)?c(n,Me):wu(n)?[n]:Ur(jo(Iu(n)))},An.toPlainObject=Ou,An.transform=function(n,t,e){var u=ff(n),i=u||af(n)||_f(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:du(n)&&_u(o)?eo(di(n)):{};
	}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return eu(n,1)},An.union=Ro,An.unionBy=zo,An.unionWith=Wo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=He,An.unzipWith=Je,An.update=function(n,t,r){return null==n?n:lr(n,t,kr(r)(kt(n,t)),void 0)},An.updateWith=function(n,t,r,e){
	return e=typeof e=="function"?e:T,null!=n&&(n=lr(n,t,kr(r)(kt(n,t)),e)),n},An.values=Uu,An.valuesIn=function(n){return null==n?[]:S(n,Bu(n))},An.without=Bo,An.words=Mu,An.wrap=function(n,t){return nf(kr(t),n)},An.xor=Lo,An.xorBy=Uo,An.xorWith=Co,An.zip=Do,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Mo,An.entries=zf,An.entriesIn=Wf,An.extend=yf,An.extendWith=bf,Nu(An,An),An.add=Qf,An.attempt=Ff,An.camelCase=Bf,An.capitalize=Cu,
	An.ceil=Xf,An.clamp=function(n,t,r){return r===T&&(r=t,t=T),r!==T&&(r=Su(r),r=r===r?r:0),t!==T&&(t=Su(t),t=t===t?t:0),pt(Su(n),t,r)},An.clone=function(n){return _t(n,4)},An.cloneDeep=function(n){return _t(n,5)},An.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,5,t)},An.cloneWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,4,t)},An.conformsTo=function(n,t){return null==t||gt(n,t,Wu(t))},An.deburr=Du,An.defaultTo=function(n,t){return null==n||n!==n?t:n},An.divide=nc,An.endsWith=function(n,t,r){
	n=Iu(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(Eu(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=lu,An.escape=function(n){return(n=Iu(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Iu(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=ff(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=Fo,An.findIndex=Ne,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=No,An.findLastIndex=Pe,An.findLastKey=function(n,t){return p(n,ye(t,3),At);
	},An.floor=tc,An.forEach=nu,An.forEachRight=tu,An.forIn=function(n,t){return null==n?n:oo(n,ye(t,3),Bu)},An.forInRight=function(n,t){return null==n?n:fo(n,ye(t,3),Bu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Ru,An.gt=ef,An.gte=uf,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=zu,An.head=qe,An.identity=$u,An.includes=function(n,t,r,e){return n=su(n)?n:Uu(n),r=r&&!e?Eu(r):0,e=n.length,0>r&&(r=Ui(e+r,0)),ju(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<v(n,t,r);
	},An.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Eu(r),0>r&&(r=Ui(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=Au(t),r===T?(r=t,t=0):r=Au(r),n=Su(n),n>=Ci(t,r)&&n<Ui(t,r)},An.invoke=kf,An.isArguments=of,An.isArray=ff,An.isArrayBuffer=cf,An.isArrayLike=su,An.isArrayLikeObject=hu,An.isBoolean=function(n){return true===n||false===n||yu(n)&&"[object Boolean]"==Ot(n)},An.isBuffer=af,An.isDate=lf,An.isElement=function(n){return yu(n)&&1===n.nodeType&&!xu(n)},An.isEmpty=function(n){
	if(null==n)return true;if(su(n)&&(ff(n)||typeof n=="string"||typeof n.splice=="function"||af(n)||_f(n)||of(n)))return!n.length;var t=vo(n);if("[object Map]"==t||"[object Set]"==t)return!n.size;if(ze(n))return!Vt(n).length;for(var r in n)if(oi.call(n,r))return false;return true},An.isEqual=function(n,t){return Mt(n,t)},An.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:T)?r(n,t):T;return e===T?Mt(n,t,T,r):!!e},An.isError=pu,An.isFinite=function(n){return typeof n=="number"&&Wi(n)},An.isFunction=_u,
	An.isInteger=vu,An.isLength=gu,An.isMap=sf,An.isMatch=function(n,t){return n===t||$t(n,t,xe(t))},An.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:T,$t(n,t,xe(t),r)},An.isNaN=function(n){return bu(n)&&n!=+n},An.isNative=function(n){if(go(n))throw new Hu("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");return Ft(n)},An.isNil=function(n){return null==n},An.isNull=function(n){return null===n},An.isNumber=bu,An.isObject=du,An.isObjectLike=yu,An.isPlainObject=xu,An.isRegExp=hf,
	An.isSafeInteger=function(n){return vu(n)&&-9007199254740991<=n&&9007199254740991>=n},An.isSet=pf,An.isString=ju,An.isSymbol=wu,An.isTypedArray=_f,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return yu(n)&&"[object WeakMap]"==vo(n)},An.isWeakSet=function(n){return yu(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Bi.call(n,t)},An.kebabCase=Lf,An.last=Ve,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=Eu(r),u=0>u?Ui(e+u,0):Ci(u,e-1)),
	t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=_(n,d,u,true);return n},An.lowerCase=Uf,An.lowerFirst=Cf,An.lt=vf,An.lte=gf,An.max=function(n){return n&&n.length?xt(n,$u,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,$u)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,$u,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=qu,An.stubFalse=Vu,An.stubObject=function(){return{}},An.stubString=function(){
	return""},An.stubTrue=function(){return true},An.multiply=rc,An.nth=function(n,t){return n&&n.length?Qt(n,Eu(t)):T},An.noConflict=function(){return $n._===this&&($n._=si),this},An.noop=Pu,An.now=Go,An.pad=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Ii(t),r)+n+ne(Oi(t),r))},An.padEnd=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return t&&e<t?n+ne(t-e,r):n},An.padStart=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return t&&e<t?ne(t-e,r)+n:n},An.parseInt=function(n,t,r){
	return r||null==t?t=0:t&&(t=+t),Mi(Iu(n).replace(on,""),t||0)},An.random=function(n,t,r){if(r&&typeof r!="boolean"&&Oe(n,t,r)&&(t=r=T),r===T&&(typeof t=="boolean"?(r=t,t=T):typeof n=="boolean"&&(r=n,n=T)),n===T&&t===T?(n=0,t=1):(n=Au(n),t===T?(t=n,n=0):t=Au(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Ti(),Ci(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=ff(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,uo)},An.reduceRight=function(n,t,r){var e=ff(n)?s:j,u=3>arguments.length;
	return e(n,ye(t,4),r,u,io)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Eu(t),or(Iu(n),t)},An.replace=function(){var n=arguments,t=Iu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++e<u;){var i=null==n?T:n[Me(t[e])];i===T&&(e=u,i=r),n=_u(i)?i.call(n):i}return n},An.round=ec,An.runInContext=x,An.sample=function(n){return(ff(n)?Qn:cr)(n)},An.size=function(n){if(null==n)return 0;if(su(n))return ju(n)?D(n):n.length;
	var t=vo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Vt(n).length},An.snakeCase=Df,An.some=function(n,t,r){var e=ff(n)?h:pr;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.sortedIndex=function(n,t){return _r(n,t)},An.sortedIndexBy=function(n,t,r){return vr(n,t,ye(r,2))},An.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){var e=_r(n,t);if(e<r&&lu(n[e],t))return e}return-1},An.sortedLastIndex=function(n,t){return _r(n,t,true)},An.sortedLastIndexBy=function(n,t,r){return vr(n,t,ye(r,2),true);
	},An.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=_r(n,t,true)-1;if(lu(n[r],t))return r}return-1},An.startCase=Mf,An.startsWith=function(n,t,r){return n=Iu(n),r=null==r?0:pt(Eu(r),0,n.length),t=yr(t),n.slice(r,r+t.length)==t},An.subtract=uc,An.sum=function(n){return n&&n.length?m(n,$u):0},An.sumBy=function(n,t){return n&&n.length?m(n,ye(t,2)):0},An.template=function(n,t,r){var e=An.templateSettings;r&&Oe(n,t,r)&&(t=T),n=Iu(n),t=bf({},t,e,ce),r=bf({},t.imports,e.imports,ce);var u,i,o=Wu(r),f=S(r,o),c=0;
	r=t.interpolate||jn;var a="__p+='";r=Xu((t.escape||jn).source+"|"+r.source+"|"+(r===Q?pn:jn).source+"|"+(t.evaluate||jn).source+"|$","g");var l=oi.call(t,"sourceURL")?"//# sourceURL="+(t.sourceURL+"").replace(/[\r\n]/g," ")+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(wn,z),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=oi.call(t,"variable")&&t.variable)||(a="with(obj){"+a+"}"),
	a=(i?a.replace(P,""):a).replace(Z,"$1").replace(q,"$1;"),a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=Ff(function(){return Ju(o,l+"return "+a).apply(T,f)}),t.source=a,pu(t))throw t;return t},An.times=function(n,t){if(n=Eu(n),1>n||9007199254740991<n)return[];var r=4294967295,e=Ci(n,4294967295);for(t=ye(t),n-=4294967295,e=A(e,t);++r<n;)t(r);return e},An.toFinite=Au,
	An.toInteger=Eu,An.toLength=ku,An.toLower=function(n){return Iu(n).toLowerCase()},An.toNumber=Su,An.toSafeInteger=function(n){return n?pt(Eu(n),-9007199254740991,9007199254740991):0===n?n:0},An.toString=Iu,An.toUpper=function(n){return Iu(n).toUpperCase()},An.trim=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(un,""):n&&(t=yr(t))?(n=M(n),r=M(t),t=I(n,r),r=R(n,r)+1,Or(n,t,r).join("")):n},An.trimEnd=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(fn,""):n&&(t=yr(t))?(n=M(n),t=R(n,M(t))+1,
	Or(n,0,t).join("")):n},An.trimStart=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(on,""):n&&(t=yr(t))?(n=M(n),t=I(n,M(t)),Or(n,t).join("")):n},An.truncate=function(n,t){var r=30,e="...";if(du(t))var u="separator"in t?t.separator:u,r="length"in t?Eu(t.length):r,e="omission"in t?yr(t.omission):e;n=Iu(n);var i=n.length;if(Rn.test(n))var o=M(n),i=o.length;if(r>=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),hf(u)){if(n.slice(i).search(u)){
	var f=r;for(u.global||(u=Xu(u.source,Iu(_n.exec(u))+"g")),u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},An.unescape=function(n){return(n=Iu(n))&&G.test(n)?n.replace(V,tt):n},An.uniqueId=function(n){var t=++fi;return Iu(n)+t},An.upperCase=Tf,An.upperFirst=$f,An.each=nu,An.eachRight=tu,An.first=qe,Nu(An,function(){var n={};return mt(An,function(t,r){oi.call(An.prototype,r)||(n[r]=t)}),n}(),{chain:false
	}),An.VERSION="4.17.15",r("bind bindKey curry curryRight partial partialRight".split(" "),function(n){An[n].placeholder=An}),r(["drop","take"],function(n,t){Un.prototype[n]=function(r){r=r===T?1:Ui(Eu(r),0);var e=this.__filtered__&&!t?new Un(this):this.clone();return e.__filtered__?e.__takeCount__=Ci(r,e.__takeCount__):e.__views__.push({size:Ci(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Un.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){
	var r=t+1,e=1==r||3==r;Un.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Un.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Un.prototype[n]=function(){return this.__filtered__?new Un(this):this[r](1)}}),Un.prototype.compact=function(){return this.filter($u)},Un.prototype.find=function(n){
	return this.filter(n).head()},Un.prototype.findLast=function(n){return this.reverse().find(n)},Un.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Un(this):this.map(function(r){return Lt(r,n,t)})}),Un.prototype.reject=function(n){return this.filter(au(ye(n)))},Un.prototype.slice=function(n,t){n=Eu(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Un(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=Eu(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Un.prototype.takeRightWhile=function(n){
	return this.reverse().takeWhile(n).reverse()},Un.prototype.toArray=function(){return this.take(4294967295)},mt(Un.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){function t(n){return n=u.apply(An,a([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Un,l=f[0],s=c||ff(o);s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,l=i&&!h,c=c&&!p;
	return!i&&s?(o=c?o:new Un(this),o=n.apply(o,f),o.__actions__.push({func:Qe,args:[t],thisArg:T}),new On(o,h)):l&&c?n.apply(this,f):(o=this.thru(t),l?e?o.value()[0]:o.value():o)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ri[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(ff(u)?u:[],n)}return this[r](function(r){return t.apply(ff(r)?r:[],n)});
	}}),mt(Un.prototype,function(n,t){var r=An[t];if(r){var e=r.name+"";oi.call(Gi,e)||(Gi[e]=[]),Gi[e].push({name:t,func:r})}}),Gi[Jr(T,2).name]=[{name:"wrapper",func:T}],Un.prototype.clone=function(){var n=new Un(this.__wrapped__);return n.__actions__=Ur(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ur(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ur(this.__views__),n},Un.prototype.reverse=function(){if(this.__filtered__){var n=new Un(this);
	n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Un.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=ff(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c<a;){var l=o[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=Ci(n,f+s);break;case"takeRight":f=Ui(f,n-s)}}if(n={start:f,end:n},o=n.start,f=n.end,n=f-o,o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Ci(n,this.__takeCount__),!e||!u&&i==n&&l==n)return wr(t,this.__actions__);
	e=[];n:for(;n--&&a<l;){for(o+=r,u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},An.prototype.at=To,An.prototype.chain=function(){return Ye(this)},An.prototype.commit=function(){return new On(this.value(),this.__chain__)},An.prototype.next=function(){this.__values__===T&&(this.__values__=mu(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){
	for(var t,r=this;r instanceof En;){var e=Fe(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Un?(this.__actions__.length&&(n=new Un(this)),n=n.reverse(),n.__actions__.push({func:Qe,args:[Ge],thisArg:T}),new On(n,this.__chain__)):this.thru(Ge)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,
	wi&&(An.prototype[wi]=Xe),An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this);
;
/*!
* Parsley.js
* Version 2.9.2 - built Tue, Dec 10th 2019, 6:18 pm
* http://parsleyjs.org
* Guillaume Potier - <guillaume@wisembly.com>
* Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
* MIT Licensed
*/

// The source code below is generated by babel as
// Parsley is written in ECMAScript 6
//

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) :
    typeof define === 'function' && define.amd ? define(['jquery'], factory) :
    (global = global || self, global.parsley = factory(global.jQuery));
  }(this, (function ($) { 'use strict';
  
    function _typeof(obj) {
      if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
        _typeof = function (obj) {
          return typeof obj;
        };
      } else {
        _typeof = function (obj) {
          return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
        };
      }
  
      return _typeof(obj);
    }
  
    function _extends() {
      _extends = Object.assign || function (target) {
        for (var i = 1; i < arguments.length; i++) {
          var source = arguments[i];
  
          for (var key in source) {
            if (Object.prototype.hasOwnProperty.call(source, key)) {
              target[key] = source[key];
            }
          }
        }
  
        return target;
      };
  
      return _extends.apply(this, arguments);
    }
  
    function _slicedToArray(arr, i) {
      return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
    }
  
    function _toConsumableArray(arr) {
      return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
    }
  
    function _arrayWithoutHoles(arr) {
      if (Array.isArray(arr)) {
        for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
  
        return arr2;
      }
    }
  
    function _arrayWithHoles(arr) {
      if (Array.isArray(arr)) return arr;
    }
  
    function _iterableToArray(iter) {
      if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
    }
  
    function _iterableToArrayLimit(arr, i) {
      if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
        return;
      }
  
      var _arr = [];
      var _n = true;
      var _d = false;
      var _e = undefined;
  
      try {
        for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
          _arr.push(_s.value);
  
          if (i && _arr.length === i) break;
        }
      } catch (err) {
        _d = true;
        _e = err;
      } finally {
        try {
          if (!_n && _i["return"] != null) _i["return"]();
        } finally {
          if (_d) throw _e;
        }
      }
  
      return _arr;
    }
  
    function _nonIterableSpread() {
      throw new TypeError("Invalid attempt to spread non-iterable instance");
    }
  
    function _nonIterableRest() {
      throw new TypeError("Invalid attempt to destructure non-iterable instance");
    }
  
    var globalID = 1;
    var pastWarnings = {};
    var Utils = {
      // Parsley DOM-API
      // returns object from dom attributes and values
      attr: function attr(element, namespace, obj) {
        var i;
        var attribute;
        var attributes;
        var regex = new RegExp('^' + namespace, 'i');
        if ('undefined' === typeof obj) obj = {};else {
          // Clear all own properties. This won't affect prototype's values
          for (i in obj) {
            if (obj.hasOwnProperty(i)) delete obj[i];
          }
        }
        if (!element) return obj;
        attributes = element.attributes;
  
        for (i = attributes.length; i--;) {
          attribute = attributes[i];
  
          if (attribute && attribute.specified && regex.test(attribute.name)) {
            obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
          }
        }
  
        return obj;
      },
      checkAttr: function checkAttr(element, namespace, _checkAttr) {
        return element.hasAttribute(namespace + _checkAttr);
      },
      setAttr: function setAttr(element, namespace, attr, value) {
        element.setAttribute(this.dasherize(namespace + attr), String(value));
      },
      getType: function getType(element) {
        return element.getAttribute('type') || 'text';
      },
      generateID: function generateID() {
        return '' + globalID++;
      },
  
      /** Third party functions **/
      deserializeValue: function deserializeValue(value) {
        var num;
  
        try {
          return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? JSON.parse(value) : value) : value;
        } catch (e) {
          return value;
        }
      },
      // Zepto camelize function
      camelize: function camelize(str) {
        return str.replace(/-+(.)?/g, function (match, chr) {
          return chr ? chr.toUpperCase() : '';
        });
      },
      // Zepto dasherize function
      dasherize: function dasherize(str) {
        return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase();
      },
      warn: function warn() {
        var _window$console;
  
        if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
      },
      warnOnce: function warnOnce(msg) {
        if (!pastWarnings[msg]) {
          pastWarnings[msg] = true;
          this.warn.apply(this, arguments);
        }
      },
      _resetWarnings: function _resetWarnings() {
        pastWarnings = {};
      },
      trimString: function trimString(string) {
        return string.replace(/^\s+|\s+$/g, '');
      },
      parse: {
        date: function date(string) {
          var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/);
          if (!parsed) return null;
  
          var _parsed$map = parsed.map(function (x) {
            return parseInt(x, 10);
          }),
              _parsed$map2 = _slicedToArray(_parsed$map, 4),
              _ = _parsed$map2[0],
              year = _parsed$map2[1],
              month = _parsed$map2[2],
              day = _parsed$map2[3];
  
          var date = new Date(year, month - 1, day);
          if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null;
          return date;
        },
        string: function string(_string) {
          return _string;
        },
        integer: function integer(string) {
          if (isNaN(string)) return null;
          return parseInt(string, 10);
        },
        number: function number(string) {
          if (isNaN(string)) throw null;
          return parseFloat(string);
        },
        'boolean': function _boolean(string) {
          return !/^\s*false\s*$/i.test(string);
        },
        object: function object(string) {
          return Utils.deserializeValue(string);
        },
        regexp: function regexp(_regexp) {
          var flags = ''; // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
  
          if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
            // Replace the regexp literal string with the first match group: ([gimy]*)
            // If no flag is present, this will be a blank string
            flags = _regexp.replace(/.*\/([gimy]*)$/, '$1'); // Again, replace the regexp literal string with the first match group:
            // everything excluding the opening and closing slashes and the flags
  
            _regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
          } else {
            // Anchor regexp:
            _regexp = '^' + _regexp + '$';
          }
  
          return new RegExp(_regexp, flags);
        }
      },
      parseRequirement: function parseRequirement(requirementType, string) {
        var converter = this.parse[requirementType || 'string'];
        if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
        var converted = converter(string);
        if (converted === null) throw "Requirement is not a ".concat(requirementType, ": \"").concat(string, "\"");
        return converted;
      },
      namespaceEvents: function namespaceEvents(events, namespace) {
        events = this.trimString(events || '').split(/\s+/);
        if (!events[0]) return '';
        return $.map(events, function (evt) {
          return "".concat(evt, ".").concat(namespace);
        }).join(' ');
      },
      difference: function difference(array, remove) {
        // This is O(N^2), should be optimized
        var result = [];
        $.each(array, function (_, elem) {
          if (remove.indexOf(elem) == -1) result.push(elem);
        });
        return result;
      },
      // Alter-ego to native Promise.all, but for jQuery
      all: function all(promises) {
        // jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
        return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
      },
      // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
      objectCreate: Object.create || function () {
        var Object = function Object() {};
  
        return function (prototype) {
          if (arguments.length > 1) {
            throw Error('Second argument not supported');
          }
  
          if (_typeof(prototype) != 'object') {
            throw TypeError('Argument must be an object');
          }
  
          Object.prototype = prototype;
          var result = new Object();
          Object.prototype = null;
          return result;
        };
      }(),
      _SubmitSelector: 'input[type="submit"], button:submit'
    };
  
    // All these options could be overriden and specified directly in DOM using
    // `data-parsley-` default DOM-API
    // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
    // eg: `data-parsley-stop-on-first-failing-constraint="false"`
    var Defaults = {
      // ### General
      // Default data-namespace for DOM API
      namespace: 'data-parsley-',
      // Supported inputs by default
      inputs: 'input, textarea, select',
      // Excluded inputs by default
      excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
      // Stop validating field on highest priority failing constraint
      priorityEnabled: true,
      // ### Field only
      // identifier used to group together inputs (e.g. radio buttons...)
      multiple: null,
      // identifier (or array of identifiers) used to validate only a select group of inputs
      group: null,
      // ### UI
      // Enable\Disable error messages
      uiEnabled: true,
      // Key events threshold before validation
      validationThreshold: 3,
      // Focused field on form validation error. 'first'|'last'|'none'
      focus: 'first',
      // event(s) that will trigger validation before first failure. eg: `input`...
      trigger: false,
      // event(s) that will trigger validation after first failure.
      triggerAfterFailure: 'input',
      // Class that would be added on every failing validation Parsley field
      errorClass: 'parsley-error',
      // Same for success validation
      successClass: 'parsley-success',
      // Return the `$element` that will receive these above success or error classes
      // Could also be (and given directly from DOM) a valid selector like `'#div'`
      classHandler: function classHandler(Field) {},
      // Return the `$element` where errors will be appended
      // Could also be (and given directly from DOM) a valid selector like `'#div'`
      errorsContainer: function errorsContainer(Field) {},
      // ul elem that would receive errors' list
      errorsWrapper: '<ul class="parsley-errors-list"></ul>',
      // li elem that would receive error message
      errorTemplate: '<li></li>'
    };
  
    var Base = function Base() {
      this.__id__ = Utils.generateID();
    };
  
    Base.prototype = {
      asyncSupport: true,
      // Deprecated
      _pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
        var _this = this;
  
        var pipe = function pipe() {
          var r = $.Deferred();
          if (true !== _this.validationResult) r.reject();
          return r.resolve().promise();
        };
  
        return [pipe, pipe];
      },
      actualizeOptions: function actualizeOptions() {
        Utils.attr(this.element, this.options.namespace, this.domOptions);
        if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
        return this;
      },
      _resetOptions: function _resetOptions(initOptions) {
        this.domOptions = Utils.objectCreate(this.parent.options);
        this.options = Utils.objectCreate(this.domOptions); // Shallow copy of ownProperties of initOptions:
  
        for (var i in initOptions) {
          if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
        }
  
        this.actualizeOptions();
      },
      _listeners: null,
      // Register a callback for the given event name
      // Callback is called with context as the first argument and the `this`
      // The context is the current parsley instance, or window.Parsley if global
      // A return value of `false` will interrupt the calls
      on: function on(name, fn) {
        this._listeners = this._listeners || {};
        var queue = this._listeners[name] = this._listeners[name] || [];
        queue.push(fn);
        return this;
      },
      // Deprecated. Use `on` instead
      subscribe: function subscribe(name, fn) {
        $.listenTo(this, name.toLowerCase(), fn);
      },
      // Unregister a callback (or all if none is given) for the given event name
      off: function off(name, fn) {
        var queue = this._listeners && this._listeners[name];
  
        if (queue) {
          if (!fn) {
            delete this._listeners[name];
          } else {
            for (var i = queue.length; i--;) {
              if (queue[i] === fn) queue.splice(i, 1);
            }
          }
        }
  
        return this;
      },
      // Deprecated. Use `off`
      unsubscribe: function unsubscribe(name, fn) {
        $.unsubscribeTo(this, name.toLowerCase());
      },
      // Trigger an event of the given name
      // A return value of `false` interrupts the callback chain
      // Returns false if execution was interrupted
      trigger: function trigger(name, target, extraArg) {
        target = target || this;
        var queue = this._listeners && this._listeners[name];
        var result;
  
        if (queue) {
          for (var i = queue.length; i--;) {
            result = queue[i].call(target, target, extraArg);
            if (result === false) return result;
          }
        }
  
        if (this.parent) {
          return this.parent.trigger(name, target, extraArg);
        }
  
        return true;
      },
      asyncIsValid: function asyncIsValid(group, force) {
        Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
        return this.whenValid({
          group: group,
          force: force
        });
      },
      _findRelated: function _findRelated() {
        return this.options.multiple ? $(this.parent.element.querySelectorAll("[".concat(this.options.namespace, "multiple=\"").concat(this.options.multiple, "\"]"))) : this.$element;
      }
    };
  
    var convertArrayRequirement = function convertArrayRequirement(string, length) {
      var m = string.match(/^\s*\[(.*)\]\s*$/);
      if (!m) throw 'Requirement is not an array: "' + string + '"';
      var values = m[1].split(',').map(Utils.trimString);
      if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
      return values;
    };
  
    var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
      var main = null;
      var extra = {};
  
      for (var key in requirementSpec) {
        if (key) {
          var value = extraOptionReader(key);
          if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
          extra[key] = value;
        } else {
          main = Utils.parseRequirement(requirementSpec[key], string);
        }
      }
  
      return [main, extra];
    }; // A Validator needs to implement the methods `validate` and `parseRequirements`
  
  
    var Validator = function Validator(spec) {
      $.extend(true, this, spec);
    };
  
    Validator.prototype = {
      // Returns `true` iff the given `value` is valid according the given requirements.
      validate: function validate(value, requirementFirstArg) {
        if (this.fn) {
          // Legacy style validator
          if (arguments.length > 3) // If more args then value, requirement, instance...
            requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
  
          return this.fn(value, requirementFirstArg);
        }
  
        if (Array.isArray(value)) {
          if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
          return this.validateMultiple.apply(this, arguments);
        } else {
          var instance = arguments[arguments.length - 1];
  
          if (this.validateDate && instance._isDateInput()) {
            arguments[0] = Utils.parse.date(arguments[0]);
            if (arguments[0] === null) return false;
            return this.validateDate.apply(this, arguments);
          }
  
          if (this.validateNumber) {
            if (!value) // Builtin validators all accept empty strings, except `required` of course
              return true;
            if (isNaN(value)) return false;
            arguments[0] = parseFloat(arguments[0]);
            return this.validateNumber.apply(this, arguments);
          }
  
          if (this.validateString) {
            return this.validateString.apply(this, arguments);
          }
  
          throw 'Validator `' + this.name + '` only handles multiple values';
        }
      },
      // Parses `requirements` into an array of arguments,
      // according to `this.requirementType`
      parseRequirements: function parseRequirements(requirements, extraOptionReader) {
        if ('string' !== typeof requirements) {
          // Assume requirement already parsed
          // but make sure we return an array
          return Array.isArray(requirements) ? requirements : [requirements];
        }
  
        var type = this.requirementType;
  
        if (Array.isArray(type)) {
          var values = convertArrayRequirement(requirements, type.length);
  
          for (var i = 0; i < values.length; i++) {
            values[i] = Utils.parseRequirement(type[i], values[i]);
          }
  
          return values;
        } else if ($.isPlainObject(type)) {
          return convertExtraOptionRequirement(type, requirements, extraOptionReader);
        } else {
          return [Utils.parseRequirement(type, requirements)];
        }
      },
      // Defaults:
      requirementType: 'string',
      priority: 2
    };
  
    var ValidatorRegistry = function ValidatorRegistry(validators, catalog) {
      this.__class__ = 'ValidatorRegistry'; // Default Parsley locale is en
  
      this.locale = 'en';
      this.init(validators || {}, catalog || {});
    };
  
    var typeTesters = {
      email: /^((([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))$/,
      // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
      number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
      integer: /^-?\d+$/,
      digits: /^\d+$/,
      alphanum: /^\w+$/i,
      date: {
        test: function test(value) {
          return Utils.parse.date(value) !== null;
        }
      },
      url: new RegExp("^" + // protocol identifier
      "(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
      // user:pass authentication
      "(?:\\S+(?::\\S*)?@)?" + "(?:" + // IP address exclusion
      // private & local networks
      // "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +   // ** mod: allow local networks
      // "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +  // ** mod: allow local networks
      // "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +  // ** mod: allow local networks
      // IP address dotted notation octets
      // excludes loopback network 0.0.0.0
      // excludes reserved space >= 224.0.0.0
      // excludes network & broacast addresses
      // (first & last IP address of each class)
      "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" + // host name
      "(?:(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)" + // domain name
      "(?:\\.(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)*" + // TLD identifier
      "(?:\\.(?:[a-zA-Z\\u00a1-\\uffff]{2,}))" + ")" + // port number
      "(?::\\d{2,5})?" + // resource path
      "(?:/\\S*)?" + "$")
    };
    typeTesters.range = typeTesters.number; // See http://stackoverflow.com/a/10454560/8279
  
    var decimalPlaces = function decimalPlaces(num) {
      var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
  
      if (!match) {
        return 0;
      }
  
      return Math.max(0, // Number of digits right of decimal point.
      (match[1] ? match[1].length : 0) - ( // Adjust for scientific notation.
      match[2] ? +match[2] : 0));
    }; // parseArguments('number', ['1', '2']) => [1, 2]
  
  
    var parseArguments = function parseArguments(type, args) {
      return args.map(Utils.parse[type]);
    }; // operatorToValidator returns a validating function for an operator function, applied to the given type
  
  
    var operatorToValidator = function operatorToValidator(type, operator) {
      return function (value) {
        for (var _len = arguments.length, requirementsAndInput = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          requirementsAndInput[_key - 1] = arguments[_key];
        }
  
        requirementsAndInput.pop(); // Get rid of `input` argument
  
        return operator.apply(void 0, [value].concat(_toConsumableArray(parseArguments(type, requirementsAndInput))));
      };
    };
  
    var comparisonOperator = function comparisonOperator(operator) {
      return {
        validateDate: operatorToValidator('date', operator),
        validateNumber: operatorToValidator('number', operator),
        requirementType: operator.length <= 2 ? 'string' : ['string', 'string'],
        // Support operators with a 1 or 2 requirement(s)
        priority: 30
      };
    };
  
    ValidatorRegistry.prototype = {
      init: function init(validators, catalog) {
        this.catalog = catalog; // Copy prototype's validators:
  
        this.validators = _extends({}, this.validators);
  
        for (var name in validators) {
          this.addValidator(name, validators[name].fn, validators[name].priority);
        }
  
        window.Parsley.trigger('parsley:validator:init');
      },
      // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
      setLocale: function setLocale(locale) {
        if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
        this.locale = locale;
        return this;
      },
      // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
      addCatalog: function addCatalog(locale, messages, set) {
        if ('object' === _typeof(messages)) this.catalog[locale] = messages;
        if (true === set) return this.setLocale(locale);
        return this;
      },
      // Add a specific message for a given constraint in a given locale
      addMessage: function addMessage(locale, name, message) {
        if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
        this.catalog[locale][name] = message;
        return this;
      },
      // Add messages for a given locale
      addMessages: function addMessages(locale, nameMessageObject) {
        for (var name in nameMessageObject) {
          this.addMessage(locale, name, nameMessageObject[name]);
        }
  
        return this;
      },
      // Add a new validator
      //
      //    addValidator('custom', {
      //        requirementType: ['integer', 'integer'],
      //        validateString: function(value, from, to) {},
      //        priority: 22,
      //        messages: {
      //          en: "Hey, that's no good",
      //          fr: "Aye aye, pas bon du tout",
      //        }
      //    })
      //
      // Old API was addValidator(name, function, priority)
      //
      addValidator: function addValidator(name, arg1, arg2) {
        if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
          Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
          return;
        }
        return this._setValidator.apply(this, arguments);
      },
      hasValidator: function hasValidator(name) {
        return !!this.validators[name];
      },
      updateValidator: function updateValidator(name, arg1, arg2) {
        if (!this.validators[name]) {
          Utils.warn('Validator "' + name + '" is not already defined.');
          return this.addValidator.apply(this, arguments);
        }
  
        return this._setValidator.apply(this, arguments);
      },
      removeValidator: function removeValidator(name) {
        if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
        delete this.validators[name];
        return this;
      },
      _setValidator: function _setValidator(name, validator, priority) {
        if ('object' !== _typeof(validator)) {
          // Old style validator, with `fn` and `priority`
          validator = {
            fn: validator,
            priority: priority
          };
        }
  
        if (!validator.validate) {
          validator = new Validator(validator);
        }
  
        this.validators[name] = validator;
  
        for (var locale in validator.messages || {}) {
          this.addMessage(locale, name, validator.messages[locale]);
        }
  
        return this;
      },
      getErrorMessage: function getErrorMessage(constraint) {
        var message; // Type constraints are a bit different, we have to match their requirements too to find right error message
  
        if ('type' === constraint.name) {
          var typeMessages = this.catalog[this.locale][constraint.name] || {};
          message = typeMessages[constraint.requirements];
        } else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
  
        return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
      },
      // Kind of light `sprintf()` implementation
      formatMessage: function formatMessage(string, parameters) {
        if ('object' === _typeof(parameters)) {
          for (var i in parameters) {
            string = this.formatMessage(string, parameters[i]);
          }
  
          return string;
        }
  
        return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
      },
      // Here is the Parsley default validators list.
      // A validator is an object with the following key values:
      //  - priority: an integer
      //  - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
      //  - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
      // Alternatively, a validator can be a function that returns such an object
      //
      validators: {
        notblank: {
          validateString: function validateString(value) {
            return /\S/.test(value);
          },
          priority: 2
        },
        required: {
          validateMultiple: function validateMultiple(values) {
            return values.length > 0;
          },
          validateString: function validateString(value) {
            return /\S/.test(value);
          },
          priority: 512
        },
        type: {
          validateString: function validateString(value, type) {
            var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
                _ref$step = _ref.step,
                step = _ref$step === void 0 ? 'any' : _ref$step,
                _ref$base = _ref.base,
                base = _ref$base === void 0 ? 0 : _ref$base;
  
            var tester = typeTesters[type];
  
            if (!tester) {
              throw new Error('validator type `' + type + '` is not supported');
            }
  
            if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
  
            if (!tester.test(value)) return false;
  
            if ('number' === type) {
              if (!/^any$/i.test(step || '')) {
                var nb = Number(value);
                var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
                if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
                  return false; // Be careful of rounding errors by using integers.
  
                var toInt = function toInt(f) {
                  return Math.round(f * Math.pow(10, decimals));
                };
  
                if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
              }
            }
  
            return true;
          },
          requirementType: {
            '': 'string',
            step: 'string',
            base: 'number'
          },
          priority: 256
        },
        pattern: {
          validateString: function validateString(value, regexp) {
            if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
  
            return regexp.test(value);
          },
          requirementType: 'regexp',
          priority: 64
        },
        minlength: {
          validateString: function validateString(value, requirement) {
            if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
  
            return value.length >= requirement;
          },
          requirementType: 'integer',
          priority: 30
        },
        maxlength: {
          validateString: function validateString(value, requirement) {
            return value.length <= requirement;
          },
          requirementType: 'integer',
          priority: 30
        },
        length: {
          validateString: function validateString(value, min, max) {
            if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
  
            return value.length >= min && value.length <= max;
          },
          requirementType: ['integer', 'integer'],
          priority: 30
        },
        mincheck: {
          validateMultiple: function validateMultiple(values, requirement) {
            return values.length >= requirement;
          },
          requirementType: 'integer',
          priority: 30
        },
        maxcheck: {
          validateMultiple: function validateMultiple(values, requirement) {
            return values.length <= requirement;
          },
          requirementType: 'integer',
          priority: 30
        },
        check: {
          validateMultiple: function validateMultiple(values, min, max) {
            return values.length >= min && values.length <= max;
          },
          requirementType: ['integer', 'integer'],
          priority: 30
        },
        min: comparisonOperator(function (value, requirement) {
          return value >= requirement;
        }),
        max: comparisonOperator(function (value, requirement) {
          return value <= requirement;
        }),
        range: comparisonOperator(function (value, min, max) {
          return value >= min && value <= max;
        }),
        equalto: {
          validateString: function validateString(value, refOrValue) {
            if (!value) return true; // Builtin validators all accept empty strings, except `required` of course
  
            var $reference = $(refOrValue);
            if ($reference.length) return value === $reference.val();else return value === refOrValue;
          },
          priority: 256
        },
        euvatin: {
          validateString: function validateString(value, refOrValue) {
            if (!value) {
              return true; // Builtin validators all accept empty strings, except `required` of course
            }
  
            var re = /^[A-Z][A-Z][A-Za-z0-9 -]{2,}$/;
            return re.test(value);
          },
          priority: 30
        }
      }
    };
  
    var UI = {};
  
    var diffResults = function diffResults(newResult, oldResult, deep) {
      var added = [];
      var kept = [];
  
      for (var i = 0; i < newResult.length; i++) {
        var found = false;
  
        for (var j = 0; j < oldResult.length; j++) {
          if (newResult[i].assert.name === oldResult[j].assert.name) {
            found = true;
            break;
          }
        }
  
        if (found) kept.push(newResult[i]);else added.push(newResult[i]);
      }
  
      return {
        kept: kept,
        added: added,
        removed: !deep ? diffResults(oldResult, newResult, true).added : []
      };
    };
  
    UI.Form = {
      _actualizeTriggers: function _actualizeTriggers() {
        var _this = this;
  
        this.$element.on('submit.Parsley', function (evt) {
          _this.onSubmitValidate(evt);
        });
        this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
          _this.onSubmitButton(evt);
        }); // UI could be disabled
  
        if (false === this.options.uiEnabled) return;
        this.element.setAttribute('novalidate', '');
      },
      focus: function focus() {
        this._focusedField = null;
        if (true === this.validationResult || 'none' === this.options.focus) return null;
  
        for (var i = 0; i < this.fields.length; i++) {
          var field = this.fields[i];
  
          if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
            this._focusedField = field.$element;
            if ('first' === this.options.focus) break;
          }
        }
  
        if (null === this._focusedField) return null;
        return this._focusedField.focus();
      },
      _destroyUI: function _destroyUI() {
        // Reset all event listeners
        this.$element.off('.Parsley');
      }
    };
    UI.Field = {
      _reflowUI: function _reflowUI() {
        this._buildUI(); // If this field doesn't have an active UI don't bother doing something
  
  
        if (!this._ui) return; // Diff between two validation results
  
        var diff = diffResults(this.validationResult, this._ui.lastValidationResult); // Then store current validation result for next reflow
  
        this._ui.lastValidationResult = this.validationResult; // Handle valid / invalid / none field class
  
        this._manageStatusClass(); // Add, remove, updated errors messages
  
  
        this._manageErrorsMessages(diff); // Triggers impl
  
  
        this._actualizeTriggers(); // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
  
  
        if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
          this._failedOnce = true;
  
          this._actualizeTriggers();
        }
      },
      // Returns an array of field's error message(s)
      getErrorsMessages: function getErrorsMessages() {
        // No error message, field is valid
        if (true === this.validationResult) return [];
        var messages = [];
  
        for (var i = 0; i < this.validationResult.length; i++) {
          messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
        }
  
        return messages;
      },
      // It's a goal of Parsley that this method is no longer required [#1073]
      addError: function addError(name) {
        var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
            message = _ref.message,
            assert = _ref.assert,
            _ref$updateClass = _ref.updateClass,
            updateClass = _ref$updateClass === void 0 ? true : _ref$updateClass;
  
        this._buildUI();
  
        this._addError(name, {
          message: message,
          assert: assert
        });
  
        if (updateClass) this._errorClass();
      },
      // It's a goal of Parsley that this method is no longer required [#1073]
      updateError: function updateError(name) {
        var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
            message = _ref2.message,
            assert = _ref2.assert,
            _ref2$updateClass = _ref2.updateClass,
            updateClass = _ref2$updateClass === void 0 ? true : _ref2$updateClass;
  
        this._buildUI();
  
        this._updateError(name, {
          message: message,
          assert: assert
        });
  
        if (updateClass) this._errorClass();
      },
      // It's a goal of Parsley that this method is no longer required [#1073]
      removeError: function removeError(name) {
        var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
            _ref3$updateClass = _ref3.updateClass,
            updateClass = _ref3$updateClass === void 0 ? true : _ref3$updateClass;
  
        this._buildUI();
  
        this._removeError(name); // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
        // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
  
  
        if (updateClass) this._manageStatusClass();
      },
      _manageStatusClass: function _manageStatusClass() {
        if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
      },
      _manageErrorsMessages: function _manageErrorsMessages(diff) {
        if ('undefined' !== typeof this.options.errorsMessagesDisabled) return; // Case where we have errorMessage option that configure an unique field error message, regardless failing validators
  
        if ('undefined' !== typeof this.options.errorMessage) {
          if (diff.added.length || diff.kept.length) {
            this._insertErrorWrapper();
  
            if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
  
            this._ui.$errorClassHandler.attr('aria-describedby', this._ui.errorsWrapperId);
  
            return this._ui.$errorsWrapper.addClass('filled').attr('aria-hidden', 'false').find('.parsley-custom-error-message').html(this.options.errorMessage);
          }
  
          this._ui.$errorClassHandler.removeAttr('aria-describedby');
  
          return this._ui.$errorsWrapper.removeClass('filled').attr('aria-hidden', 'true').find('.parsley-custom-error-message').remove();
        } // Show, hide, update failing constraints messages
  
  
        for (var i = 0; i < diff.removed.length; i++) {
          this._removeError(diff.removed[i].assert.name);
        }
  
        for (i = 0; i < diff.added.length; i++) {
          this._addError(diff.added[i].assert.name, {
            message: diff.added[i].errorMessage,
            assert: diff.added[i].assert
          });
        }
  
        for (i = 0; i < diff.kept.length; i++) {
          this._updateError(diff.kept[i].assert.name, {
            message: diff.kept[i].errorMessage,
            assert: diff.kept[i].assert
          });
        }
      },
      _addError: function _addError(name, _ref4) {
        var message = _ref4.message,
            assert = _ref4.assert;
  
        this._insertErrorWrapper();
  
        this._ui.$errorClassHandler.attr('aria-describedby', this._ui.errorsWrapperId);
  
        this._ui.$errorsWrapper.addClass('filled').attr('aria-hidden', 'false').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert)));
      },
      _updateError: function _updateError(name, _ref5) {
        var message = _ref5.message,
            assert = _ref5.assert;
  
        this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
      },
      _removeError: function _removeError(name) {
        this._ui.$errorClassHandler.removeAttr('aria-describedby');
  
        this._ui.$errorsWrapper.removeClass('filled').attr('aria-hidden', 'true').find('.parsley-' + name).remove();
      },
      _getErrorMessage: function _getErrorMessage(constraint) {
        var customConstraintErrorMessage = constraint.name + 'Message';
        if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
        return window.Parsley.getErrorMessage(constraint);
      },
      _buildUI: function _buildUI() {
        // UI could be already built or disabled
        if (this._ui || false === this.options.uiEnabled) return;
        var _ui = {}; // Give field its Parsley id in DOM
  
        this.element.setAttribute(this.options.namespace + 'id', this.__id__);
        /** Generate important UI elements and store them in this **/
        // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
  
        _ui.$errorClassHandler = this._manageClassHandler(); // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
  
        _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
        _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId); // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
  
        _ui.lastValidationResult = [];
        _ui.validationInformationVisible = false; // Store it in this for later
  
        this._ui = _ui;
      },
      // Determine which element will have `parsley-error` and `parsley-success` classes
      _manageClassHandler: function _manageClassHandler() {
        // Class handled could also be determined by function given in Parsley options
        if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler); // Class handled could also be determined by function given in Parsley options
  
        var $handlerFunction = this.options.classHandler; // It might also be the function name of a global function
  
        if ('string' === typeof this.options.classHandler && 'function' === typeof window[this.options.classHandler]) $handlerFunction = window[this.options.classHandler];
  
        if ('function' === typeof $handlerFunction) {
          var $handler = $handlerFunction.call(this, this); // If this function returned a valid existing DOM element, go for it
  
          if ('undefined' !== typeof $handler && $handler.length) return $handler;
        } else if ('object' === _typeof($handlerFunction) && $handlerFunction instanceof jQuery && $handlerFunction.length) {
          return $handlerFunction;
        } else if ($handlerFunction) {
          Utils.warn('The class handler `' + $handlerFunction + '` does not exist in DOM nor as a global JS function');
        }
  
        return this._inputHolder();
      },
      _inputHolder: function _inputHolder() {
        // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
        if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element; // But if multiple element (radio, checkbox), that would be their parent
  
        return this.$element.parent();
      },
      _insertErrorWrapper: function _insertErrorWrapper() {
        var $errorsContainer = this.options.errorsContainer; // Nothing to do if already inserted
  
        if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
  
        if ('string' === typeof $errorsContainer) {
          if ($($errorsContainer).length) return $($errorsContainer).append(this._ui.$errorsWrapper);else if ('function' === typeof window[$errorsContainer]) $errorsContainer = window[$errorsContainer];else Utils.warn('The errors container `' + $errorsContainer + '` does not exist in DOM nor as a global JS function');
        }
  
        if ('function' === typeof $errorsContainer) $errorsContainer = $errorsContainer.call(this, this);
        if ('object' === _typeof($errorsContainer) && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
        return this._inputHolder().after(this._ui.$errorsWrapper);
      },
      _actualizeTriggers: function _actualizeTriggers() {
        var _this2 = this;
  
        var $toBind = this._findRelated();
  
        var trigger; // Remove Parsley events already bound on this field
  
        $toBind.off('.Parsley');
        if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
          _this2._validateIfNeeded();
        });else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
          $toBind.on(trigger, function (event) {
            _this2._validateIfNeeded(event);
          });
        }
      },
      _validateIfNeeded: function _validateIfNeeded(event) {
        var _this3 = this;
  
        // For keyup, keypress, keydown, input... events that could be a little bit obstrusive
        // do not validate if val length < min threshold on first validation. Once field have been validated once and info
        // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
        if (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
  
        if (this.options.debounce) {
          window.clearTimeout(this._debounced);
          this._debounced = window.setTimeout(function () {
            return _this3.validate();
          }, this.options.debounce);
        } else this.validate();
      },
      _resetUI: function _resetUI() {
        // Reset all event listeners
        this._failedOnce = false;
  
        this._actualizeTriggers(); // Nothing to do if UI never initialized for this field
  
  
        if ('undefined' === typeof this._ui) return; // Reset all errors' li
  
        this._ui.$errorsWrapper.removeClass('filled').children().remove(); // Reset validation class
  
  
        this._resetClass(); // Reset validation flags and last validation result
  
  
        this._ui.lastValidationResult = [];
        this._ui.validationInformationVisible = false;
      },
      _destroyUI: function _destroyUI() {
        this._resetUI();
  
        if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
        delete this._ui;
      },
      _successClass: function _successClass() {
        this._ui.validationInformationVisible = true;
  
        this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
      },
      _errorClass: function _errorClass() {
        this._ui.validationInformationVisible = true;
  
        this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
      },
      _resetClass: function _resetClass() {
        this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
      }
    };
  
    var Form = function Form(element, domOptions, options) {
      this.__class__ = 'Form';
      this.element = element;
      this.$element = $(element);
      this.domOptions = domOptions;
      this.options = options;
      this.parent = window.Parsley;
      this.fields = [];
      this.validationResult = null;
    };
  
    var statusMapping = {
      pending: null,
      resolved: true,
      rejected: false
    };
    Form.prototype = {
      onSubmitValidate: function onSubmitValidate(event) {
        var _this = this;
  
        // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
        if (true === event.parsley) return; // If we didn't come here through a submit button, use the first one in the form
  
        var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
        this._submitSource = null;
        this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
        if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
        window.Parsley._remoteCache = {};
        var promise = this.whenValidate({
          event: event
        });
  
        if ('resolved' === promise.state() && false !== this._trigger('submit')) ; else {
          // Rejected or pending: cancel this submit
          event.stopImmediatePropagation();
          event.preventDefault();
          if ('pending' === promise.state()) promise.done(function () {
            _this._submit(submitSource);
          });
        }
      },
      onSubmitButton: function onSubmitButton(event) {
        this._submitSource = event.currentTarget;
      },
      // internal
      // _submit submits the form, this time without going through the validations.
      // Care must be taken to "fake" the actual submit button being clicked.
      _submit: function _submit(submitSource) {
        if (false === this._trigger('submit')) return; // Add submit button's data
  
        if (submitSource) {
          var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
          if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
          $synthetic.attr({
            name: submitSource.getAttribute('name'),
            value: submitSource.getAttribute('value')
          });
        }
  
        this.$element.trigger(_extends($.Event('submit'), {
          parsley: true
        }));
      },
      // Performs validation on fields while triggering events.
      // @returns `true` if all validations succeeds, `false`
      // if a failure is immediately detected, or `null`
      // if dependant on a promise.
      // Consider using `whenValidate` instead.
      validate: function validate(options) {
        if (arguments.length >= 1 && !$.isPlainObject(options)) {
          Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
  
          var _arguments = Array.prototype.slice.call(arguments),
              group = _arguments[0],
              force = _arguments[1],
              event = _arguments[2];
  
          options = {
            group: group,
            force: force,
            event: event
          };
        }
  
        return statusMapping[this.whenValidate(options).state()];
      },
      whenValidate: function whenValidate() {
        var _this2 = this,
            _Utils$all$done$fail$;
  
        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
            group = _ref.group,
            force = _ref.force,
            event = _ref.event;
  
        this.submitEvent = event;
  
        if (event) {
          this.submitEvent = _extends({}, event, {
            preventDefault: function preventDefault() {
              Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
              _this2.validationResult = false;
            }
          });
        }
  
        this.validationResult = true; // fire validate event to eventually modify things before every validation
  
        this._trigger('validate'); // Refresh form DOM options and form's fields that could have changed
  
  
        this._refreshFields();
  
        var promises = this._withoutReactualizingFormOptions(function () {
          return $.map(_this2.fields, function (field) {
            return field.whenValidate({
              force: force,
              group: group
            });
          });
        });
  
        return (_Utils$all$done$fail$ = Utils.all(promises).done(function () {
          _this2._trigger('success');
        }).fail(function () {
          _this2.validationResult = false;
  
          _this2.focus();
  
          _this2._trigger('error');
        }).always(function () {
          _this2._trigger('validated');
        })).pipe.apply(_Utils$all$done$fail$, _toConsumableArray(this._pipeAccordingToValidationResult()));
      },
      // Iterate over refreshed fields, and stop on first failure.
      // Returns `true` if all fields are valid, `false` if a failure is detected
      // or `null` if the result depends on an unresolved promise.
      // Prefer using `whenValid` instead.
      isValid: function isValid(options) {
        if (arguments.length >= 1 && !$.isPlainObject(options)) {
          Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
  
          var _arguments2 = Array.prototype.slice.call(arguments),
              group = _arguments2[0],
              force = _arguments2[1];
  
          options = {
            group: group,
            force: force
          };
        }
  
        return statusMapping[this.whenValid(options).state()];
      },
      // Iterate over refreshed fields and validate them.
      // Returns a promise.
      // A validation that immediately fails will interrupt the validations.
      whenValid: function whenValid() {
        var _this3 = this;
  
        var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
            group = _ref2.group,
            force = _ref2.force;
  
        this._refreshFields();
  
        var promises = this._withoutReactualizingFormOptions(function () {
          return $.map(_this3.fields, function (field) {
            return field.whenValid({
              group: group,
              force: force
            });
          });
        });
  
        return Utils.all(promises);
      },
      refresh: function refresh() {
        this._refreshFields();
  
        return this;
      },
      // Reset UI
      reset: function reset() {
        // Form case: emit a reset event for each field
        for (var i = 0; i < this.fields.length; i++) {
          this.fields[i].reset();
        }
  
        this._trigger('reset');
      },
      // Destroy Parsley instance (+ UI)
      destroy: function destroy() {
        // Field case: emit destroy event to clean UI and then destroy stored instance
        this._destroyUI(); // Form case: destroy all its fields and then destroy stored instance
  
  
        for (var i = 0; i < this.fields.length; i++) {
          this.fields[i].destroy();
        }
  
        this.$element.removeData('Parsley');
  
        this._trigger('destroy');
      },
      _refreshFields: function _refreshFields() {
        return this.actualizeOptions()._bindFields();
      },
      _bindFields: function _bindFields() {
        var _this4 = this;
  
        var oldFields = this.fields;
        this.fields = [];
        this.fieldsMappedById = {};
  
        this._withoutReactualizingFormOptions(function () {
          _this4.$element.find(_this4.options.inputs).not(_this4.options.excluded).not("[".concat(_this4.options.namespace, "excluded=true]")).each(function (_, element) {
            var fieldInstance = new window.Parsley.Factory(element, {}, _this4); // Only add valid and not excluded `Field` and `FieldMultiple` children
  
            if ('Field' === fieldInstance.__class__ || 'FieldMultiple' === fieldInstance.__class__) {
              var uniqueId = fieldInstance.__class__ + '-' + fieldInstance.__id__;
  
              if ('undefined' === typeof _this4.fieldsMappedById[uniqueId]) {
                _this4.fieldsMappedById[uniqueId] = fieldInstance;
  
                _this4.fields.push(fieldInstance);
              }
            }
          });
  
          $.each(Utils.difference(oldFields, _this4.fields), function (_, field) {
            field.reset();
          });
        });
  
        return this;
      },
      // Internal only.
      // Looping on a form's fields to do validation or similar
      // will trigger reactualizing options on all of them, which
      // in turn will reactualize the form's options.
      // To avoid calling actualizeOptions so many times on the form
      // for nothing, _withoutReactualizingFormOptions temporarily disables
      // the method actualizeOptions on this form while `fn` is called.
      _withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
        var oldActualizeOptions = this.actualizeOptions;
  
        this.actualizeOptions = function () {
          return this;
        };
  
        var result = fn();
        this.actualizeOptions = oldActualizeOptions;
        return result;
      },
      // Internal only.
      // Shortcut to trigger an event
      // Returns true iff event is not interrupted and default not prevented.
      _trigger: function _trigger(eventName) {
        return this.trigger('form:' + eventName);
      }
    };
  
    var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
      var validatorSpec = window.Parsley._validatorRegistry.validators[name];
      var validator = new Validator(validatorSpec);
      priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
      isDomConstraint = true === isDomConstraint;
  
      _extends(this, {
        validator: validator,
        name: name,
        requirements: requirements,
        priority: priority,
        isDomConstraint: isDomConstraint
      });
  
      this._parseRequirements(parsleyField.options);
    };
  
    var capitalize = function capitalize(str) {
      var cap = str[0].toUpperCase();
      return cap + str.slice(1);
    };
  
    Constraint.prototype = {
      validate: function validate(value, instance) {
        var _this$validator;
  
        return (_this$validator = this.validator).validate.apply(_this$validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
      },
      _parseRequirements: function _parseRequirements(options) {
        var _this = this;
  
        this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
          return options[_this.name + capitalize(key)];
        });
      }
    };
  
    var Field = function Field(field, domOptions, options, parsleyFormInstance) {
      this.__class__ = 'Field';
      this.element = field;
      this.$element = $(field); // Set parent if we have one
  
      if ('undefined' !== typeof parsleyFormInstance) {
        this.parent = parsleyFormInstance;
      }
  
      this.options = options;
      this.domOptions = domOptions; // Initialize some properties
  
      this.constraints = [];
      this.constraintsByName = {};
      this.validationResult = true; // Bind constraints
  
      this._bindConstraints();
    };
  
    var statusMapping$1 = {
      pending: null,
      resolved: true,
      rejected: false
    };
    Field.prototype = {
      // # Public API
      // Validate field and trigger some events for mainly `UI`
      // @returns `true`, an array of the validators that failed, or
      // `null` if validation is not finished. Prefer using whenValidate
      validate: function validate(options) {
        if (arguments.length >= 1 && !$.isPlainObject(options)) {
          Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
          options = {
            options: options
          };
        }
  
        var promise = this.whenValidate(options);
        if (!promise) // If excluded with `group` option
          return true;
  
        switch (promise.state()) {
          case 'pending':
            return null;
  
          case 'resolved':
            return true;
  
          case 'rejected':
            return this.validationResult;
        }
      },
      // Validate field and trigger some events for mainly `UI`
      // @returns a promise that succeeds only when all validations do
      // or `undefined` if field is not in the given `group`.
      whenValidate: function whenValidate() {
        var _this$whenValid$alway,
            _this = this;
  
        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
            force = _ref.force,
            group = _ref.group;
  
        // do not validate a field if not the same as given validation group
        this.refresh();
        if (group && !this._isInGroup(group)) return;
        this.value = this.getValue(); // Field Validate event. `this.value` could be altered for custom needs
  
        this._trigger('validate');
  
        return (_this$whenValid$alway = this.whenValid({
          force: force,
          value: this.value,
          _refreshed: true
        }).always(function () {
          _this._reflowUI();
        }).done(function () {
          _this._trigger('success');
        }).fail(function () {
          _this._trigger('error');
        }).always(function () {
          _this._trigger('validated');
        })).pipe.apply(_this$whenValid$alway, _toConsumableArray(this._pipeAccordingToValidationResult()));
      },
      hasConstraints: function hasConstraints() {
        return 0 !== this.constraints.length;
      },
      // An empty optional field does not need validation
      needsValidation: function needsValidation(value) {
        if ('undefined' === typeof value) value = this.getValue(); // If a field is empty and not required, it is valid
        // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
  
        if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
        return true;
      },
      _isInGroup: function _isInGroup(group) {
        if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
        return this.options.group === group;
      },
      // Just validate field. Do not trigger any event.
      // Returns `true` iff all constraints pass, `false` if there are failures,
      // or `null` if the result can not be determined yet (depends on a promise)
      // See also `whenValid`.
      isValid: function isValid(options) {
        if (arguments.length >= 1 && !$.isPlainObject(options)) {
          Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
  
          var _arguments = Array.prototype.slice.call(arguments),
              force = _arguments[0],
              value = _arguments[1];
  
          options = {
            force: force,
            value: value
          };
        }
  
        var promise = this.whenValid(options);
        if (!promise) // Excluded via `group`
          return true;
        return statusMapping$1[promise.state()];
      },
      // Just validate field. Do not trigger any event.
      // @returns a promise that succeeds only when all validations do
      // or `undefined` if the field is not in the given `group`.
      // The argument `force` will force validation of empty fields.
      // If a `value` is given, it will be validated instead of the value of the input.
      whenValid: function whenValid() {
        var _this2 = this;
  
        var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
            _ref2$force = _ref2.force,
            force = _ref2$force === void 0 ? false : _ref2$force,
            value = _ref2.value,
            group = _ref2.group,
            _refreshed = _ref2._refreshed;
  
        // Recompute options and rebind constraints to have latest changes
        if (!_refreshed) this.refresh(); // do not validate a field if not the same as given validation group
  
        if (group && !this._isInGroup(group)) return;
        this.validationResult = true; // A field without constraint is valid
  
        if (!this.hasConstraints()) return $.when(); // Value could be passed as argument, needed to add more power to 'field:validate'
  
        if ('undefined' === typeof value || null === value) value = this.getValue();
        if (!this.needsValidation(value) && true !== force) return $.when();
  
        var groupedConstraints = this._getGroupedConstraints();
  
        var promises = [];
        $.each(groupedConstraints, function (_, constraints) {
          // Process one group of constraints at a time, we validate the constraints
          // and combine the promises together.
          var promise = Utils.all($.map(constraints, function (constraint) {
            return _this2._validateConstraint(value, constraint);
          }));
          promises.push(promise);
          if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
        });
        return Utils.all(promises);
      },
      // @returns a promise
      _validateConstraint: function _validateConstraint(value, constraint) {
        var _this3 = this;
  
        var result = constraint.validate(value, this); // Map false to a failed promise
  
        if (false === result) result = $.Deferred().reject(); // Make sure we return a promise and that we record failures
  
        return Utils.all([result]).fail(function (errorMessage) {
          if (!(_this3.validationResult instanceof Array)) _this3.validationResult = [];
  
          _this3.validationResult.push({
            assert: constraint,
            errorMessage: 'string' === typeof errorMessage && errorMessage
          });
        });
      },
      // @returns Parsley field computed value that could be overrided or configured in DOM
      getValue: function getValue() {
        var value; // Value could be overriden in DOM or with explicit options
  
        if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val(); // Handle wrong DOM or configurations
  
        if ('undefined' === typeof value || null === value) return '';
        return this._handleWhitespace(value);
      },
      // Reset UI
      reset: function reset() {
        this._resetUI();
  
        return this._trigger('reset');
      },
      // Destroy Parsley instance (+ UI)
      destroy: function destroy() {
        // Field case: emit destroy event to clean UI and then destroy stored instance
        this._destroyUI();
  
        this.$element.removeData('Parsley');
        this.$element.removeData('FieldMultiple');
  
        this._trigger('destroy');
      },
      // Actualize options and rebind constraints
      refresh: function refresh() {
        this._refreshConstraints();
  
        return this;
      },
      _refreshConstraints: function _refreshConstraints() {
        return this.actualizeOptions()._bindConstraints();
      },
      refreshConstraints: function refreshConstraints() {
        Utils.warnOnce("Parsley's refreshConstraints is deprecated. Please use refresh");
        return this.refresh();
      },
  
      /**
      * Add a new constraint to a field
      *
      * @param {String}   name
      * @param {Mixed}    requirements      optional
      * @param {Number}   priority          optional
      * @param {Boolean}  isDomConstraint   optional
      */
      addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
        if (window.Parsley._validatorRegistry.validators[name]) {
          var constraint = new Constraint(this, name, requirements, priority, isDomConstraint); // if constraint already exist, delete it and push new version
  
          if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
          this.constraints.push(constraint);
          this.constraintsByName[constraint.name] = constraint;
        }
  
        return this;
      },
      // Remove a constraint
      removeConstraint: function removeConstraint(name) {
        for (var i = 0; i < this.constraints.length; i++) {
          if (name === this.constraints[i].name) {
            this.constraints.splice(i, 1);
            break;
          }
        }
  
        delete this.constraintsByName[name];
        return this;
      },
      // Update a constraint (Remove + re-add)
      updateConstraint: function updateConstraint(name, parameters, priority) {
        return this.removeConstraint(name).addConstraint(name, parameters, priority);
      },
      // # Internals
      // Internal only.
      // Bind constraints from config + options + DOM
      _bindConstraints: function _bindConstraints() {
        var constraints = [];
        var constraintsByName = {}; // clean all existing DOM constraints to only keep javascript user constraints
  
        for (var i = 0; i < this.constraints.length; i++) {
          if (false === this.constraints[i].isDomConstraint) {
            constraints.push(this.constraints[i]);
            constraintsByName[this.constraints[i].name] = this.constraints[i];
          }
        }
  
        this.constraints = constraints;
        this.constraintsByName = constraintsByName; // then re-add Parsley DOM-API constraints
  
        for (var name in this.options) {
          this.addConstraint(name, this.options[name], undefined, true);
        } // finally, bind special HTML5 constraints
  
  
        return this._bindHtml5Constraints();
      },
      // Internal only.
      // Bind specific HTML5 constraints to be HTML5 compliant
      _bindHtml5Constraints: function _bindHtml5Constraints() {
        // html5 required
        if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true); // html5 pattern
  
        if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true); // range
  
        var min = this.element.getAttribute('min');
        var max = this.element.getAttribute('max');
        if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true); // HTML5 min
        else if (null !== min) this.addConstraint('min', min, undefined, true); // HTML5 max
          else if (null !== max) this.addConstraint('max', max, undefined, true); // length
  
        if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true); // HTML5 minlength
        else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true); // HTML5 maxlength
          else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true); // html5 types
  
        var type = Utils.getType(this.element); // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
  
        if ('number' === type) {
          return this.addConstraint('type', ['number', {
            step: this.element.getAttribute('step') || '1',
            base: min || this.element.getAttribute('value')
          }], undefined, true); // Regular other HTML5 supported types
        } else if (/^(email|url|range|date)$/i.test(type)) {
          return this.addConstraint('type', type, undefined, true);
        }
  
        return this;
      },
      // Internal only.
      // Field is required if have required constraint without `false` value
      _isRequired: function _isRequired() {
        if ('undefined' === typeof this.constraintsByName.required) return false;
        return false !== this.constraintsByName.required.requirements;
      },
      // Internal only.
      // Shortcut to trigger an event
      _trigger: function _trigger(eventName) {
        return this.trigger('field:' + eventName);
      },
      // Internal only
      // Handles whitespace in a value
      // Use `data-parsley-whitespace="squish"` to auto squish input value
      // Use `data-parsley-whitespace="trim"` to auto trim input value
      _handleWhitespace: function _handleWhitespace(value) {
        if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
        if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
        if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
        return value;
      },
      _isDateInput: function _isDateInput() {
        var c = this.constraintsByName.type;
        return c && c.requirements === 'date';
      },
      // Internal only.
      // Returns the constraints, grouped by descending priority.
      // The result is thus an array of arrays of constraints.
      _getGroupedConstraints: function _getGroupedConstraints() {
        if (false === this.options.priorityEnabled) return [this.constraints];
        var groupedConstraints = [];
        var index = {}; // Create array unique of priorities
  
        for (var i = 0; i < this.constraints.length; i++) {
          var p = this.constraints[i].priority;
          if (!index[p]) groupedConstraints.push(index[p] = []);
          index[p].push(this.constraints[i]);
        } // Sort them by priority DESC
  
  
        groupedConstraints.sort(function (a, b) {
          return b[0].priority - a[0].priority;
        });
        return groupedConstraints;
      }
    };
  
    var Multiple = function Multiple() {
      this.__class__ = 'FieldMultiple';
    };
  
    Multiple.prototype = {
      // Add new `$element` sibling for multiple field
      addElement: function addElement($element) {
        this.$elements.push($element);
        return this;
      },
      // See `Field._refreshConstraints()`
      _refreshConstraints: function _refreshConstraints() {
        var fieldConstraints;
        this.constraints = []; // Select multiple special treatment
  
        if (this.element.nodeName === 'SELECT') {
          this.actualizeOptions()._bindConstraints();
  
          return this;
        } // Gather all constraints for each input in the multiple group
  
  
        for (var i = 0; i < this.$elements.length; i++) {
          // Check if element have not been dynamically removed since last binding
          if (!$('html').has(this.$elements[i]).length) {
            this.$elements.splice(i, 1);
            continue;
          }
  
          fieldConstraints = this.$elements[i].data('FieldMultiple')._refreshConstraints().constraints;
  
          for (var j = 0; j < fieldConstraints.length; j++) {
            this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
          }
        }
  
        return this;
      },
      // See `Field.getValue()`
      getValue: function getValue() {
        // Value could be overriden in DOM
        if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value; // Radio input case
  
        if (this.element.nodeName === 'INPUT') {
          var type = Utils.getType(this.element);
          if (type === 'radio') return this._findRelated().filter(':checked').val() || ''; // checkbox input case
  
          if (type === 'checkbox') {
            var values = [];
  
            this._findRelated().filter(':checked').each(function () {
              values.push($(this).val());
            });
  
            return values;
          }
        } // Select multiple case
  
  
        if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return []; // Default case that should never happen
  
        return this.$element.val();
      },
      _init: function _init() {
        this.$elements = [this.$element];
        return this;
      }
    };
  
    var Factory = function Factory(element, options, parsleyFormInstance) {
      this.element = element;
      this.$element = $(element); // If the element has already been bound, returns its saved Parsley instance
  
      var savedparsleyFormInstance = this.$element.data('Parsley');
  
      if (savedparsleyFormInstance) {
        // If the saved instance has been bound without a Form parent and there is one given in this call, add it
        if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
          savedparsleyFormInstance.parent = parsleyFormInstance;
  
          savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
        }
  
        if ('object' === _typeof(options)) {
          _extends(savedparsleyFormInstance.options, options);
        }
  
        return savedparsleyFormInstance;
      } // Parsley must be instantiated with a DOM element or jQuery $element
  
  
      if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
      if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a Form instance');
      this.parent = parsleyFormInstance || window.Parsley;
      return this.init(options);
    };
  
    Factory.prototype = {
      init: function init(options) {
        this.__class__ = 'Parsley';
        this.__version__ = '2.9.2';
        this.__id__ = Utils.generateID(); // Pre-compute options
  
        this._resetOptions(options); // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
  
  
        if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm'); // Every other element is bound as a `Field` or `FieldMultiple`
  
        return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
      },
      isMultiple: function isMultiple() {
        var type = Utils.getType(this.element);
        return type === 'radio' || type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple');
      },
      // Multiples fields are a real nightmare :(
      // Maybe some refactoring would be appreciated here...
      handleMultiple: function handleMultiple() {
        var _this = this;
  
        var name;
        var parsleyMultipleInstance; // Handle multiple name
  
        this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id'); // Special select multiple input
  
        if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
          this.options.multiple = this.options.multiple || this.__id__;
          return this.bind('parsleyFieldMultiple'); // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
        } else if (!this.options.multiple) {
          Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
          return this;
        } // Remove special chars
  
  
        this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, ''); // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
  
        if (name) {
          $('input[name="' + name + '"]').each(function (i, input) {
            var type = Utils.getType(input);
            if (type === 'radio' || type === 'checkbox') input.setAttribute(_this.options.namespace + 'multiple', _this.options.multiple);
          });
        } // Check here if we don't already have a related multiple instance saved
  
  
        var $previouslyRelated = this._findRelated();
  
        for (var i = 0; i < $previouslyRelated.length; i++) {
          parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
  
          if ('undefined' !== typeof parsleyMultipleInstance) {
            if (!this.$element.data('FieldMultiple')) {
              parsleyMultipleInstance.addElement(this.$element);
            }
  
            break;
          }
        } // Create a secret Field instance for every multiple field. It will be stored in `data('FieldMultiple')`
        // And will be useful later to access classic `Field` stuff while being in a `FieldMultiple` instance
  
  
        this.bind('parsleyField', true);
        return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
      },
      // Return proper `Form`, `Field` or `FieldMultiple`
      bind: function bind(type, doNotStore) {
        var parsleyInstance;
  
        switch (type) {
          case 'parsleyForm':
            parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
            break;
  
          case 'parsleyField':
            parsleyInstance = $.extend(new Field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
            break;
  
          case 'parsleyFieldMultiple':
            parsleyInstance = $.extend(new Field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
            break;
  
          default:
            throw new Error(type + 'is not a supported Parsley type');
        }
  
        if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
  
        if ('undefined' !== typeof doNotStore) {
          this.$element.data('FieldMultiple', parsleyInstance);
          return parsleyInstance;
        } // Store the freshly bound instance in a DOM element for later access using jQuery `data()`
  
  
        this.$element.data('Parsley', parsleyInstance); // Tell the world we have a new Form or Field instance!
  
        parsleyInstance._actualizeTriggers();
  
        parsleyInstance._trigger('init');
  
        return parsleyInstance;
      }
    };
  
    var vernums = $.fn.jquery.split('.');
  
    if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
      throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
    }
  
    if (!vernums.forEach) {
      Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
    } // Inherit `on`, `off` & `trigger` to Parsley:
  
  
    var Parsley = _extends(new Base(), {
      element: document,
      $element: $(document),
      actualizeOptions: null,
      _resetOptions: null,
      Factory: Factory,
      version: '2.9.2'
    }); // Supplement Field and Form with Base
    // This way, the constructors will have access to those methods
  
  
    _extends(Field.prototype, UI.Field, Base.prototype);
  
    _extends(Form.prototype, UI.Form, Base.prototype); // Inherit actualizeOptions and _resetOptions:
  
  
    _extends(Factory.prototype, Base.prototype); // ### jQuery API
    // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
  
  
    $.fn.parsley = $.fn.psly = function (options) {
      if (this.length > 1) {
        var instances = [];
        this.each(function () {
          instances.push($(this).parsley(options));
        });
        return instances;
      } // Return undefined if applied to non existing DOM element
  
  
      if (this.length == 0) {
        return;
      }
  
      return new Factory(this[0], options);
    }; // ### Field and Form extension
    // Ensure the extension is now defined if it wasn't previously
  
  
    if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {}; // ### Parsley config
    // Inherit from ParsleyDefault, and copy over any existing values
  
    Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig);
    window.ParsleyConfig = Parsley.options; // Old way of accessing global options
    // ### Globals
  
    window.Parsley = window.psly = Parsley;
    Parsley.Utils = Utils;
    window.ParsleyUtils = {};
    $.each(Utils, function (key, value) {
      if ('function' === typeof value) {
        window.ParsleyUtils[key] = function () {
          Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
          return Utils[key].apply(Utils, arguments);
        };
      }
    }); // ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
  
    var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
    window.ParsleyValidator = {};
    $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator hasValidator'.split(' '), function (i, method) {
      window.Parsley[method] = function () {
        return registry[method].apply(registry, arguments);
      };
  
      window.ParsleyValidator[method] = function () {
        var _window$Parsley;
  
        Utils.warnOnce("Accessing the method '".concat(method, "' through Validator is deprecated. Simply call 'window.Parsley.").concat(method, "(...)'"));
        return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
      };
    }); // ### UI
    // Deprecated global object
  
    window.Parsley.UI = UI;
    window.ParsleyUI = {
      removeError: function removeError(instance, name, doNotUpdateClass) {
        var updateClass = true !== doNotUpdateClass;
        Utils.warnOnce("Accessing UI is deprecated. Call 'removeError' on the instance directly. Please comment in issue 1073 as to your need to call this method.");
        return instance.removeError(name, {
          updateClass: updateClass
        });
      },
      getErrorsMessages: function getErrorsMessages(instance) {
        Utils.warnOnce("Accessing UI is deprecated. Call 'getErrorsMessages' on the instance directly.");
        return instance.getErrorsMessages();
      }
    };
    $.each('addError updateError'.split(' '), function (i, method) {
      window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
        var updateClass = true !== doNotUpdateClass;
        Utils.warnOnce("Accessing UI is deprecated. Call '".concat(method, "' on the instance directly. Please comment in issue 1073 as to your need to call this method."));
        return instance[method](name, {
          message: message,
          assert: assert,
          updateClass: updateClass
        });
      };
    }); // ### PARSLEY auto-binding
    // Prevent it by setting `ParsleyConfig.autoBind` to `false`
  
    if (false !== window.ParsleyConfig.autoBind) {
      $(function () {
        // Works only on `data-parsley-validate`.
        if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
      });
    }
  
    var o = $({});
  
    var deprecated = function deprecated() {
      Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
    }; // Returns an event handler that calls `fn` with the arguments it expects
  
  
    function adapt(fn, context) {
      // Store to allow unbinding
      if (!fn.parsleyAdaptedCallback) {
        fn.parsleyAdaptedCallback = function () {
          var args = Array.prototype.slice.call(arguments, 0);
          args.unshift(this);
          fn.apply(context || o, args);
        };
      }
  
      return fn.parsleyAdaptedCallback;
    }
  
    var eventPrefix = 'parsley:'; // Converts 'parsley:form:validate' into 'form:validate'
  
    function eventName(name) {
      if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
      return name;
    } // $.listen is deprecated. Use Parsley.on instead.
  
  
    $.listen = function (name, callback) {
      var context;
      deprecated();
  
      if ('object' === _typeof(arguments[1]) && 'function' === typeof arguments[2]) {
        context = arguments[1];
        callback = arguments[2];
      }
  
      if ('function' !== typeof callback) throw new Error('Wrong parameters');
      window.Parsley.on(eventName(name), adapt(callback, context));
    };
  
    $.listenTo = function (instance, name, fn) {
      deprecated();
      if (!(instance instanceof Field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
      if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
      instance.on(eventName(name), adapt(fn));
    };
  
    $.unsubscribe = function (name, fn) {
      deprecated();
      if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
      window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
    };
  
    $.unsubscribeTo = function (instance, name) {
      deprecated();
      if (!(instance instanceof Field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
      instance.off(eventName(name));
    };
  
    $.unsubscribeAll = function (name) {
      deprecated();
      window.Parsley.off(eventName(name));
      $('form,input,textarea,select').each(function () {
        var instance = $(this).data('Parsley');
  
        if (instance) {
          instance.off(eventName(name));
        }
      });
    }; // $.emit is deprecated. Use jQuery events instead.
  
  
    $.emit = function (name, instance) {
      var _instance;
  
      deprecated();
      var instanceGiven = instance instanceof Field || instance instanceof Form;
      var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
      args.unshift(eventName(name));
  
      if (!instanceGiven) {
        instance = window.Parsley;
      }
  
      (_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
    };
  
    $.extend(true, Parsley, {
      asyncValidators: {
        'default': {
          fn: function fn(xhr) {
            // By default, only status 2xx are deemed successful.
            // Note: we use status instead of state() because responses with status 200
            // but invalid messages (e.g. an empty body for content type set to JSON) will
            // result in state() === 'rejected'.
            return xhr.status >= 200 && xhr.status < 300;
          },
          url: false
        },
        reverse: {
          fn: function fn(xhr) {
            // If reverse option is set, a failing ajax request is considered successful
            return xhr.status < 200 || xhr.status >= 300;
          },
          url: false
        }
      },
      addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
        Parsley.asyncValidators[name] = {
          fn: fn,
          url: url || false,
          options: options || {}
        };
        return this;
      }
    });
    Parsley.addValidator('remote', {
      requirementType: {
        '': 'string',
        'validator': 'string',
        'reverse': 'boolean',
        'options': 'object'
      },
      validateString: function validateString(value, url, options, instance) {
        var data = {};
        var ajaxOptions;
        var csr;
        var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
        if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
        url = Parsley.asyncValidators[validator].url || url; // Fill current value
  
        if (url.indexOf('{value}') > -1) {
          url = url.replace('{value}', encodeURIComponent(value));
        } else {
          data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value;
        } // Merge options passed in from the function with the ones in the attribute
  
  
        var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options); // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
  
        ajaxOptions = $.extend(true, {}, {
          url: url,
          data: data,
          type: 'GET'
        }, remoteOptions); // Generate store key based on ajax options
  
        instance.trigger('field:ajaxoptions', instance, ajaxOptions);
        csr = $.param(ajaxOptions); // Initialise querry cache
  
        if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {}; // Try to retrieve stored xhr
  
        var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
  
        var handleXhr = function handleXhr() {
          var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
          if (!result) // Map falsy results to rejected promise
            result = $.Deferred().reject();
          return $.when(result);
        };
  
        return xhr.then(handleXhr, handleXhr);
      },
      priority: -1
    });
    Parsley.on('form:submit', function () {
      Parsley._remoteCache = {};
    });
  
    Base.prototype.addAsyncValidator = function () {
      Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
      return Parsley.addAsyncValidator.apply(Parsley, arguments);
    };
  
    // This is included with the Parsley library itself,
    Parsley.addMessages('en', {
      defaultMessage: "This value seems to be invalid.",
      type: {
        email: "This value should be a valid email.",
        url: "This value should be a valid url.",
        number: "This value should be a valid number.",
        integer: "This value should be a valid integer.",
        digits: "This value should be digits.",
        alphanum: "This value should be alphanumeric."
      },
      notblank: "This value should not be blank.",
      required: "This value is required.",
      pattern: "This value seems to be invalid.",
      min: "This value should be greater than or equal to %s.",
      max: "This value should be lower than or equal to %s.",
      range: "This value should be between %s and %s.",
      minlength: "This value is too short. It should have %s characters or more.",
      maxlength: "This value is too long. It should have %s characters or fewer.",
      length: "This value length is invalid. It should be between %s and %s characters long.",
      mincheck: "You must select at least %s choices.",
      maxcheck: "You must select %s choices or fewer.",
      check: "You must select between %s and %s choices.",
      equalto: "This value should be the same.",
      euvatin: "It's not a valid VAT Identification Number."
    });
    Parsley.setLocale('en');
  
    function InputEvent() {
      var _this = this;
  
      var globals = window || global; // Slightly odd way construct our object. This way methods are force bound.
      // Used to test for duplicate library.
  
      _extends(this, {
        // For browsers that do not support isTrusted, assumes event is native.
        isNativeEvent: function isNativeEvent(evt) {
          return evt.originalEvent && evt.originalEvent.isTrusted !== false;
        },
        fakeInputEvent: function fakeInputEvent(evt) {
          if (_this.isNativeEvent(evt)) {
            $(evt.target).trigger('input');
          }
        },
        misbehaves: function misbehaves(evt) {
          if (_this.isNativeEvent(evt)) {
            _this.behavesOk(evt);
  
            $(document).on('change.inputevent', evt.data.selector, _this.fakeInputEvent);
  
            _this.fakeInputEvent(evt);
          }
        },
        behavesOk: function behavesOk(evt) {
          if (_this.isNativeEvent(evt)) {
            $(document) // Simply unbinds the testing handler
            .off('input.inputevent', evt.data.selector, _this.behavesOk).off('change.inputevent', evt.data.selector, _this.misbehaves);
          }
        },
        // Bind the testing handlers
        install: function install() {
          if (globals.inputEventPatched) {
            return;
          }
  
          globals.inputEventPatched = '0.0.3';
  
          for (var _i = 0, _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]']; _i < _arr.length; _i++) {
            var selector = _arr[_i];
            $(document).on('input.inputevent', selector, {
              selector: selector
            }, _this.behavesOk).on('change.inputevent', selector, {
              selector: selector
            }, _this.misbehaves);
          }
        },
        uninstall: function uninstall() {
          delete globals.inputEventPatched;
          $(document).off('.inputevent');
        }
      });
    }
    var inputevent = new InputEvent();
  
    inputevent.install();
  
    return Parsley;
  
  })));
  ;
/* ========================================================================
 * Bootstrap: transition.js v3.3.7
 * http://getbootstrap.com/javascript/#transitions
 * ========================================================================
 * Copyright 2011-2016 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.3.7
 * http://getbootstrap.com/javascript/#collapse
 * ========================================================================
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */

/* Modified by David Storey - December 2016
 * Added data-single-use attribute that allows an accordion to trigger only once
 */

/* jshint latedef: false */

+function ($) {
  'use strict';

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')

    this.usage = (this.$element.attr('data-single-use') === 'true') ? 1 : -1;

    this.transitioning = null

    if (this.options.parent) {
      this.$parent = this.getParent()
    } else {
      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
    }

    if (this.options.toggle) this.toggle()
  }

  Collapse.VERSION  = '3.3.7'

  Collapse.TRANSITION_DURATION = 350

  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 activesData
    var actives = this.$parent && (this.$parent.children('.panel').length ? this.$parent.children('.panel').children('.in, .collapsing') : this.$parent.find('.panel').find('.in, .collapsing') )

    if (actives && actives.length) {
      activesData = actives.data('bs.collapse')
      if (activesData && activesData.transitioning) return
    }

    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    if (actives && actives.length) {
      Plugin.call(actives, 'hide')
      activesData || actives.data('bs.collapse', null)
    }

    var dimension = this.dimension()

    this.$element
      .removeClass('collapse')
      .addClass('collapsing')[dimension](0)
      .attr('aria-expanded', true)

    this.$trigger
      .removeClass('collapsed')
      .attr('aria-expanded', true)

    this.transitioning = 1

    var complete = function () {
      this.$element
        .removeClass('collapsing')
        .addClass('collapse in')[dimension]('')
      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('bsTransitionEnd', $.proxy(complete, this))
      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[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 in')
      .attr('aria-expanded', false)

    this.$trigger
      .addClass('collapsed')
      .attr('aria-expanded', false)

    this.transitioning = 1

    var complete = function () {
      this.transitioning = 0
      this.$element
        .removeClass('collapsing')
        .addClass('collapse')
        .trigger('hidden.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    this.$element
      [dimension](0)
      .one('bsTransitionEnd', $.proxy(complete, this))
      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
  }

  Collapse.prototype.toggle = function () {
      // usage = -1 - Accordion should open/close normally
      // usage =  0 - Accordion should no longer open/close  
      // usage =  1 - Accordion should open/close once then never again

      if (this.usage != 0) {
          this[this.$element.hasClass('in') ? 'hide' : 'show']()
      }

      if (this.usage > 0) {
          this.usage--;
      }
  }

  Collapse.prototype.getParent = function () {
    return $(this.options.parent)
      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
      .each($.proxy(function (i, element) {
        var $element = $(element)
        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
      }, this))
      .end()
  }

  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
    var isOpen = $element.hasClass('in')

    $element.attr('aria-expanded', isOpen)
    $trigger
      .toggleClass('collapsed', !isOpen)
      .attr('aria-expanded', isOpen)
  }

  function getTargetFromTrigger($trigger) {
    var href
    var target = $trigger.attr('data-target')
      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7

    return $(target)
  }


  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  function Plugin(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 && /show|hide/.test(option)) options.toggle = false
      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  var old = $.fn.collapse

  $.fn.collapse             = Plugin
  $.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)

    if (!$this.attr('data-target')) e.preventDefault()

    var $target = getTargetFromTrigger($this)
    var data    = $target.data('bs.collapse')
    var option  = data ? 'toggle' : $this.data()

    Plugin.call($target, option)
  })

}(jQuery);
;
/* ========================================================================
 * Bootstrap: tab.js v3.3.7
 * http://getbootstrap.com/javascript/#tabs
 * ========================================================================
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // TAB CLASS DEFINITION
  // ====================

  var Tab = function (element) {
    // jscs:disable requireDollarBeforejQueryAssignment
    this.element = $(element)
    // jscs:enable requireDollarBeforejQueryAssignment
  }

  Tab.VERSION = '3.3.7'

  Tab.TRANSITION_DURATION = 150

  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')
    var hideEvent = $.Event('hide.bs.tab', {
      relatedTarget: $this[0]
    })
    var showEvent = $.Event('show.bs.tab', {
      relatedTarget: $previous[0]
    })

    $previous.trigger(hideEvent)
    $this.trigger(showEvent)

    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return

    var $target = $(selector)

    this.activate($this.closest('li'), $ul)
    this.activate($target, $target.parent(), function () {
      $previous.trigger({
        type: 'hidden.bs.tab',
        relatedTarget: $this[0]
      })
      $this.trigger({
        type: 'shown.bs.tab',
        relatedTarget: $previous[0]
      })
    })
  }

  Tab.prototype.activate = function (element, container, callback) {
    var $active    = container.find('> .active')
    var transition = callback
      && $.support.transition
      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)

    function next() {
      $active
        .removeClass('active')
        .find('> .dropdown-menu > .active')
          .removeClass('active')
        .end()
        .find('[data-toggle="tab"]')
          .attr('aria-expanded', false)

        container.find('.active')
          .removeClass('active')

      element
        .addClass('active')
        .find('[data-toggle="tab"]')
          .attr('aria-expanded', true)

      if (transition) {
        element[0].offsetWidth // reflow for transition
        element.addClass('in')
      } else {
        element.removeClass('fade')
      }

      if (element.parent('.dropdown-menu').length) {
        element
          .closest('li.dropdown')
            .addClass('active')
          .end()
          .find('[data-toggle="tab"]')
            .attr('aria-expanded', true)
      }

      callback && callback()
    }

    $active.length && transition ?
      $active
        .one('bsTransitionEnd', next)
        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
      next()

    $active.removeClass('in')
  }


  // TAB PLUGIN DEFINITION
  // =====================

  function Plugin(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]()
    })
  }

  var old = $.fn.tab

  $.fn.tab             = Plugin
  $.fn.tab.Constructor = Tab


  // TAB NO CONFLICT
  // ===============

  $.fn.tab.noConflict = function () {
    $.fn.tab = old
    return this
  }


  // TAB DATA-API
  // ============

  var clickHandler = function (e) {
    e.preventDefault()
    Plugin.call($(this), 'show')
  }

  $(document)
    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)

}(jQuery);
;
/* ========================================================================
 * Bootstrap: modal.js v3.3.7
 * http://getbootstrap.com/javascript/#modals
 * ========================================================================
 * Copyright 2011-2016 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.$body               = $(document.body)
    this.$element            = $(element)
    this.$dialog             = this.$element.find('.modal-dialog')
    this.$backdrop           = null
    this.isShown             = null
    this.originalBodyPad     = null
    this.scrollbarWidth      = 0
    this.ignoreBackdropClick = false

    if (this.options.remote) {
      this.$element
        .find('.modal-content')
        .load(this.options.remote, $.proxy(function () {
          this.$element.trigger('loaded.bs.modal')
        }, this))
    }
  }

  Modal.VERSION  = '3.3.7'

  Modal.TRANSITION_DURATION = 300
  Modal.BACKDROP_TRANSITION_DURATION = 150

  Modal.DEFAULTS = {
    backdrop: true,
    keyboard: true,
    show: true
  }

  Modal.prototype.toggle = function (_relatedTarget) {
    return this.isShown ? this.hide() : this.show(_relatedTarget)
  }

  Modal.prototype.show = function (_relatedTarget) {
    var that = this
    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })

    // Allow us to use scripts tags to not load modal content until the modal is first shown
    if (this.$element.find('script').length) {
        this.$element.find('script').each(function () {
            $(this).replaceWith($(this).html());
            window.EFL.eventDispatcher.dispatch('get-packages')
        });
    }

    this.$element.trigger(e)

    if (this.isShown || e.isDefaultPrevented()) return

    this.isShown = true

    this.checkScrollbar()
    this.setScrollbar()
    this.$body.addClass('modal-open')

    this.escape()
    this.resize()

    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))

    this.$dialog.on('mousedown.dismiss.bs.modal', function () {
      that.$element.one('mouseup.dismiss.bs.modal', function (e) {
        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
      })
    })

    this.backdrop(function () {
      var transition = $.support.transition && that.$element.hasClass('fade')

      if (!that.$element.parent().length) {
        that.$element.appendTo(that.$body) // don't move modals dom position
      }

      that.$element
        .show()
        .scrollTop(0)

      that.adjustDialog()

      if (transition) {
        that.$element[0].offsetWidth // force reflow
      }

      that.$element.addClass('in')

      that.enforceFocus()

      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })

      transition ?
        that.$dialog // wait for modal to slide in
          .one('bsTransitionEnd', function () {
            that.$element.trigger('focus').trigger(e)
          })
          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
        that.$element.trigger('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()
    this.resize()

    $(document).off('focusin.bs.modal')

    this.$element
      .removeClass('in')
      .off('click.dismiss.bs.modal')
      .off('mouseup.dismiss.bs.modal')

    this.$dialog.off('mousedown.dismiss.bs.modal')

    $.support.transition && this.$element.hasClass('fade') ?
      this.$element
        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
      this.hideModal()
  }

  Modal.prototype.enforceFocus = function () {
    $(document)
      .off('focusin.bs.modal') // guard against infinite focus loop
      .on('focusin.bs.modal', $.proxy(function (e) {
        if (document !== e.target &&
            this.$element[0] !== e.target &&
            !this.$element.has(e.target).length) {
          this.$element.trigger('focus')
        }
      }, this))
  }

  Modal.prototype.escape = function () {
    if (this.isShown && this.options.keyboard) {
      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
        e.which == 27 && this.hide()
      }, this))
    } else if (!this.isShown) {
      this.$element.off('keydown.dismiss.bs.modal')
    }
  }

  Modal.prototype.resize = function () {
    if (this.isShown) {
      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
    } else {
      $(window).off('resize.bs.modal')
    }
  }

  Modal.prototype.hideModal = function () {
    var that = this
    this.$element.hide()
    this.backdrop(function () {
      that.$body.removeClass('modal-open')
      that.resetAdjustments()
      that.resetScrollbar()
      that.$element.trigger('hidden.bs.modal')
    })
  }

  Modal.prototype.removeBackdrop = function () {
    this.$backdrop && this.$backdrop.remove()
    this.$backdrop = null
  }

  Modal.prototype.backdrop = function (callback) {
    var that = this
    var animate = this.$element.hasClass('fade') ? 'fade' : ''

    if (this.isShown && this.options.backdrop) {
      var doAnimate = $.support.transition && animate

      this.$backdrop = $(document.createElement('div'))
        .addClass('modal-backdrop ' + animate)
        .appendTo(this.$body)

      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
        if (this.ignoreBackdropClick) {
          this.ignoreBackdropClick = false
          return
        }
        if (e.target !== e.currentTarget) return
        this.options.backdrop == 'static'
          ? this.$element[0].focus()
          : this.hide()
      }, this))

      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow

      this.$backdrop.addClass('in')

      if (!callback) return

      doAnimate ?
        this.$backdrop
          .one('bsTransitionEnd', callback)
          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
        callback()

    } else if (!this.isShown && this.$backdrop) {
      this.$backdrop.removeClass('in')

      var callbackRemove = function () {
        that.removeBackdrop()
        callback && callback()
      }
      $.support.transition && this.$element.hasClass('fade') ?
        this.$backdrop
          .one('bsTransitionEnd', callbackRemove)
          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
        callbackRemove()

    } else if (callback) {
      callback()
    }
  }

  // these following methods are used to handle overflowing modals

  Modal.prototype.handleUpdate = function () {
    this.adjustDialog()
  }

  Modal.prototype.adjustDialog = function () {
    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight

    this.$element.css({
      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
    })
  }

  Modal.prototype.resetAdjustments = function () {
    this.$element.css({
      paddingLeft: '',
      paddingRight: ''
    })
  }

  Modal.prototype.checkScrollbar = function () {
    var fullWindowWidth = window.innerWidth
    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
      var documentElementRect = document.documentElement.getBoundingClientRect()
      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
    }
    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
    this.scrollbarWidth = this.measureScrollbar()
  }

  Modal.prototype.setScrollbar = function () {
    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
    this.originalBodyPad = document.body.style.paddingRight || ''
    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
  }

  Modal.prototype.resetScrollbar = function () {
    this.$body.css('padding-right', this.originalBodyPad)
  }

  Modal.prototype.measureScrollbar = function () { // thx walsh
    var scrollDiv = document.createElement('div')
    scrollDiv.className = 'modal-scrollbar-measure'
    this.$body.append(scrollDiv)
    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
    this.$body[0].removeChild(scrollDiv)
    return scrollbarWidth
  }


  // MODAL PLUGIN DEFINITION
  // =======================

  function Plugin(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)
    })
  }

  var old = $.fn.modal

  $.fn.modal             = Plugin
  $.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.one('show.bs.modal', function (showEvent) {
      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
      $target.one('hidden.bs.modal', function () {
        $this.is(':visible') && $this.trigger('focus')
      })
    })
    Plugin.call($target, option, this)
  })

}(jQuery);
;
/*
* jquery-match-height 0.7.0 by @liabru
* http://brm.io/jquery-match-height/
* License MIT
*/
!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):t(jQuery)}(function(t){var e=-1,o=-1,i=function(t){return parseFloat(t)||0},a=function(e){var o=1,a=t(e),n=null,r=[];return a.each(function(){var e=t(this),a=e.offset().top-i(e.css("margin-top")),s=r.length>0?r[r.length-1]:null;null===s?r.push(e):Math.floor(Math.abs(n-a))<=o?r[r.length-1]=s.add(e):r.push(e),n=a}),r},n=function(e){var o={
byRow:!0,property:"height",target:null,remove:!1};return"object"==typeof e?t.extend(o,e):("boolean"==typeof e?o.byRow=e:"remove"===e&&(o.remove=!0),o)},r=t.fn.matchHeight=function(e){var o=n(e);if(o.remove){var i=this;return this.css(o.property,""),t.each(r._groups,function(t,e){e.elements=e.elements.not(i)}),this}return this.length<=1&&!o.target?this:(r._groups.push({elements:this,options:o}),r._apply(this,o),this)};r.version="0.7.0",r._groups=[],r._throttle=80,r._maintainScroll=!1,r._beforeUpdate=null,
r._afterUpdate=null,r._rows=a,r._parse=i,r._parseOptions=n,r._apply=function(e,o){var s=n(o),h=t(e),l=[h],c=t(window).scrollTop(),p=t("html").outerHeight(!0),d=h.parents().filter(":hidden");return d.each(function(){var e=t(this);e.data("style-cache",e.attr("style"))}),d.css("display","block"),s.byRow&&!s.target&&(h.each(function(){var e=t(this),o=e.css("display");"inline-block"!==o&&"flex"!==o&&"inline-flex"!==o&&(o="block"),e.data("style-cache",e.attr("style")),e.css({display:o,"padding-top":"0",
"padding-bottom":"0","margin-top":"0","margin-bottom":"0","border-top-width":"0","border-bottom-width":"0",height:"100px",overflow:"hidden"})}),l=a(h),h.each(function(){var e=t(this);e.attr("style",e.data("style-cache")||"")})),t.each(l,function(e,o){var a=t(o),n=0;if(s.target)n=s.target.outerHeight(!1);else{if(s.byRow&&a.length<=1)return void a.css(s.property,"");a.each(function(){var e=t(this),o=e.attr("style"),i=e.css("display");"inline-block"!==i&&"flex"!==i&&"inline-flex"!==i&&(i="block");var a={
display:i};a[s.property]="",e.css(a),e.outerHeight(!1)>n&&(n=e.outerHeight(!1)),o?e.attr("style",o):e.css("display","")})}a.each(function(){var e=t(this),o=0;s.target&&e.is(s.target)||("border-box"!==e.css("box-sizing")&&(o+=i(e.css("border-top-width"))+i(e.css("border-bottom-width")),o+=i(e.css("padding-top"))+i(e.css("padding-bottom"))),e.css(s.property,n-o+"px"))})}),d.each(function(){var e=t(this);e.attr("style",e.data("style-cache")||null)}),r._maintainScroll&&t(window).scrollTop(c/p*t("html").outerHeight(!0)),
this},r._applyDataApi=function(){var e={};t("[data-match-height], [data-mh]").each(function(){var o=t(this),i=o.attr("data-mh")||o.attr("data-match-height");i in e?e[i]=e[i].add(o):e[i]=o}),t.each(e,function(){this.matchHeight(!0)})};var s=function(e){r._beforeUpdate&&r._beforeUpdate(e,r._groups),t.each(r._groups,function(){r._apply(this.elements,this.options)}),r._afterUpdate&&r._afterUpdate(e,r._groups)};r._update=function(i,a){if(a&&"resize"===a.type){var n=t(window).width();if(n===e)return;e=n;
}i?-1===o&&(o=setTimeout(function(){s(a),o=-1},r._throttle)):s(a)},t(r._applyDataApi),t(window).bind("load",function(t){r._update(!1,t)}),t(window).bind("resize orientationchange",function(t){r._update(!0,t)})});;
/* HTML5 Placeholder jQuery Plugin - v2.3.1
 * Copyright (c)2015 Mathias Bynens
 * 2015-12-16
 */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof module&&module.exports?require("jquery"):jQuery)}(function(a){function b(b){var c={},d=/^jQuery\d+$/;return a.each(b.attributes,function(a,b){b.specified&&!d.test(b.name)&&(c[b.name]=b.value)}),c}function c(b,c){var d=this,f=a(this);if(d.value===f.attr(h?"placeholder-x":"placeholder")&&f.hasClass(n.customClass))if(d.value="",f.removeClass(n.customClass),f.data("placeholder-password")){if(f=f.hide().nextAll('input[type="password"]:first').show().attr("id",f.removeAttr("id").data("placeholder-id")),b===!0)return f[0].value=c,c;f.focus()}else d==e()&&d.select()}function d(d){var e,f=this,g=a(this),i=f.id;if(!d||"blur"!==d.type||!g.hasClass(n.customClass))if(""===f.value){if("password"===f.type){if(!g.data("placeholder-textinput")){try{e=g.clone().prop({type:"text"})}catch(j){e=a("<input>").attr(a.extend(b(this),{type:"text"}))}e.removeAttr("name").data({"placeholder-enabled":!0,"placeholder-password":g,"placeholder-id":i}).bind("focus.placeholder",c),g.data({"placeholder-textinput":e,"placeholder-id":i}).before(e)}f.value="",g=g.removeAttr("id").hide().prevAll('input[type="text"]:first').attr("id",g.data("placeholder-id")).show()}else{var k=g.data("placeholder-password");k&&(k[0].value="",g.attr("id",g.data("placeholder-id")).show().nextAll('input[type="password"]:last').hide().removeAttr("id"))}g.addClass(n.customClass),g[0].value=g.attr(h?"placeholder-x":"placeholder")}else g.removeClass(n.customClass)}function e(){try{return document.activeElement}catch(a){}}var f,g,h=!1,i="[object OperaMini]"===Object.prototype.toString.call(window.operamini),j="placeholder"in document.createElement("input")&&!i&&!h,k="placeholder"in document.createElement("textarea")&&!i&&!h,l=a.valHooks,m=a.propHooks,n={};j&&k?(g=a.fn.placeholder=function(){return this},g.input=!0,g.textarea=!0):(g=a.fn.placeholder=function(b){var e={customClass:"placeholder"};return n=a.extend({},e,b),this.filter((j?"textarea":":input")+"["+(h?"placeholder-x":"placeholder")+"]").not("."+n.customClass).not(":radio, :checkbox, [type=hidden]").bind({"focus.placeholder":c,"blur.placeholder":d}).data("placeholder-enabled",!0).trigger("blur.placeholder")},g.input=j,g.textarea=k,f={get:function(b){var c=a(b),d=c.data("placeholder-password");return d?d[0].value:c.data("placeholder-enabled")&&c.hasClass(n.customClass)?"":b.value},set:function(b,f){var g,h,i=a(b);return""!==f&&(g=i.data("placeholder-textinput"),h=i.data("placeholder-password"),g?(c.call(g[0],!0,f)||(b.value=f),g[0].value=f):h&&(c.call(b,!0,f)||(h[0].value=f),b.value=f)),i.data("placeholder-enabled")?(""===f?(b.value=f,b!=e()&&d.call(b)):(i.hasClass(n.customClass)&&c.call(b),b.value=f),i):(b.value=f,i)}},j||(l.input=f,m.value=f),k||(l.textarea=f,m.value=f),a(function(){a(document).delegate("form","submit.placeholder",function(){var b=a("."+n.customClass,this).each(function(){c.call(this,!0,"")});setTimeout(function(){b.each(d)},10)})}),a(window).bind("beforeunload.placeholder",function(){var b=!0;try{"javascript:void(0)"===document.activeElement.toString()&&(b=!1)}catch(c){}b&&a("."+n.customClass).each(function(){this.value=""})}))});;
/*!
 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/)
 * Copyright (c) 2016 Edson Hilios
 * 
 * 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(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";function b(a){if(a instanceof Date)return a;if(String(a).match(g))return String(a).match(/^[0-9]*$/)&&(a=Number(a)),String(a).match(/\-/)&&(a=String(a).replace(/\-/g,"/")),new Date(a);throw new Error("Couldn't cast `"+a+"` to a date object.")}function c(a){var b=a.toString().replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1");return new RegExp(b)}function d(a){return function(b){var d=b.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);if(d)for(var f=0,g=d.length;f<g;++f){var h=d[f].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/),j=c(h[0]),k=h[1]||"",l=h[3]||"",m=null;h=h[2],i.hasOwnProperty(h)&&(m=i[h],m=Number(a[m])),null!==m&&("!"===k&&(m=e(l,m)),""===k&&m<10&&(m="0"+m.toString()),b=b.replace(j,m.toString()))}return b=b.replace(/%%/,"%")}}function e(a,b){var c="s",d="";return a&&(a=a.replace(/(:|;|\s)/gi,"").split(/\,/),1===a.length?c=a[0]:(d=a[0],c=a[1])),Math.abs(b)>1?c:d}var f=[],g=[],h={precision:100,elapse:!1,defer:!1};g.push(/^[0-9]*$/.source),g.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),g.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),g=new RegExp(g.join("|"));var i={Y:"years",m:"months",n:"daysToMonth",d:"daysToWeek",w:"weeks",W:"weeksToMonth",H:"hours",M:"minutes",S:"seconds",D:"totalDays",I:"totalHours",N:"totalMinutes",T:"totalSeconds"},j=function(b,c,d){this.el=b,this.$el=a(b),this.interval=null,this.offset={},this.options=a.extend({},h),this.instanceNumber=f.length,f.push(this),this.$el.data("countdown-instance",this.instanceNumber),d&&("function"==typeof d?(this.$el.on("update.countdown",d),this.$el.on("stoped.countdown",d),this.$el.on("finish.countdown",d)):this.options=a.extend({},h,d)),this.setFinalDate(c),this.options.defer===!1&&this.start()};a.extend(j.prototype,{start:function(){null!==this.interval&&clearInterval(this.interval);var a=this;this.update(),this.interval=setInterval(function(){a.update.call(a)},this.options.precision)},stop:function(){clearInterval(this.interval),this.interval=null,this.dispatchEvent("stoped")},toggle:function(){this.interval?this.stop():this.start()},pause:function(){this.stop()},resume:function(){this.start()},remove:function(){this.stop.call(this),f[this.instanceNumber]=null,delete this.$el.data().countdownInstance},setFinalDate:function(a){this.finalDate=b(a)},update:function(){if(0===this.$el.closest("html").length)return void this.remove();var b,c=void 0!==a._data(this.el,"events"),d=new Date;b=this.finalDate.getTime()-d.getTime(),b=Math.ceil(b/1e3),b=!this.options.elapse&&b<0?0:Math.abs(b),this.totalSecsLeft!==b&&c&&(this.totalSecsLeft=b,this.elapsed=d>=this.finalDate,this.offset={seconds:this.totalSecsLeft%60,minutes:Math.floor(this.totalSecsLeft/60)%60,hours:Math.floor(this.totalSecsLeft/60/60)%24,days:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToWeek:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToMonth:Math.floor(this.totalSecsLeft/60/60/24%30.4368),weeks:Math.floor(this.totalSecsLeft/60/60/24/7),weeksToMonth:Math.floor(this.totalSecsLeft/60/60/24/7)%4,months:Math.floor(this.totalSecsLeft/60/60/24/30.4368),years:Math.abs(this.finalDate.getFullYear()-d.getFullYear()),totalDays:Math.floor(this.totalSecsLeft/60/60/24),totalHours:Math.floor(this.totalSecsLeft/60/60),totalMinutes:Math.floor(this.totalSecsLeft/60),totalSeconds:this.totalSecsLeft},this.options.elapse||0!==this.totalSecsLeft?this.dispatchEvent("update"):(this.stop(),this.dispatchEvent("finish")))},dispatchEvent:function(b){var c=a.Event(b+".countdown");c.finalDate=this.finalDate,c.elapsed=this.elapsed,c.offset=a.extend({},this.offset),c.strftime=d(this.offset),this.$el.trigger(c)}}),a.fn.countdown=function(){var b=Array.prototype.slice.call(arguments,0);return this.each(function(){var c=a(this).data("countdown-instance");if(void 0!==c){var d=f[c],e=b[0];j.prototype.hasOwnProperty(e)?d[e].apply(d,b.slice(1)):null===String(e).match(/^[$A-Z_][0-9A-Z_$]*$/i)?(d.setFinalDate.call(d,e),d.start()):a.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi,e))}else new j(this,b[0],b[1])})}});;
/*!
 * jQuery Cookie Plugin v1.4.1
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2006, 2014 Klaus Hartl
 * Released under the MIT license
 */
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD (Register as an anonymous module)
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node/CommonJS
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($) {

    var pluses = /\+/g;

    function encode(s) {
        return config.raw ? s : encodeURIComponent(s);
    }

    function decode(s) {
        return config.raw ? s : decodeURIComponent(s);
    }

    function stringifyCookieValue(value) {
        return encode(config.json ? JSON.stringify(value) : String(value));
    }

    function parseCookieValue(s) {
        if (s.indexOf('"') === 0) {
            // This is a quoted cookie as according to RFC2068, unescape...
            s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
        }

        try {
            // Replace server-side written pluses with spaces.
            // If we can't decode the cookie, ignore it, it's unusable.
            // If we can't parse the cookie, ignore it, it's unusable.
            s = decodeURIComponent(s.replace(pluses, ' '));
            return config.json ? JSON.parse(s) : s;
        } catch (e) { }
    }

    function read(s, converter) {
        var value = config.raw ? s : parseCookieValue(s);
        return $.isFunction(converter) ? converter(value) : value;
    }

    var config = $.cookie = function (key, value, options) {

        // Write

        if (arguments.length > 1 && !$.isFunction(value)) {
            options = $.extend({}, config.defaults, options);

            if (typeof options.expires === 'number') {
                var days = options.expires, t = options.expires = new Date();
                t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
            }

            return (document.cookie = [
				encode(key), '=', stringifyCookieValue(value),
				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
				options.path ? '; path=' + options.path : '',
				options.domain ? '; domain=' + options.domain : '',
				options.secure ? '; secure' : ''
            ].join(''));
        }

        // Read

        var result = key ? undefined : {},
			// To prevent the for loop in the first place assign an empty array
			// in case there are no cookies at all. Also prevents odd result when
			// calling $.cookie().
			cookies = document.cookie ? document.cookie.split('; ') : [],
			i = 0,
			l = cookies.length;

        for (; i < l; i++) {
            var parts = cookies[i].split('='),
				name = decode(parts.shift()),
				cookie = parts.join('=');

            if (key === name) {
                // If second argument (value) is a function it's a converter...
                result = read(cookie, value);
                break;
            }

            // Prevent storing a cookie that we couldn't decode.
            if (!key && (cookie = read(cookie)) !== undefined) {
                result[name] = cookie;
            }
        }

        return result;
    };

    config.defaults = {};

    $.removeCookie = function (key, options) {
        // Must not alter options, thus extending a fresh object...
        $.cookie(key, '', $.extend({}, options, { expires: -1 }));
        return !$.cookie(key);
    };

}));
;
/*!
 * Fotorama 4.6.4 | http://fotorama.io/license/
 */
fotoramaVersion = '4.6.4';
(function (window, document, location, $, undefined) {
    "use strict";
    var _fotoramaClass = 'fotorama',
        _fullscreenClass = 'fullscreen',

        wrapClass = _fotoramaClass + '__wrap',
        wrapCss2Class = wrapClass + '--css2',
        wrapCss3Class = wrapClass + '--css3',
        wrapVideoClass = wrapClass + '--video',
        wrapFadeClass = wrapClass + '--fade',
        wrapSlideClass = wrapClass + '--slide',
        wrapNoControlsClass = wrapClass + '--no-controls',
        wrapNoShadowsClass = wrapClass + '--no-shadows',
        wrapPanYClass = wrapClass + '--pan-y',
        wrapRtlClass = wrapClass + '--rtl',
        wrapOnlyActiveClass = wrapClass + '--only-active',
        wrapNoCaptionsClass = wrapClass + '--no-captions',
        wrapToggleArrowsClass = wrapClass + '--toggle-arrows',

        stageClass = _fotoramaClass + '__stage',
        stageFrameClass = stageClass + '__frame',
        stageFrameVideoClass = stageFrameClass + '--video',
        stageShaftClass = stageClass + '__shaft',

        grabClass = _fotoramaClass + '__grab',
        pointerClass = _fotoramaClass + '__pointer',

        arrClass = _fotoramaClass + '__arr',
        arrDisabledClass = arrClass + '--disabled',
        arrPrevClass = arrClass + '--prev',
        arrNextClass = arrClass + '--next',
        arrArrClass = arrClass + '__arr',

        navClass = _fotoramaClass + '__nav',
        navWrapClass = navClass + '-wrap',
        navShaftClass = navClass + '__shaft',
        navDotsClass = navClass + '--dots',
        navThumbsClass = navClass + '--thumbs',
        navFrameClass = navClass + '__frame',
        navFrameDotClass = navFrameClass + '--dot',
        navFrameThumbClass = navFrameClass + '--thumb',

        fadeClass = _fotoramaClass + '__fade',
        fadeFrontClass = fadeClass + '-front',
        fadeRearClass = fadeClass + '-rear',

        shadowClass = _fotoramaClass + '__shadow',
        shadowsClass = shadowClass + 's',
        shadowsLeftClass = shadowsClass + '--left',
        shadowsRightClass = shadowsClass + '--right',

        activeClass = _fotoramaClass + '__active',
        selectClass = _fotoramaClass + '__select',

        hiddenClass = _fotoramaClass + '--hidden',

        fullscreenClass = _fotoramaClass + '--fullscreen',
        fullscreenIconClass = _fotoramaClass + '__fullscreen-icon',

        errorClass = _fotoramaClass + '__error',
        loadingClass = _fotoramaClass + '__loading',
        loadedClass = _fotoramaClass + '__loaded',
        loadedFullClass = loadedClass + '--full',
        loadedImgClass = loadedClass + '--img',

        grabbingClass = _fotoramaClass + '__grabbing',

        imgClass = _fotoramaClass + '__img',
        imgFullClass = imgClass + '--full',

        dotClass = _fotoramaClass + '__dot',
        thumbClass = _fotoramaClass + '__thumb',
        thumbBorderClass = thumbClass + '-border',

        htmlClass = _fotoramaClass + '__html',

        videoClass = _fotoramaClass + '__video',
        videoPlayClass = videoClass + '-play',
        videoCloseClass = videoClass + '-close',

        captionClass = _fotoramaClass + '__caption',
        captionWrapClass = _fotoramaClass + '__caption__wrap',

        spinnerClass = _fotoramaClass + '__spinner',

        buttonAttributes = '" tabindex="0" role="button';

    var JQUERY_VERSION = $ && $.fn.jquery.split('.');

    if (!JQUERY_VERSION
        || JQUERY_VERSION[0] < 1
        || (JQUERY_VERSION[0] == 1 && JQUERY_VERSION[1] < 8)) {
        throw 'Fotorama requires jQuery 1.8 or later and will not run without it.';
    }
    // My Underscore :-)
    var _ = {};
    /* Modernizr 2.6.2 (Custom Build) | MIT & BSD
     * Build: http://modernizr.com/download/#-csstransforms3d-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes
     */

    var Modernizr = (function (window, document, undefined) {

        var version = '2.6.2',

            Modernizr = {},

            docElement = document.documentElement,

            mod = 'modernizr',
            modElem = document.createElement(mod),
            mStyle = modElem.style,

            inputElem,

            toString = {}.toString,

            prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),

            omPrefixes = 'Webkit Moz O ms',

            cssomPrefixes = omPrefixes.split(' '),

            domPrefixes = omPrefixes.toLowerCase().split(' '),

            tests = {},
            inputs = {},
            attrs = {},

            classes = [],

            slice = classes.slice,

            featureName,

            injectElementWithStyles = function (rule, callback, nodes, testnames) {

                var style, ret, node, docOverflow,
                    div = document.createElement('div'),
                    body = document.body,
                    fakeBody = body || document.createElement('body');

                if (parseInt(nodes, 10)) {
                    while (nodes--) {
                        node = document.createElement('div');
                        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
                        div.appendChild(node);
                    }
                }

                style = ['&#173;', '<style id="s', mod, '">', rule, '</style>'].join('');
                div.id = mod;
                (body ? div : fakeBody).innerHTML += style;
                fakeBody.appendChild(div);
                if (!body) {
                    fakeBody.style.background = '';
                    fakeBody.style.overflow = 'hidden';
                    docOverflow = docElement.style.overflow;
                    docElement.style.overflow = 'hidden';
                    docElement.appendChild(fakeBody);
                }

                ret = callback(div, rule);
                if (!body) {
                    fakeBody.parentNode.removeChild(fakeBody);
                    docElement.style.overflow = docOverflow;
                } else {
                    div.parentNode.removeChild(div);
                }

                return !!ret;

            },
            _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;

        if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {
            hasOwnProp = function (object, property) {
                return _hasOwnProperty.call(object, property);
            };
        }
        else {
            hasOwnProp = function (object, property) {
                return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
            };
        }


        if (!Function.prototype.bind) {
            Function.prototype.bind = function bind(that) {

                var target = this;

                if (typeof target != "function") {
                    throw new TypeError();
                }

                var args = slice.call(arguments, 1),
                    bound = function () {

                        if (this instanceof bound) {

                            var F = function () {
                            };
                            F.prototype = target.prototype;
                            var self = new F();

                            var result = target.apply(
                                self,
                                args.concat(slice.call(arguments))
                            );
                            if (Object(result) === result) {
                                return result;
                            }
                            return self;

                        } else {

                            return target.apply(
                                that,
                                args.concat(slice.call(arguments))
                            );

                        }

                    };

                return bound;
            };
        }

        function setCss(str) {
            mStyle.cssText = str;
        }

        function setCssAll(str1, str2) {
            return setCss(prefixes.join(str1 + ';') + (str2 || ''));
        }

        function is(obj, type) {
            return typeof obj === type;
        }

        function contains(str, substr) {
            return !!~('' + str).indexOf(substr);
        }

        function testProps(props, prefixed) {
            for (var i in props) {
                var prop = props[i];
                if (!contains(prop, "-") && mStyle[prop] !== undefined) {
                    return prefixed == 'pfx' ? prop : true;
                }
            }
            return false;
        }

        function testDOMProps(props, obj, elem) {
            for (var i in props) {
                var item = obj[props[i]];
                if (item !== undefined) {

                    if (elem === false) return props[i];

                    if (is(item, 'function')) {
                        return item.bind(elem || obj);
                    }

                    return item;
                }
            }
            return false;
        }

        function testPropsAll(prop, prefixed, elem) {

            var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
                props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');

            if (is(prefixed, "string") || is(prefixed, "undefined")) {
                return testProps(props, prefixed);

            } else {
                props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
                return testDOMProps(props, prefixed, elem);
            }
        }

        tests['csstransforms3d'] = function () {

            var ret = !!testPropsAll('perspective');

            // Chrome fails that test, ignore
            //		if (ret && 'webkitPerspective' in docElement.style) {
            //
            //			injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function (node, rule) {
            //				ret = node.offsetLeft === 9 && node.offsetHeight === 3;
            //			});
            //		}
            return ret;
        };

        for (var feature in tests) {
            if (hasOwnProp(tests, feature)) {
                featureName = feature.toLowerCase();
                Modernizr[featureName] = tests[feature]();

                classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
            }
        }

        Modernizr.addTest = function (feature, test) {
            if (typeof feature == 'object') {
                for (var key in feature) {
                    if (hasOwnProp(feature, key)) {
                        Modernizr.addTest(key, feature[key]);
                    }
                }
            } else {

                feature = feature.toLowerCase();

                if (Modernizr[feature] !== undefined) {
                    return Modernizr;
                }

                test = typeof test == 'function' ? test() : test;

                if (typeof enableClasses !== "undefined" && enableClasses) {
                    docElement.className += ' ' + (test ? '' : 'no-') + feature;
                }
                Modernizr[feature] = test;

            }

            return Modernizr;
        };


        setCss('');
        modElem = inputElem = null;


        Modernizr._version = version;

        Modernizr._prefixes = prefixes;
        Modernizr._domPrefixes = domPrefixes;
        Modernizr._cssomPrefixes = cssomPrefixes;

        Modernizr.testProp = function (prop) {
            return testProps([prop]);
        };

        Modernizr.testAllProps = testPropsAll;

        Modernizr.testStyles = injectElementWithStyles;
        Modernizr.prefixed = function (prop, obj, elem) {
            if (!obj) {
                return testPropsAll(prop, 'pfx');
            } else {
                return testPropsAll(prop, obj, elem);
            }
        };

        return Modernizr;
    })(window, document);
    var fullScreenApi = {
        ok: false,
        is: function () {
            return false;
        },
        request: function () {
        },
        cancel: function () {
        },
        event: '',
        prefix: ''
    },
        browserPrefixes = 'webkit moz o ms khtml'.split(' ');

    // check for native support
    if (typeof document.cancelFullScreen != 'undefined') {
        fullScreenApi.ok = 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.ok = true;
                break;
            }
        }
    }

    // update methods to do something useful
    if (fullScreenApi.ok) {
        fullScreenApi.event = fullScreenApi.prefix + 'fullscreenchange';
        fullScreenApi.is = function () {
            switch (this.prefix) {
                case '':
                    return document.fullScreen;
                case 'webkit':
                    return document.webkitIsFullScreen;
                default:
                    return document[this.prefix + 'FullScreen'];
            }
        };
        fullScreenApi.request = function (el) {
            return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
        };
        fullScreenApi.cancel = function (el) {
            return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
        };
    }
    //fgnass.github.com/spin.js#v1.3.2

    /**
     * Copyright (c) 2011-2013 Felix Gnass
     * Licensed under the MIT license
     */

    var Spinner,
        spinnerDefaults = {
            lines: 12, // The number of lines to draw
            length: 5, // The length of each line
            width: 2, // The line thickness
            radius: 7, // The radius of the inner circle
            corners: 1, // Corner roundness (0..1)
            rotate: 15, // The rotation offset
            color: 'rgba(128, 128, 128, .75)',
            hwaccel: true
        },
        spinnerOverride = {
            top: 'auto',
            left: 'auto',
            className: ''
        };

    (function (root, factory) {

        /* CommonJS */
        //if (typeof exports == 'object')  module.exports = factory()

        /* AMD module */
        //else if (typeof define == 'function' && define.amd) define(factory)

        /* Browser global */
        //else root.Spinner = factory()

        Spinner = factory();
    }
    (this, function () {
        "use strict";

        var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
          , animations = {} /* Animation rules keyed by their name */
          , useCssAnimations /* Whether to use CSS animations or setTimeout */

        /**
         * Utility function to create elements. If no tag name is given,
         * a DIV is created. Optionally properties can be passed.
         */
        function createEl(tag, prop) {
            var el = document.createElement(tag || 'div')
              , n

            for (n in prop) el[n] = prop[n]
            return el
        }

        /**
         * Appends children and returns the parent.
         */
        function ins(parent /* child1, child2, ...*/) {
            for (var i = 1, n = arguments.length; i < n; i++)
                parent.appendChild(arguments[i])

            return parent
        }

        /**
         * Insert a new stylesheet to hold the @keyframe or VML rules.
         */
        var sheet = (function () {
            var el = createEl('style', { type: 'text/css' })
            ins(document.getElementsByTagName('head')[0], el)
            return el.sheet || el.styleSheet
        }())

        /**
         * Creates an opacity keyframe animation rule and returns its name.
         * Since most mobile Webkits have timing issues with animation-delay,
         * we create separate rules for each line/segment.
         */
        function addAnimation(alpha, trail, i, lines) {
            var name = ['opacity', trail, ~~(alpha * 100), i, lines].join('-')
              , start = 0.01 + i / lines * 100
              , z = Math.max(1 - (1 - alpha) / trail * (100 - start), alpha)
              , prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase()
              , pre = prefix && '-' + prefix + '-' || ''

            if (!animations[name]) {
                sheet.insertRule(
                  '@' + pre + 'keyframes ' + name + '{' +
                  '0%{opacity:' + z + '}' +
                  start + '%{opacity:' + alpha + '}' +
                  (start + 0.01) + '%{opacity:1}' +
                  (start + trail) % 100 + '%{opacity:' + alpha + '}' +
                  '100%{opacity:' + z + '}' +
                  '}', sheet.cssRules.length)

                animations[name] = 1
            }

            return name
        }

        /**
         * Tries various vendor prefixes and returns the first supported property.
         */
        function vendor(el, prop) {
            var s = el.style
              , pp
              , i

            prop = prop.charAt(0).toUpperCase() + prop.slice(1)
            for (i = 0; i < prefixes.length; i++) {
                pp = prefixes[i] + prop
                if (s[pp] !== undefined) return pp
            }
            if (s[prop] !== undefined) return prop
        }

        /**
         * Sets multiple style properties at once.
         */
        function css(el, prop) {
            for (var n in prop)
                el.style[vendor(el, n) || n] = prop[n]

            return el
        }

        /**
         * Fills in default values.
         */
        function merge(obj) {
            for (var i = 1; i < arguments.length; i++) {
                var def = arguments[i]
                for (var n in def)
                    if (obj[n] === undefined) obj[n] = def[n]
            }
            return obj
        }

        /**
         * Returns the absolute page-offset of the given element.
         */
        function pos(el) {
            var o = { x: el.offsetLeft, y: el.offsetTop }
            while ((el = el.offsetParent))
                o.x += el.offsetLeft, o.y += el.offsetTop

            return o
        }

        /**
         * Returns the line color from the given string or array.
         */
        function getColor(color, idx) {
            return typeof color == 'string' ? color : color[idx % color.length]
        }

        // Built-in defaults

        var defaults = {
            lines: 12,            // The number of lines to draw
            length: 7,            // The length of each line
            width: 5,             // The line thickness
            radius: 10,           // The radius of the inner circle
            rotate: 0,            // Rotation offset
            corners: 1,           // Roundness (0..1)
            color: '#000',        // #rgb or #rrggbb
            direction: 1,         // 1: clockwise, -1: counterclockwise
            speed: 1,             // Rounds per second
            trail: 100,           // Afterglow percentage
            opacity: 1 / 4,         // Opacity of the lines
            fps: 20,              // Frames per second when using setTimeout()
            zIndex: 2e9,          // Use a high z-index by default
            className: 'spinner', // CSS class to assign to the element
            top: 'auto',          // center vertically
            left: 'auto',         // center horizontally
            position: 'relative'  // element position
        }

        /** The constructor */
        function Spinner(o) {
            if (typeof this == 'undefined') return new Spinner(o)
            this.opts = merge(o || {}, Spinner.defaults, defaults)
        }

        // Global defaults that override the built-ins:
        Spinner.defaults = {}

        merge(Spinner.prototype, {

            /**
             * Adds the spinner to the given target element. If this instance is already
             * spinning, it is automatically removed from its previous target b calling
             * stop() internally.
             */
            spin: function (target) {
                this.stop()

                var self = this
                  , o = self.opts
                  , el = self.el = css(createEl(0, { className: o.className }), { position: o.position, width: 0, zIndex: o.zIndex })
                  , mid = o.radius + o.length + o.width
                  , ep // element position
                  , tp // target position

                if (target) {
                    target.insertBefore(el, target.firstChild || null)
                    tp = pos(target)
                    ep = pos(el)
                    css(el, {
                        left: (o.left == 'auto' ? tp.x - ep.x + (target.offsetWidth >> 1) : parseInt(o.left, 10) + mid) + 'px',
                        top: (o.top == 'auto' ? tp.y - ep.y + (target.offsetHeight >> 1) : parseInt(o.top, 10) + mid) + 'px'
                    })
                }

                el.setAttribute('role', 'progressbar')
                self.lines(el, self.opts)

                if (!useCssAnimations) {
                    // No CSS animation support, use setTimeout() instead
                    var i = 0
                      , start = (o.lines - 1) * (1 - o.direction) / 2
                      , alpha
                      , fps = o.fps
                      , f = fps / o.speed
                      , ostep = (1 - o.opacity) / (f * o.trail / 100)
                      , astep = f / o.lines

                    ; (function anim() {
                        i++;
                        for (var j = 0; j < o.lines; j++) {
                            alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)

                            self.opacity(el, j * o.direction + start, alpha, o)
                        }
                        self.timeout = self.el && setTimeout(anim, ~~(1000 / fps))
                    })()
                }
                return self
            },

            /**
             * Stops and removes the Spinner.
             */
            stop: function () {
                var el = this.el
                if (el) {
                    clearTimeout(this.timeout)
                    if (el.parentNode) el.parentNode.removeChild(el)
                    this.el = undefined
                }
                return this
            },

            /**
             * Internal method that draws the individual lines. Will be overwritten
             * in VML fallback mode below.
             */
            lines: function (el, o) {
                var i = 0
                  , start = (o.lines - 1) * (1 - o.direction) / 2
                  , seg

                function fill(color, shadow) {
                    return css(createEl(), {
                        position: 'absolute',
                        width: (o.length + o.width) + 'px',
                        height: o.width + 'px',
                        background: color,
                        boxShadow: shadow,
                        transformOrigin: 'left',
                        transform: 'rotate(' + ~~(360 / o.lines * i + o.rotate) + 'deg) translate(' + o.radius + 'px' + ',0)',
                        borderRadius: (o.corners * o.width >> 1) + 'px'
                    })
                }

                for (; i < o.lines; i++) {
                    seg = css(createEl(), {
                        position: 'absolute',
                        top: 1 + ~(o.width / 2) + 'px',
                        transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
                        opacity: o.opacity,
                        animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1 / o.speed + 's linear infinite'
                    })

                    if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), { top: 2 + 'px' }))
                    ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)')))
                }
                return el
            },

            /**
             * Internal method that adjusts the opacity of a single line.
             * Will be overwritten in VML fallback mode below.
             */
            opacity: function (el, i, val) {
                if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
            }

        })


        function initVML() {

            /* Utility function to create a VML tag */
            function vml(tag, attr) {
                return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
            }

            // No CSS transforms but VML support, add a CSS rule for VML elements:
            sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')

            Spinner.prototype.lines = function (el, o) {
                var r = o.length + o.width
                  , s = 2 * r

                function grp() {
                    return css(
                      vml('group', {
                          coordsize: s + ' ' + s,
                          coordorigin: -r + ' ' + -r
                      }),
                      { width: s, height: s }
                    )
                }

                var margin = -(o.width + o.length) * 2 + 'px'
                  , g = css(grp(), { position: 'absolute', top: margin, left: margin })
                  , i

                function seg(i, dx, filter) {
                    ins(g,
                      ins(css(grp(), { rotation: 360 / o.lines * i + 'deg', left: ~~dx }),
                        ins(css(vml('roundrect', { arcsize: o.corners }), {
                            width: r,
                            height: o.width,
                            left: o.radius,
                            top: -o.width >> 1,
                            filter: filter
                        }),
                          vml('fill', { color: getColor(o.color, i), opacity: o.opacity }),
                          vml('stroke', { opacity: 0 }) // transparent stroke to fix color bleeding upon opacity change
                        )
                      )
                    )
                }

                if (o.shadow)
                    for (i = 1; i <= o.lines; i++)
                        seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')

                for (i = 1; i <= o.lines; i++) seg(i)
                return ins(el, g)
            }

            Spinner.prototype.opacity = function (el, i, val, o) {
                var c = el.firstChild
                o = o.shadow && o.lines || 0
                if (c && i + o < c.childNodes.length) {
                    c = c.childNodes[i + o]; c = c && c.firstChild; c = c && c.firstChild
                    if (c) c.opacity = val
                }
            }
        }

        var probe = css(createEl('group'), { behavior: 'url(#default#VML)' })

        if (!vendor(probe, 'transform') && probe.adj) initVML()
        else useCssAnimations = vendor(probe, 'animation')

        return Spinner

    }));

    /* Bez v1.0.10-g5ae0136
     * http://github.com/rdallasgray/bez
     *
     * A plugin to convert CSS3 cubic-bezier co-ordinates to jQuery-compatible easing functions
     *
     * With thanks to Nikolay Nemshilov for clarification on the cubic-bezier maths
     * See http://st-on-it.blogspot.com/2011/05/calculating-cubic-bezier-function.html
     *
     * Copyright 2011 Robert Dallas Gray. All rights reserved.
     * Provided under the FreeBSD license: https://github.com/rdallasgray/bez/blob/master/LICENSE.txt
     */
    function bez(coOrdArray) {
        var encodedFuncName = "bez_" + $.makeArray(arguments).join("_").replace(".", "p");
        if (typeof $['easing'][encodedFuncName] !== "function") {
            var polyBez = function (p1, p2) {
                var A = [null, null],
                    B = [null, null],
                    C = [null, null],
                    bezCoOrd = function (t, ax) {
                        C[ax] = 3 * p1[ax];
                        B[ax] = 3 * (p2[ax] - p1[ax]) - C[ax];
                        A[ax] = 1 - C[ax] - B[ax];
                        return t * (C[ax] + t * (B[ax] + t * A[ax]));
                    },
                    xDeriv = function (t) {
                        return C[0] + t * (2 * B[0] + 3 * A[0] * t);
                    },
                    xForT = function (t) {
                        var x = t, i = 0, z;
                        while (++i < 14) {
                            z = bezCoOrd(x, 0) - t;
                            if (Math.abs(z) < 1e-3) break;
                            x -= z / xDeriv(x);
                        }
                        return x;
                    };
                return function (t) {
                    return bezCoOrd(xForT(t), 1);
                }
            };
            $['easing'][encodedFuncName] = function (x, t, b, c, d) {
                return c * polyBez([coOrdArray[0], coOrdArray[1]], [coOrdArray[2], coOrdArray[3]])(t / d) + b;
            }
        }
        return encodedFuncName;
    }
    var $WINDOW = $(window),
        $DOCUMENT = $(document),
        $HTML,
        $BODY,

        QUIRKS_FORCE = location.hash.replace('#', '') === 'quirks',
        TRANSFORMS3D = Modernizr.csstransforms3d,
        CSS3 = TRANSFORMS3D && !QUIRKS_FORCE,
        COMPAT = TRANSFORMS3D || document.compatMode === 'CSS1Compat',
        FULLSCREEN = fullScreenApi.ok,

        MOBILE = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),
        SLOW = !CSS3 || MOBILE,

        MS_POINTER = navigator.msPointerEnabled,

        WHEEL = "onwheel" in document.createElement("div") ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll",

        TOUCH_TIMEOUT = 250,
        TRANSITION_DURATION = 300,

        SCROLL_LOCK_TIMEOUT = 1400,

        AUTOPLAY_INTERVAL = 5000,
        MARGIN = 2,
        THUMB_SIZE = 64,

        WIDTH = 500,
        HEIGHT = 333,

        STAGE_FRAME_KEY = '$stageFrame',
        NAV_DOT_FRAME_KEY = '$navDotFrame',
        NAV_THUMB_FRAME_KEY = '$navThumbFrame',

        AUTO = 'auto',

        BEZIER = bez([.1, 0, .25, 1]),

        MAX_WIDTH = 99999,

        FIFTYFIFTY = '50%',

        OPTIONS = {
            // dimensions
            width: null, // 500 || '100%'
            minwidth: null,
            maxwidth: '100%', // '100%'
            height: null,
            minheight: null,
            maxheight: null,

            ratio: null, // '16/9' || 500/333 || 1.5

            margin: MARGIN,
            glimpse: 0,

            fit: 'contain', // 'cover' || 'scaledown' || 'none'

            position: FIFTYFIFTY,
            thumbposition: FIFTYFIFTY,

            // navigation, thumbs
            nav: 'dots', // 'thumbs' || false
            navposition: 'bottom', // 'top'
            navwidth: null,
            thumbwidth: THUMB_SIZE,
            thumbheight: THUMB_SIZE,
            thumbmargin: MARGIN,
            thumbborderwidth: MARGIN,
            thumbfit: 'cover', // 'contain' || 'scaledown' || 'none'

            allowfullscreen: false, // true || 'native'

            transition: 'slide', // 'crossfade' || 'dissolve'
            clicktransition: null,
            transitionduration: TRANSITION_DURATION,

            captions: true,

            hash: false,
            startindex: 0,

            loop: false,

            autoplay: false,
            stopautoplayontouch: true,

            keyboard: false,

            arrows: true,
            click: true,
            swipe: true,
            trackpad: false,

            enableifsingleframe: false,

            controlsonstart: true,

            shuffle: false,

            direction: 'ltr', // 'rtl'

            shadows: true,
            spinner: null
        },

        KEYBOARD_OPTIONS = {
            left: true,
            right: true,
            down: false,
            up: false,
            space: false,
            home: false,
            end: false
        };
    function noop() { }

    function minMaxLimit(value, min, max) {
        return Math.max(isNaN(min) ? -Infinity : min, Math.min(isNaN(max) ? Infinity : max, value));
    }

    function readTransform(css) {
        return css.match(/ma/) && css.match(/-?\d+(?!d)/g)[css.match(/3d/) ? 12 : 4];
    }

    function readPosition($el) {
        if (CSS3) {
            return +readTransform($el.css('transform'));
        } else {
            return +$el.css('left').replace('px', '');
        }
    }

    function getTranslate(pos/*, _001*/) {
        var obj = {};
        if (CSS3) {
            obj.transform = 'translate3d(' + (pos/* + (_001 ? 0.001 : 0)*/) + 'px,0,0)'; // 0.001 to remove Retina artifacts
        } else {
            obj.left = pos;
        }
        return obj;
    }

    function getDuration(time) {
        return { 'transition-duration': time + 'ms' };
    }

    function unlessNaN(value, alternative) {
        return isNaN(value) ? alternative : value;
    }

    function numberFromMeasure(value, measure) {
        return unlessNaN(+String(value).replace(measure || 'px', ''));
    }

    function numberFromPercent(value) {
        return /%$/.test(value) ? numberFromMeasure(value, '%') : undefined;
    }

    function numberFromWhatever(value, whole) {
        return unlessNaN(numberFromPercent(value) / 100 * whole, numberFromMeasure(value));
    }

    function measureIsValid(value) {
        return (!isNaN(numberFromMeasure(value)) || !isNaN(numberFromMeasure(value, '%'))) && value;
    }

    function getPosByIndex(index, side, margin, baseIndex) {
        ////console.log('getPosByIndex', index, side, margin, baseIndex);
        ////console.log((index - (baseIndex || 0)) * (side + (margin || 0)));

        return (index - (baseIndex || 0)) * (side + (margin || 0));
    }

    function getIndexByPos(pos, side, margin, baseIndex) {
        return -Math.round(pos / (side + (margin || 0)) - (baseIndex || 0));
    }

    function bindTransitionEnd($el) {
        var elData = $el.data();

        if (elData.tEnd) return;

        var el = $el[0],
            transitionEndEvent = {
                WebkitTransition: 'webkitTransitionEnd',
                MozTransition: 'transitionend',
                OTransition: 'oTransitionEnd otransitionend',
                msTransition: 'MSTransitionEnd',
                transition: 'transitionend'
            };
        addEvent(el, transitionEndEvent[Modernizr.prefixed('transition')], function (e) {
            elData.tProp && e.propertyName.match(elData.tProp) && elData.onEndFn();
        });
        elData.tEnd = true;
    }

    function afterTransition($el, property, fn, time) {
        var ok,
            elData = $el.data();

        if (elData) {
            elData.onEndFn = function () {
                if (ok) return;
                ok = true;
                clearTimeout(elData.tT);
                fn();
            };
            elData.tProp = property;

            // Passive call, just in case of fail of native transition-end event
            clearTimeout(elData.tT);
            elData.tT = setTimeout(function () {
                elData.onEndFn();
            }, time * 1.5);

            bindTransitionEnd($el);
        }
    }


    function stop($el, left/*, _001*/) {
        if ($el.length) {
            var elData = $el.data();
            if (CSS3) {
                $el.css(getDuration(0));
                elData.onEndFn = noop;
                clearTimeout(elData.tT);
            } else {
                $el.stop();
            }
            var lockedLeft = getNumber(left, function () {
                return readPosition($el);
            });

            $el.css(getTranslate(lockedLeft/*, _001*/));//.width(); // `.width()` for reflow
            return lockedLeft;
        }
    }

    function getNumber() {
        var number;
        for (var _i = 0, _l = arguments.length; _i < _l; _i++) {
            number = _i ? arguments[_i]() : arguments[_i];
            if (typeof number === 'number') {
                break;
            }
        }

        return number;
    }

    function edgeResistance(pos, edge) {
        return Math.round(pos + ((edge - pos) / 1.5));
    }

    function getProtocol() {
        getProtocol.p = getProtocol.p || (location.protocol === 'https:' ? 'https://' : 'http://');
        return getProtocol.p;
    }

    function parseHref(href) {
        var a = document.createElement('a');
        a.href = href;
        return a;
    }

    function findVideoId(href, forceVideo) {
        if (typeof href !== 'string') return href;
        href = parseHref(href);

        var id,
            type;

        if (href.host.match(/youtube\.com/) && href.search) {
            //.log();
            id = href.search.split('v=')[1];
            if (id) {
                var ampersandPosition = id.indexOf('&');
                if (ampersandPosition !== -1) {
                    id = id.substring(0, ampersandPosition);
                }
                type = 'youtube';
            }
        } else if (href.host.match(/youtube\.com|youtu\.be/)) {
            id = href.pathname.replace(/^\/(embed\/|v\/)?/, '').replace(/\/.*/, '');
            type = 'youtube';
        } else if (href.host.match(/vimeo\.com/)) {
            type = 'vimeo';
            id = href.pathname.replace(/^\/(video\/)?/, '').replace(/\/.*/, '');
        }

        if ((!id || !type) && forceVideo) {
            id = href.href;
            type = 'custom';
        }

        return id ? { id: id, type: type, s: href.search.replace(/^\?/, ''), p: getProtocol() } : false;
    }

    function getVideoThumbs(dataFrame, data, fotorama) {
        var img, thumb, video = dataFrame.video;
        if (video.type === 'youtube') {
            thumb = getProtocol() + 'img.youtube.com/vi/' + video.id + '/default.jpg';
            img = thumb.replace(/\/default.jpg$/, '/hqdefault.jpg');
            dataFrame.thumbsReady = true;
        } else if (video.type === 'vimeo') {
            $.ajax({
                url: getProtocol() + 'vimeo.com/api/v2/video/' + video.id + '.json',
                dataType: 'jsonp',
                success: function (json) {
                    dataFrame.thumbsReady = true;
                    updateData(data, { img: json[0].thumbnail_large, thumb: json[0].thumbnail_small }, dataFrame.i, fotorama);
                }
            });
        } else {
            dataFrame.thumbsReady = true;
        }

        return {
            img: img,
            thumb: thumb
        }
    }

    function updateData(data, _dataFrame, i, fotorama) {
        for (var _i = 0, _l = data.length; _i < _l; _i++) {
            var dataFrame = data[_i];

            if (dataFrame.i === i && dataFrame.thumbsReady) {
                var clear = { videoReady: true };
                clear[STAGE_FRAME_KEY] = clear[NAV_THUMB_FRAME_KEY] = clear[NAV_DOT_FRAME_KEY] = false;

                fotorama.splice(_i, 1, $.extend(
                    {},
                    dataFrame,
                    clear,
                    _dataFrame
                ));

                break;
            }
        }
    }

    function getDataFromHtml($el) {
        var data = [];

        function getDataFromImg($img, imgData, checkVideo) {
            var $child = $img.children('img').eq(0),
                _imgHref = $img.attr('href'),
                _imgSrc = $img.attr('src'),
                _thumbSrc = $child.attr('src'),
                _thumbAlt = $child.attr('alt'),
                _video = imgData.video,
                video = checkVideo ? findVideoId(_imgHref, _video === true) : false;

            if (video) {
                _imgHref = false;
            } else {
                video = _video;
            }

            getDimensions($img, $child, $.extend(imgData, {
                video: video,
                img: imgData.img || _imgHref || _imgSrc || _thumbSrc,
                thumb: imgData.thumb || _thumbSrc || _imgSrc || _imgHref
            }));
        }

        function getDimensions($img, $child, imgData) {
            var separateThumbFLAG = imgData.thumb && imgData.img !== imgData.thumb,
                width = numberFromMeasure(imgData.width || $img.attr('width')),
                height = numberFromMeasure(imgData.height || $img.attr('height'));

            $.extend(imgData, {
                width: width,
                height: height,
                thumbratio: getRatio(imgData.thumbratio || (numberFromMeasure(imgData.thumbwidth || ($child && $child.attr('width')) || separateThumbFLAG || width) / numberFromMeasure(imgData.thumbheight || ($child && $child.attr('height')) || separateThumbFLAG || height)))
            });
        }

        $el.children().each(function () {
            var $this = $(this),
                dataFrame = optionsToLowerCase($.extend($this.data(), { id: $this.attr('id') }));
            if ($this.is('a, img')) {
                getDataFromImg($this, dataFrame, true);
            } else if (!$this.is(':empty')) {
                getDimensions($this, null, $.extend(dataFrame, {
                    html: this,
                    _html: $this.html() // Because of IE
                }));
            } else return;

            data.push(dataFrame);
        });

        return data;
    }

    function isHidden(el) {
        return el.offsetWidth === 0 && el.offsetHeight === 0;
    }

    function isDetached(el) {
        return !$.contains(document.documentElement, el);
    }

    function waitFor(test, fn, timeout, i) {
        if (!waitFor.i) {
            waitFor.i = 1;
            waitFor.ii = [true];
        }

        i = i || waitFor.i;

        if (typeof waitFor.ii[i] === 'undefined') {
            waitFor.ii[i] = true;
        }

        if (test()) {
            fn();
        } else {
            waitFor.ii[i] && setTimeout(function () {
                waitFor.ii[i] && waitFor(test, fn, timeout, i);
            }, timeout || 100);
        }

        return waitFor.i++;
    }

    waitFor.stop = function (i) {
        waitFor.ii[i] = false;
    };

    function setHash(hash) {
        //////console.time('setHash ' + hash);
        location.replace(location.protocol
            + '//'
            + location.host
            + location.pathname.replace(/^\/?/, '/')
            + location.search
            + '#' + hash);
        //////console.timeEnd('setHash ' + hash);
    }

    function fit($el, measuresToFit, method, position) {
        var elData = $el.data(),
            measures = elData.measures;

        if (measures && (!elData.l ||
            elData.l.W !== measures.width ||
            elData.l.H !== measures.height ||
            elData.l.r !== measures.ratio ||
            elData.l.w !== measuresToFit.w ||
            elData.l.h !== measuresToFit.h ||
            elData.l.m !== method ||
            elData.l.p !== position)) {

            //console.log('fit');

            var width = measures.width,
                height = measures.height,
                ratio = measuresToFit.w / measuresToFit.h,
                biggerRatioFLAG = measures.ratio >= ratio,
                fitFLAG = method === 'scaledown',
                containFLAG = method === 'contain',
                coverFLAG = method === 'cover',
                pos = parsePosition(position);

            if (biggerRatioFLAG && (fitFLAG || containFLAG) || !biggerRatioFLAG && coverFLAG) {
                width = minMaxLimit(measuresToFit.w, 0, fitFLAG ? width : Infinity);
                height = width / measures.ratio;
            } else if (biggerRatioFLAG && coverFLAG || !biggerRatioFLAG && (fitFLAG || containFLAG)) {
                height = minMaxLimit(measuresToFit.h, 0, fitFLAG ? height : Infinity);
                width = height * measures.ratio;
            }

            $el.css({
                width: width,
                height: height,
                left: numberFromWhatever(pos.x, measuresToFit.w - width),
                top: numberFromWhatever(pos.y, measuresToFit.h - height)
            });

            elData.l = {
                W: measures.width,
                H: measures.height,
                r: measures.ratio,
                w: measuresToFit.w,
                h: measuresToFit.h,
                m: method,
                p: position
            };
        }

        return true;
    }

    function setStyle($el, style) {
        var el = $el[0];
        if (el.styleSheet) {
            el.styleSheet.cssText = style;
        } else {
            $el.html(style);
        }
    }

    function findShadowEdge(pos, min, max) {
        return min === max ? false : pos <= min ? 'left' : pos >= max ? 'right' : 'left right';
    }

    function getIndexFromHash(hash, data, ok, startindex) {
        if (!ok) return false;
        if (!isNaN(hash)) return hash - (startindex ? 0 : 1);

        var index;

        for (var _i = 0, _l = data.length; _i < _l; _i++) {
            var dataFrame = data[_i];

            if (dataFrame.id === hash) {
                index = _i;
                break;
            }
        }

        return index;
    }

    function smartClick($el, fn, _options) {
        _options = _options || {};

        $el.each(function () {
            var $this = $(this),
                thisData = $this.data(),
                startEvent;

            if (thisData.clickOn) return;

            thisData.clickOn = true;

            $.extend(touch($this, {
                onStart: function (e) {
                    startEvent = e;
                    (_options.onStart || noop).call(this, e);
                },
                onMove: _options.onMove || noop,
                onTouchEnd: _options.onTouchEnd || noop,
                onEnd: function (result) {
                    ////console.log('smartClick → result.moved', result.moved);
                    if (result.moved) return;
                    fn.call(this, startEvent);
                }
            }), { noMove: true });
        });
    }

    function div(classes, child) {
        return '<div class="' + classes + '">' + (child || '') + '</div>';
    }

    function button(classes, child) {
        return '<button class="' + classes + '">' + (child || '') + '</button>';
    }

    // Fisher–Yates Shuffle
    // http://bost.ocks.org/mike/shuffle/
    function shuffle(array) {
        // While there remain elements to shuffle
        var l = array.length;
        while (l) {
            // Pick a remaining element
            var i = Math.floor(Math.random() * l--);

            // And swap it with the current element
            var t = array[l];
            array[l] = array[i];
            array[i] = t;
        }

        return array;
    }

    function clone(array) {
        return Object.prototype.toString.call(array) == '[object Array]'
            && $.map(array, function (frame) {
                return $.extend({}, frame);
            });
    }

    function lockScroll($el, left, top) {
        $el
          .scrollLeft(left || 0)
          .scrollTop(top || 0);
    }

    function optionsToLowerCase(options) {
        if (options) {
            var opts = {};
            $.each(options, function (key, value) {
                opts[key.toLowerCase()] = value;
            });

            return opts;
        }
    }

    function getRatio(_ratio) {
        if (!_ratio) return;
        var ratio = +_ratio;
        if (!isNaN(ratio)) {
            return ratio;
        } else {
            ratio = _ratio.split('/');
            return +ratio[0] / +ratio[1] || undefined;
        }
    }

    function addEvent(el, e, fn, bool) {
        if (!e) return;
        el.addEventListener ? el.addEventListener(e, fn, !!bool) : el.attachEvent('on' + e, fn);
    }

    function elIsDisabled(el) {
        return !!el.getAttribute('disabled');
    }

    function disableAttr(FLAG) {
        return { tabindex: FLAG * -1 + '', disabled: FLAG };
    }

    function addEnterUp(el, fn) {
        addEvent(el, 'keyup', function (e) {
            elIsDisabled(el) || e.keyCode == 13 && fn.call(el, e);
        });
    }

    function addFocus(el, fn) {
        addEvent(el, 'focus', el.onfocusin = function (e) {
            fn.call(el, e);
        }, true);
    }

    function stopEvent(e, stopPropagation) {
        e.preventDefault ? e.preventDefault() : (e.returnValue = false);
        stopPropagation && e.stopPropagation && e.stopPropagation();
    }

    function getDirectionSign(forward) {
        return forward ? '>' : '<';
    }

    function parsePosition(rule) {
        rule = (rule + '').split(/\s+/);
        return {
            x: measureIsValid(rule[0]) || FIFTYFIFTY,
            y: measureIsValid(rule[1]) || FIFTYFIFTY
        }
    }
    function slide($el, options) {
        var elData = $el.data(),
            elPos = Math.round(options.pos),
            onEndFn = function () {
                elData.sliding = false;
                (options.onEnd || noop)();
            };

        if (typeof options.overPos !== 'undefined' && options.overPos !== options.pos) {
            elPos = options.overPos;
            onEndFn = function () {
                slide($el, $.extend({}, options, { overPos: options.pos, time: Math.max(TRANSITION_DURATION, options.time / 2) }))
            };
        }

        ////////console.time('var translate = $.extend');
        var translate = $.extend(getTranslate(elPos/*, options._001*/), options.width && { width: options.width });
        ////////console.timeEnd('var translate = $.extend');

        elData.sliding = true;

        if (CSS3) {
            $el.css($.extend(getDuration(options.time), translate));
            if (options.time > 10) {
                ////////console.time('afterTransition');
                afterTransition($el, 'transform', onEndFn, options.time);
                ////////console.timeEnd('afterTransition');
            } else {
                onEndFn();
            }
        } else {
            $el.stop().animate(translate, options.time, BEZIER, onEndFn);
        }
    }

    function fade($el1, $el2, $frames, options, fadeStack, chain) {
        var chainedFLAG = typeof chain !== 'undefined';
        if (!chainedFLAG) {
            fadeStack.push(arguments);
            Array.prototype.push.call(arguments, fadeStack.length);
            if (fadeStack.length > 1) return;
        }

        $el1 = $el1 || $($el1);
        $el2 = $el2 || $($el2);

        var _$el1 = $el1[0],
            _$el2 = $el2[0],
            crossfadeFLAG = options.method === 'crossfade',
            onEndFn = function () {
                if (!onEndFn.done) {
                    onEndFn.done = true;
                    var args = (chainedFLAG || fadeStack.shift()) && fadeStack.shift();
                    args && fade.apply(this, args);
                    (options.onEnd || noop)(!!args);
                }
            },
            time = options.time / (chain || 1);

        $frames.removeClass(fadeRearClass + ' ' + fadeFrontClass);

        $el1
            .stop()
            .addClass(fadeRearClass);
        $el2
            .stop()
            .addClass(fadeFrontClass);

        crossfadeFLAG && _$el2 && $el1.fadeTo(0, 0);

        $el1.fadeTo(crossfadeFLAG ? time : 0, 1, crossfadeFLAG && onEndFn);
        $el2.fadeTo(time, 0, onEndFn);

        (_$el1 && crossfadeFLAG) || _$el2 || onEndFn();
    }
    var lastEvent,
        moveEventType,
        preventEvent,
        preventEventTimeout;

    function extendEvent(e) {
        var touch = (e.touches || [])[0] || e;
        e._x = touch.pageX;
        e._y = touch.clientY;
        e._now = $.now();
    }

    function touch($el, options) {
        var el = $el[0],
            tail = {},
            touchEnabledFLAG,
            startEvent,
            $target,
            controlTouch,
            touchFLAG,
            targetIsSelectFLAG,
            targetIsLinkFlag,
            tolerance,
            moved;

        function onStart(e) {
            $target = $(e.target);
            tail.checked = targetIsSelectFLAG = targetIsLinkFlag = moved = false;

            if (touchEnabledFLAG
                || tail.flow
                || (e.touches && e.touches.length > 1)
                || e.which > 1
                || (lastEvent && lastEvent.type !== e.type && preventEvent)
                || (targetIsSelectFLAG = options.select && $target.is(options.select, el))) return targetIsSelectFLAG;

            touchFLAG = e.type === 'touchstart';
            targetIsLinkFlag = $target.is('a, a *', el);
            controlTouch = tail.control;

            tolerance = (tail.noMove || tail.noSwipe || controlTouch) ? 16 : !tail.snap ? 4 : 0;

            extendEvent(e);

            startEvent = lastEvent = e;
            moveEventType = e.type.replace(/down|start/, 'move').replace(/Down/, 'Move');

            (options.onStart || noop).call(el, e, { control: controlTouch, $target: $target });

            touchEnabledFLAG = tail.flow = true;

            if (!touchFLAG || tail.go) stopEvent(e);
        }

        function onMove(e) {
            if ((e.touches && e.touches.length > 1)
                || (MS_POINTER && !e.isPrimary)
                || moveEventType !== e.type
                || !touchEnabledFLAG) {
                touchEnabledFLAG && onEnd();
                (options.onTouchEnd || noop)();
                return;
            }

            extendEvent(e);

            var xDiff = Math.abs(e._x - startEvent._x), // opt _x → _pageX
                yDiff = Math.abs(e._y - startEvent._y),
                xyDiff = xDiff - yDiff,
                xWin = (tail.go || tail.x || xyDiff >= 0) && !tail.noSwipe,
                yWin = xyDiff < 0;

            if (touchFLAG && !tail.checked) {
                if (touchEnabledFLAG = xWin) {
                    stopEvent(e);
                }
            } else {
                ////console.log('onMove e.preventDefault');
                stopEvent(e);
                (options.onMove || noop).call(el, e, { touch: touchFLAG });
            }

            if (!moved && Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)) > tolerance) {
                moved = true;
            }

            tail.checked = tail.checked || xWin || yWin;
        }

        function onEnd(e) {
            //////console.time('touch.js onEnd');

            (options.onTouchEnd || noop)();

            var _touchEnabledFLAG = touchEnabledFLAG;
            tail.control = touchEnabledFLAG = false;

            if (_touchEnabledFLAG) {
                tail.flow = false;
            }

            if (!_touchEnabledFLAG || (targetIsLinkFlag && !tail.checked)) return;

            e && stopEvent(e);

            preventEvent = true;
            clearTimeout(preventEventTimeout);
            preventEventTimeout = setTimeout(function () {
                preventEvent = false;
            }, 1000);

            (options.onEnd || noop).call(el, { moved: moved, $target: $target, control: controlTouch, touch: touchFLAG, startEvent: startEvent, aborted: !e || e.type === 'MSPointerCancel' });
            //////console.timeEnd('touch.js onEnd');
        }

        function onOtherStart() {
            if (tail.flow) return;
            setTimeout(function () {
                tail.flow = true;
            }, 10);
        }

        function onOtherEnd() {
            if (!tail.flow) return;
            setTimeout(function () {
                tail.flow = false;
            }, TOUCH_TIMEOUT);
        }

        if (MS_POINTER) {
            addEvent(el, 'MSPointerDown', onStart);
            addEvent(document, 'MSPointerMove', onMove);
            addEvent(document, 'MSPointerCancel', onEnd);
            addEvent(document, 'MSPointerUp', onEnd);
        } else {
            addEvent(el, 'touchstart', onStart);
            addEvent(el, 'touchmove', onMove);
            addEvent(el, 'touchend', onEnd);

            addEvent(document, 'touchstart', onOtherStart);
            addEvent(document, 'touchend', onOtherEnd);
            addEvent(document, 'touchcancel', onOtherEnd);

            $WINDOW.on('scroll', onOtherEnd);

            $el.on('mousedown', onStart);
            $DOCUMENT
                .on('mousemove', onMove)
                .on('mouseup', onEnd);
        }

        $el.on('click', 'a', function (e) {
            tail.checked && stopEvent(e);
        });

        return tail;
    }

    function moveOnTouch($el, options) {
        var el = $el[0],
            elData = $el.data(),
            tail = {},
            startCoo,
            coo,
            startElPos,
            moveElPos,
            edge,
            moveTrack,
            startTime,
            endTime,
            min,
            max,
            snap,
            slowFLAG,
            controlFLAG,
            moved,
            tracked;

        function startTracking(e, noStop) {
            tracked = true;
            startCoo = coo = e._x;
            startTime = e._now;

            moveTrack = [
              [startTime, startCoo]
            ];

            startElPos = moveElPos = tail.noMove || noStop ? 0 : stop($el, (options.getPos || noop)()/*, options._001*/);

            (options.onStart || noop).call(el, e);
        }

        function onStart(e, result) {
            min = tail.min;
            max = tail.max;
            snap = tail.snap;

            slowFLAG = e.altKey;
            tracked = moved = false;

            controlFLAG = result.control;

            if (!controlFLAG && !elData.sliding) {
                startTracking(e);
            }
        }

        function onMove(e, result) {
            if (!tail.noSwipe) {
                if (!tracked) {
                    startTracking(e);
                }

                coo = e._x;

                moveTrack.push([e._now, coo]);

                moveElPos = startElPos - (startCoo - coo);

                edge = findShadowEdge(moveElPos, min, max);

                if (moveElPos <= min) {
                    moveElPos = edgeResistance(moveElPos, min);
                } else if (moveElPos >= max) {
                    moveElPos = edgeResistance(moveElPos, max);
                }

                if (!tail.noMove) {
                    $el.css(getTranslate(moveElPos/*, options._001*/));
                    if (!moved) {
                        moved = true;
                        // only for mouse
                        result.touch || MS_POINTER || $el.addClass(grabbingClass);
                    }

                    (options.onMove || noop).call(el, e, { pos: moveElPos, edge: edge });
                }
            }
        }

        function onEnd(result) {
            //////console.time('moveontouch.js onEnd');
            if (tail.noSwipe && result.moved) return;

            if (!tracked) {
                startTracking(result.startEvent, true);
            }

            ////console.log('onEnd');

            result.touch || MS_POINTER || $el.removeClass(grabbingClass);

            endTime = $.now();

            var _backTimeIdeal = endTime - TOUCH_TIMEOUT,
                _backTime,
                _timeDiff,
                _timeDiffLast,
                backTime = null,
                backCoo,
                virtualPos,
                limitPos,
                newPos,
                overPos,
                time = TRANSITION_DURATION,
                speed,
                friction = options.friction;

            for (var _i = moveTrack.length - 1; _i >= 0; _i--) {
                _backTime = moveTrack[_i][0];
                _timeDiff = Math.abs(_backTime - _backTimeIdeal);
                if (backTime === null || _timeDiff < _timeDiffLast) {
                    backTime = _backTime;
                    backCoo = moveTrack[_i][1];
                } else if (backTime === _backTimeIdeal || _timeDiff > _timeDiffLast) {
                    break;
                }
                _timeDiffLast = _timeDiff;
            }

            newPos = minMaxLimit(moveElPos, min, max);

            var cooDiff = backCoo - coo,
                forwardFLAG = cooDiff >= 0,
                timeDiff = endTime - backTime,
                longTouchFLAG = timeDiff > TOUCH_TIMEOUT,
                swipeFLAG = !longTouchFLAG && moveElPos !== startElPos && newPos === moveElPos;

            if (snap) {
                newPos = minMaxLimit(Math[swipeFLAG ? (forwardFLAG ? 'floor' : 'ceil') : 'round'](moveElPos / snap) * snap, min, max);
                min = max = newPos;
            }

            if (swipeFLAG && (snap || newPos === moveElPos)) {
                speed = -(cooDiff / timeDiff);
                time *= minMaxLimit(Math.abs(speed), options.timeLow, options.timeHigh);
                virtualPos = Math.round(moveElPos + speed * time / friction);

                if (!snap) {
                    newPos = virtualPos;
                }

                if (!forwardFLAG && virtualPos > max || forwardFLAG && virtualPos < min) {
                    limitPos = forwardFLAG ? min : max;
                    overPos = virtualPos - limitPos;
                    if (!snap) {
                        newPos = limitPos;
                    }
                    overPos = minMaxLimit(newPos + overPos * .03, limitPos - 50, limitPos + 50);
                    time = Math.abs((moveElPos - overPos) / (speed / friction));
                }
            }

            time *= slowFLAG ? 10 : 1;

            (options.onEnd || noop).call(el, $.extend(result, { moved: result.moved || longTouchFLAG && snap, pos: moveElPos, newPos: newPos, overPos: overPos, time: time }));
        }

        tail = $.extend(touch(options.$wrap, $.extend({}, options, {
            onStart: onStart,
            onMove: onMove,
            onEnd: onEnd
        })), tail);

        return tail;
    }
    function wheel($el, options) {
        var el = $el[0],
            lockFLAG,
            lastDirection,
            lastNow,
            tail = {
                prevent: {}
            };

        addEvent(el, WHEEL, function (e) {
            var yDelta = e.wheelDeltaY || -1 * e.deltaY || 0,
                xDelta = e.wheelDeltaX || -1 * e.deltaX || 0,
                xWin = Math.abs(xDelta) && !Math.abs(yDelta),
                direction = getDirectionSign(xDelta < 0),
                sameDirection = lastDirection === direction,
                now = $.now(),
                tooFast = now - lastNow < TOUCH_TIMEOUT;

            lastDirection = direction;
            lastNow = now;

            if (!xWin || !tail.ok || tail.prevent[direction] && !lockFLAG) {
                return;
            } else {
                stopEvent(e, true);
                if (lockFLAG && sameDirection && tooFast) {
                    return;
                }
            }

            if (options.shift) {
                lockFLAG = true;
                clearTimeout(tail.t);
                tail.t = setTimeout(function () {
                    lockFLAG = false;
                }, SCROLL_LOCK_TIMEOUT);
            }

            (options.onEnd || noop)(e, options.shift ? direction : xDelta);

        });

        return tail;
    }
    jQuery.Fotorama = function ($fotorama, opts) {
        $HTML = $('html');
        $BODY = $('body');

        var that = this,
            stamp = $.now(),
            stampClass = _fotoramaClass + stamp,
            fotorama = $fotorama[0],
            data,
            dataFrameCount = 1,
            fotoramaData = $fotorama.data(),
            size,

            $style = $('<style></style>'),

            $anchor = $(div(hiddenClass)),
            $wrap = $(div(wrapClass)),
            $stage = $(div(stageClass)).appendTo($wrap),
            stage = $stage[0],

            $stageShaft = $(div(stageShaftClass)).appendTo($stage),
            $stageFrame = $(),
            $arrPrev = $(div(arrClass + ' ' + arrPrevClass + buttonAttributes, '<span class="sr-only">previous</span>')),
            $arrNext = $(div(arrClass + ' ' + arrNextClass + buttonAttributes, '<span class="sr-only">next</span>')),
            $arrs = $arrPrev.add($arrNext).appendTo($stage),
            $navWrap = $(div(navWrapClass)),
            $nav = $(div(navClass)).appendTo($navWrap),
            $navShaft = $(div(navShaftClass)).appendTo($nav),
            $navFrame,
            $navDotFrame = $(),
            $navThumbFrame = $(),

            stageShaftData = $stageShaft.data(),
            navShaftData = $navShaft.data(),

            $thumbBorder = $(div(thumbBorderClass)).appendTo($navShaft),

            $fullscreenIcon = $(div(fullscreenIconClass + buttonAttributes)),
            fullscreenIcon = $fullscreenIcon[0],
            $videoPlay = $(div(videoPlayClass)),
            $videoClose = $(div(videoCloseClass)).appendTo($stage),
            videoClose = $videoClose[0],

            spinner,
            $spinner = $(div(spinnerClass)),

            $videoPlaying,

            activeIndex = false,
            activeFrame,
            activeIndexes,
            repositionIndex,
            dirtyIndex,
            lastActiveIndex,
            prevIndex,
            nextIndex,
            nextAutoplayIndex,
            startIndex,

            o_loop,
            o_nav,
            o_navThumbs,
            o_navTop,
            o_allowFullScreen,
            o_nativeFullScreen,
            o_fade,
            o_thumbSide,
            o_thumbSide2,
            o_transitionDuration,
            o_transition,
            o_shadows,
            o_rtl,
            o_keyboard,
            lastOptions = {},

            measures = {},
            measuresSetFLAG,

            stageShaftTouchTail = {},
            stageWheelTail = {},
            navShaftTouchTail = {},
            navWheelTail = {},

            scrollTop,
            scrollLeft,

            showedFLAG,
            pausedAutoplayFLAG,
            stoppedAutoplayFLAG,

            toDeactivate = {},
            toDetach = {},

            measuresStash,

            touchedFLAG,

            hoverFLAG,

            navFrameKey,
            stageLeft = 0,

            fadeStack = [];

        $wrap[STAGE_FRAME_KEY] = $(div(stageFrameClass));
        $wrap[NAV_THUMB_FRAME_KEY] = $(button(navFrameClass + ' ' + navFrameThumbClass + buttonAttributes, div(thumbClass)));
        $wrap[NAV_DOT_FRAME_KEY] = $(div(navFrameClass + ' ' + navFrameDotClass + buttonAttributes, div(dotClass)));

        toDeactivate[STAGE_FRAME_KEY] = [];
        toDeactivate[NAV_THUMB_FRAME_KEY] = [];
        toDeactivate[NAV_DOT_FRAME_KEY] = [];
        toDetach[STAGE_FRAME_KEY] = {};

        $wrap
            .addClass(CSS3 ? wrapCss3Class : wrapCss2Class)
            .toggleClass(wrapNoControlsClass, !opts.controlsonstart);

        fotoramaData.fotorama = this;

        function checkForVideo() {
            $.each(data, function (i, dataFrame) {
                if (!dataFrame.i) {
                    dataFrame.i = dataFrameCount++;
                    var video = findVideoId(dataFrame.video, true);
                    if (video) {
                        var thumbs = {};
                        dataFrame.video = video;
                        if (!dataFrame.img && !dataFrame.thumb) {
                            thumbs = getVideoThumbs(dataFrame, data, that);
                        } else {
                            dataFrame.thumbsReady = true;
                        }
                        updateData(data, { img: thumbs.img, thumb: thumbs.thumb }, dataFrame.i, that);
                    }
                }
            });
        }

        function allowKey(key) {
            return o_keyboard[key] || that.fullScreen;
        }

        function bindGlobalEvents(FLAG) {
            var keydownCommon = 'keydown.' + _fotoramaClass,
                localStamp = _fotoramaClass + stamp,
                keydownLocal = 'keydown.' + localStamp,
                resizeLocal = 'resize.' + localStamp + ' ' + 'orientationchange.' + localStamp;

            if (FLAG) {
                $DOCUMENT
                    .on(keydownLocal, function (e) {
                        var catched,
                            index;

                        if ($videoPlaying && e.keyCode === 27) {
                            catched = true;
                            unloadVideo($videoPlaying, true, true);
                        } else if (that.fullScreen || (opts.keyboard && !that.index)) {
                            if (e.keyCode === 27) {
                                catched = true;
                                that.cancelFullScreen();
                            } else if ((e.shiftKey && e.keyCode === 32 && allowKey('space')) || (e.keyCode === 37 && allowKey('left')) || (e.keyCode === 38 && allowKey('up'))) {
                                index = '<';
                            } else if ((e.keyCode === 32 && allowKey('space')) || (e.keyCode === 39 && allowKey('right')) || (e.keyCode === 40 && allowKey('down'))) {
                                index = '>';
                            } else if (e.keyCode === 36 && allowKey('home')) {
                                index = '<<';
                            } else if (e.keyCode === 35 && allowKey('end')) {
                                index = '>>';
                            }
                        }

                        (catched || index) && stopEvent(e);
                        index && that.show({ index: index, slow: e.altKey, user: true });
                    });

                if (!that.index) {
                    $DOCUMENT
                        .off(keydownCommon)
                        .on(keydownCommon, 'textarea, input, select', function (e) {
                            !$BODY.hasClass(_fullscreenClass) && e.stopPropagation();
                        });
                }

                $WINDOW.on(resizeLocal, that.resize);
            } else {
                $DOCUMENT.off(keydownLocal);
                $WINDOW.off(resizeLocal);
            }
        }

        function appendElements(FLAG) {
            if (FLAG === appendElements.f) return;

            if (FLAG) {
                $fotorama
                    .html('')
                    .addClass(_fotoramaClass + ' ' + stampClass)
                    .append($wrap)
                    .before($style)
                    .before($anchor);

                addInstance(that);
            } else {
                $wrap.detach();
                $style.detach();
                $anchor.detach();
                $fotorama
                    .html(fotoramaData.urtext)
                    .removeClass(stampClass);

                hideInstance(that);
            }

            bindGlobalEvents(FLAG);
            appendElements.f = FLAG;
        }

        function setData() {
            data = that.data = data || clone(opts.data) || getDataFromHtml($fotorama);
            size = that.size = data.length;

            !ready.ok && opts.shuffle && shuffle(data);

            checkForVideo();

            activeIndex = limitIndex(activeIndex);

            size && appendElements(true);
        }

        function stageNoMove() {
            var _noMove = (size < 2 && !opts.enableifsingleframe) || $videoPlaying;
            stageShaftTouchTail.noMove = _noMove || o_fade;
            stageShaftTouchTail.noSwipe = _noMove || !opts.swipe;

            !o_transition && $stageShaft.toggleClass(grabClass, !opts.click && !stageShaftTouchTail.noMove && !stageShaftTouchTail.noSwipe);
            MS_POINTER && $wrap.toggleClass(wrapPanYClass, !stageShaftTouchTail.noSwipe);
        }

        function setAutoplayInterval(interval) {
            if (interval === true) interval = '';
            opts.autoplay = Math.max(+interval || AUTOPLAY_INTERVAL, o_transitionDuration * 1.5);
        }

        /**
         * Options on the fly
         * */
        function setOptions() {
            that.options = opts = optionsToLowerCase(opts);

            o_fade = (opts.transition === 'crossfade' || opts.transition === 'dissolve');

            o_loop = opts.loop && (size > 2 || (o_fade && (!o_transition || o_transition !== 'slide')));

            o_transitionDuration = +opts.transitionduration || TRANSITION_DURATION;

            o_rtl = opts.direction === 'rtl';

            o_keyboard = $.extend({}, opts.keyboard && KEYBOARD_OPTIONS, opts.keyboard);

            var classes = { add: [], remove: [] };

            function addOrRemoveClass(FLAG, value) {
                classes[FLAG ? 'add' : 'remove'].push(value);
            }

            if (size > 1 || opts.enableifsingleframe) {
                o_nav = opts.nav;
                o_navTop = opts.navposition === 'top';
                classes.remove.push(selectClass);

                $arrs.toggle(!!opts.arrows);
            } else {
                o_nav = false;
                $arrs.hide();
            }

            spinnerStop();
            spinner = new Spinner($.extend(spinnerDefaults, opts.spinner, spinnerOverride, { direction: o_rtl ? -1 : 1 }));

            arrsUpdate();
            stageWheelUpdate();

            if (opts.autoplay) setAutoplayInterval(opts.autoplay);

            o_thumbSide = numberFromMeasure(opts.thumbwidth) || THUMB_SIZE;
            o_thumbSide2 = numberFromMeasure(opts.thumbheight) || THUMB_SIZE;

            stageWheelTail.ok = navWheelTail.ok = opts.trackpad && !SLOW;

            stageNoMove();

            extendMeasures(opts, [measures]);

            o_navThumbs = o_nav === 'thumbs';

            if (o_navThumbs) {
                frameDraw(size, 'navThumb');

                $navFrame = $navThumbFrame;
                navFrameKey = NAV_THUMB_FRAME_KEY;

                
                
                setStyle($style, $.Fotorama.jst.style({ w: o_thumbSide, h: o_thumbSide2, b: opts.thumbborderwidth, m: opts.thumbmargin, s: stamp, q: !COMPAT }));

                $nav
                    .addClass(navThumbsClass)
                    .removeClass(navDotsClass);
            } else if (o_nav === 'dots') {
                frameDraw(size, 'navDot');

                $navFrame = $navDotFrame;
                navFrameKey = NAV_DOT_FRAME_KEY;

                $nav
                    .addClass(navDotsClass)
                    .removeClass(navThumbsClass);
            } else {
                o_nav = false;
                $nav.removeClass(navThumbsClass + ' ' + navDotsClass);
            }

            if (o_nav) {
                if (o_navTop) {
                    $navWrap.insertBefore($stage);
                } else {
                    $navWrap.insertAfter($stage);
                }
                frameAppend.nav = false;
                frameAppend($navFrame, $navShaft, 'nav');
            }

            o_allowFullScreen = opts.allowfullscreen;

            if (o_allowFullScreen) {
                $fullscreenIcon.prependTo($stage);
                o_nativeFullScreen = FULLSCREEN && o_allowFullScreen === 'native';
            } else {
                $fullscreenIcon.detach();
                o_nativeFullScreen = false;
            }

            addOrRemoveClass(o_fade, wrapFadeClass);
            addOrRemoveClass(!o_fade, wrapSlideClass);
            addOrRemoveClass(!opts.captions, wrapNoCaptionsClass);
            addOrRemoveClass(o_rtl, wrapRtlClass);
            addOrRemoveClass(opts.arrows !== 'always', wrapToggleArrowsClass);

            o_shadows = opts.shadows && !SLOW;
            addOrRemoveClass(!o_shadows, wrapNoShadowsClass);

            $wrap
                .addClass(classes.add.join(' '))
                .removeClass(classes.remove.join(' '));

            lastOptions = $.extend({}, opts);
        }

        function normalizeIndex(index) {
            return index < 0 ? (size + (index % size)) % size : index >= size ? index % size : index;
        }

        function limitIndex(index) {
            return minMaxLimit(index, 0, size - 1);
        }

        function edgeIndex(index) {
            return o_loop ? normalizeIndex(index) : limitIndex(index);
        }

        function getPrevIndex(index) {
            return index > 0 || o_loop ? index - 1 : false;
        }

        function getNextIndex(index) {
            return index < size - 1 || o_loop ? index + 1 : false;
        }

        function setStageShaftMinmaxAndSnap() {
            stageShaftTouchTail.min = o_loop ? -Infinity : -getPosByIndex(size - 1, measures.w, opts.margin, repositionIndex);
            stageShaftTouchTail.max = o_loop ? Infinity : -getPosByIndex(0, measures.w, opts.margin, repositionIndex);
            stageShaftTouchTail.snap = measures.w + opts.margin;
        }

        function setNavShaftMinMax() {
            ////////console.log('setNavShaftMinMax', measures.nw);
            navShaftTouchTail.min = Math.min(0, measures.nw - $navShaft.width());
            navShaftTouchTail.max = 0;
            $navShaft.toggleClass(grabClass, !(navShaftTouchTail.noMove = navShaftTouchTail.min === navShaftTouchTail.max));
        }

        function eachIndex(indexes, type, fn) {
            if (typeof indexes === 'number') {
                indexes = new Array(indexes);
                var rangeFLAG = true;
            }
            return $.each(indexes, function (i, index) {
                if (rangeFLAG) index = i;
                if (typeof index === 'number') {
                    var dataFrame = data[normalizeIndex(index)];

                    if (dataFrame) {
                        var key = '$' + type + 'Frame',
                            $frame = dataFrame[key];

                        fn.call(this, i, index, dataFrame, $frame, key, $frame && $frame.data());
                    }
                }
            });
        }

        function setMeasures(width, height, ratio, index) {
            if (!measuresSetFLAG || (measuresSetFLAG === '*' && index === startIndex)) {

                //////console.log('setMeasures', index, opts.width, opts.height);

                width = measureIsValid(opts.width) || measureIsValid(width) || WIDTH;
                height = measureIsValid(opts.height) || measureIsValid(height) || HEIGHT;
                that.resize({
                    width: width,
                    ratio: opts.ratio || ratio || width / height
                }, 0, index !== startIndex && '*');
            }
        }

        function loadImg(indexes, type, specialMeasures, method, position, again) {
            eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {

                if (!$frame) return;

                var fullFLAG = that.fullScreen && dataFrame.full && dataFrame.full !== dataFrame.img && !frameData.$full && type === 'stage';

                if (frameData.$img && !again && !fullFLAG) return;

                var img = new Image(),
                    $img = $(img),
                    imgData = $img.data();

                frameData[fullFLAG ? '$full' : '$img'] = $img;

                var srcKey = type === 'stage' ? (fullFLAG ? 'full' : 'img') : 'thumb',
                    src = dataFrame[srcKey],
                    dummy = fullFLAG ? null : dataFrame[type === 'stage' ? 'thumb' : 'img'];

                if (type === 'navThumb') $frame = frameData.$wrap;

                function triggerTriggerEvent(event) {
                    var _index = normalizeIndex(index);
                    triggerEvent(event, {
                        index: _index,
                        src: src,
                        frame: data[_index]
                    });
                }

                function error() {
                    $img.remove();

                    $.Fotorama.cache[src] = 'error';

                    if ((!dataFrame.html || type !== 'stage') && dummy && dummy !== src) {
                        dataFrame[srcKey] = src = dummy;
                        loadImg([index], type, specialMeasures, method, position, true);
                    } else {
                        if (src && !dataFrame.html && !fullFLAG) {
                            $frame
                                .trigger('f:error')
                                .removeClass(loadingClass)
                                .addClass(errorClass);

                            triggerTriggerEvent('error');
                        } else if (type === 'stage') {
                            $frame
                                .trigger('f:load')
                                .removeClass(loadingClass + ' ' + errorClass)
                                .addClass(loadedClass);

                            triggerTriggerEvent('load');
                            setMeasures();
                        }

                        frameData.state = 'error';

                        if (size > 1 && data[index] === dataFrame && !dataFrame.html && !dataFrame.deleted && !dataFrame.video && !fullFLAG) {
                            dataFrame.deleted = true;
                            that.splice(index, 1);
                        }
                    }
                }

                function loaded() {
                    //////console.log('loaded: ' + src);

                    ////console.log('$.Fotorama.measures[src]', $.Fotorama.measures[src]);

                    $.Fotorama.measures[src] = imgData.measures = $.Fotorama.measures[src] || {
                        width: img.width,
                        height: img.height,
                        ratio: img.width / img.height
                    };

                    setMeasures(imgData.measures.width, imgData.measures.height, imgData.measures.ratio, index);

                    $img
                        .off('load error')
                        .addClass(imgClass + (fullFLAG ? ' ' + imgFullClass : ''))
                        .prependTo($frame);

                    fit($img, ($.isFunction(specialMeasures) ? specialMeasures() : specialMeasures) || measures, method || dataFrame.fit || opts.fit, position || dataFrame.position || opts.position);

                    $.Fotorama.cache[src] = frameData.state = 'loaded';

                    setTimeout(function () {
                        $frame
                            .trigger('f:load')
                            .removeClass(loadingClass + ' ' + errorClass)
                            .addClass(loadedClass + ' ' + (fullFLAG ? loadedFullClass : loadedImgClass));

                        if (type === 'stage') {
                            triggerTriggerEvent('load');
                        } else if (dataFrame.thumbratio === AUTO || !dataFrame.thumbratio && opts.thumbratio === AUTO) {
                            // danger! reflow for all thumbnails
                            dataFrame.thumbratio = imgData.measures.ratio;
                            reset();
                        }
                    }, 0);
                }

                if (!src) {
                    error();
                    return;
                }

                function waitAndLoad() {
                    var _i = 10;
                    waitFor(function () {
                        return !touchedFLAG || !_i-- && !SLOW;
                    }, function () {
                        loaded();
                    });
                }

                if (!$.Fotorama.cache[src]) {
                    $.Fotorama.cache[src] = '*';

                    $img
                        .on('load', waitAndLoad)
                        .on('error', error);
                } else {
                    (function justWait() {
                        if ($.Fotorama.cache[src] === 'error') {
                            error();
                        } else if ($.Fotorama.cache[src] === 'loaded') {
                            ////console.log('take from cache: ' + src);
                            setTimeout(waitAndLoad, 0);
                        } else {
                            setTimeout(justWait, 100);
                        }
                    })();
                }

                frameData.state = '';
                img.src = src;
            });
        }

        function spinnerSpin($el) {
            $spinner.append(spinner.spin().el).appendTo($el);
        }

        function spinnerStop() {
            $spinner.detach();
            spinner && spinner.stop();
        }

        function updateFotoramaState() {
            var $frame = activeFrame[STAGE_FRAME_KEY];

            if ($frame && !$frame.data().state) {
                spinnerSpin($frame);
                $frame.on('f:load f:error', function () {
                    $frame.off('f:load f:error');
                    spinnerStop();
                });
            }
        }

        function addNavFrameEvents(frame) {
            addEnterUp(frame, onNavFrameClick);
            addFocus(frame, function () {

                setTimeout(function () {
                    lockScroll($nav);
                }, 0);
                slideNavShaft({ time: o_transitionDuration, guessIndex: $(this).data().eq, minMax: navShaftTouchTail });
            });
        }

        function frameDraw(indexes, type) {
            eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {
                if ($frame) return;

                $frame = dataFrame[key] = $wrap[key].clone();
                frameData = $frame.data();
                frameData.data = dataFrame;
                var frame = $frame[0];

                if (type === 'stage') {

                    if (dataFrame.html) {
                        $('<div class="' + htmlClass + '"></div>')
                            .append(
                                dataFrame._html ? $(dataFrame.html)
                                    .removeAttr('id')
                                    .html(dataFrame._html) // Because of IE
                                : dataFrame.html
                            )
                            .appendTo($frame);
                    }

                    dataFrame.caption && $(div(captionClass, div(captionWrapClass, dataFrame.caption))).appendTo($frame);

                    dataFrame.video && $frame
                      .addClass(stageFrameVideoClass)
                      .append($videoPlay.clone());

                    // This solves tabbing problems
                    addFocus(frame, function () {
                        setTimeout(function () {
                            lockScroll($stage);
                        }, 0);
                        clickToShow({ index: frameData.eq, user: true });
                    });

                    $stageFrame = $stageFrame.add($frame);
                } else if (type === 'navDot') {
                    addNavFrameEvents(frame);
                    $navDotFrame = $navDotFrame.add($frame);
                } else if (type === 'navThumb') {
                    addNavFrameEvents(frame);
                    frameData.$wrap = $frame.children(':first');
                    $navThumbFrame = $navThumbFrame.add($frame);
                    if (dataFrame.video) {
                        frameData.$wrap.append($videoPlay.clone());
                    }
                }
            });
        }

        function callFit($img, measuresToFit, method, position) {
            return $img && $img.length && fit($img, measuresToFit, method, position);
        }

        function stageFramePosition(indexes) {
            eachIndex(indexes, 'stage', function (i, index, dataFrame, $frame, key, frameData) {
                if (!$frame) return;

                var normalizedIndex = normalizeIndex(index),
                    method = dataFrame.fit || opts.fit,
                    position = dataFrame.position || opts.position;
                frameData.eq = normalizedIndex;

                toDetach[STAGE_FRAME_KEY][normalizedIndex] = $frame.css($.extend({ left: o_fade ? 0 : getPosByIndex(index, measures.w, opts.margin, repositionIndex) }, o_fade && getDuration(0)));

                if (isDetached($frame[0])) {
                    $frame.appendTo($stageShaft);
                    unloadVideo(dataFrame.$video);
                }

                callFit(frameData.$img, measures, method, position);
                callFit(frameData.$full, measures, method, position);
            });
        }

        function thumbsDraw(pos, loadFLAG) {
            if (o_nav !== 'thumbs' || isNaN(pos)) return;

            var leftLimit = -pos,
                rightLimit = -pos + measures.nw;

            $navThumbFrame.each(function () {
                var $this = $(this),
                    thisData = $this.data(),
                    eq = thisData.eq,
                    getSpecialMeasures = function () {
                        return {
                            h: o_thumbSide2,
                            w: thisData.w
                        }
                    },
                    specialMeasures = getSpecialMeasures(),
                    dataFrame = data[eq] || {},
                    method = dataFrame.thumbfit || opts.thumbfit,
                    position = dataFrame.thumbposition || opts.thumbposition;

                specialMeasures.w = thisData.w;

                if (thisData.l + thisData.w < leftLimit
                    || thisData.l > rightLimit
                    || callFit(thisData.$img, specialMeasures, method, position)) return;

                loadFLAG && loadImg([eq], 'navThumb', getSpecialMeasures, method, position);
            });
        }

        function frameAppend($frames, $shaft, type) {
            if (!frameAppend[type]) {

                var thumbsFLAG = type === 'nav' && o_navThumbs,
                    left = 0;

                $shaft.append(
                  $frames
                      .filter(function () {
                          var actual,
                              $this = $(this),
                              frameData = $this.data();
                          for (var _i = 0, _l = data.length; _i < _l; _i++) {
                              if (frameData.data === data[_i]) {
                                  actual = true;
                                  frameData.eq = _i;
                                  break;
                              }
                          }
                          return actual || $this.remove() && false;
                      })
                      .sort(function (a, b) {
                          return $(a).data().eq - $(b).data().eq;
                      })
                      .each(function () {

                          if (!thumbsFLAG) return;

                          var $this = $(this),
                              frameData = $this.data(),
                              thumbwidth = Math.round(o_thumbSide2 * frameData.data.thumbratio) || o_thumbSide;

                          frameData.l = left;
                          frameData.w = thumbwidth;

                          $this.css({ width: thumbwidth });

                          left += thumbwidth + opts.thumbmargin;
                      })
                );

                frameAppend[type] = true;
            }
        }

        function getDirection(x) {
            return x - stageLeft > measures.w / 3;
        }

        function disableDirrection(i) {
            return !o_loop && (!(activeIndex + i) || !(activeIndex - size + i)) && !$videoPlaying;
        }

        function arrsUpdate() {
            var disablePrev = disableDirrection(0),
                disableNext = disableDirrection(1);
            $arrPrev
                .toggleClass(arrDisabledClass, disablePrev)
                .attr(disableAttr(disablePrev));
            $arrNext
                .toggleClass(arrDisabledClass, disableNext)
                .attr(disableAttr(disableNext));
        }

        function stageWheelUpdate() {
            if (stageWheelTail.ok) {
                stageWheelTail.prevent = { '<': disableDirrection(0), '>': disableDirrection(1) };
            }
        }

        function getNavFrameBounds($navFrame) {
            var navFrameData = $navFrame.data(),
                left,
                width;

            if (o_navThumbs) {
                left = navFrameData.l;
                width = navFrameData.w;
            } else {
                left = $navFrame.position().left;
                width = $navFrame.width();
            }

            return {
                c: left + width / 2,
                min: -left + opts.thumbmargin * 10,
                max: -left + measures.w - width - opts.thumbmargin * 10
            };
        }

        function slideThumbBorder(time) {
            var navFrameData = activeFrame[navFrameKey].data();
            slide($thumbBorder, {
                time: time * 1.2,
                pos: navFrameData.l,
                width: navFrameData.w - opts.thumbborderwidth * 2
            });
        }

        function slideNavShaft(options) {
            ////console.log('slideNavShaft', options.guessIndex, options.keep, slideNavShaft.l);
            var $guessNavFrame = data[options.guessIndex][navFrameKey];
            if ($guessNavFrame) {
                var overflowFLAG = navShaftTouchTail.min !== navShaftTouchTail.max,
                    minMax = options.minMax || overflowFLAG && getNavFrameBounds(activeFrame[navFrameKey]),
                    l = overflowFLAG && (options.keep && slideNavShaft.l ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max)),
                    pos = overflowFLAG && minMaxLimit(l, navShaftTouchTail.min, navShaftTouchTail.max),
                    time = options.time * 1.1;

                slide($navShaft, {
                    time: time,
                    pos: pos || 0,
                    onEnd: function () {
                        thumbsDraw(pos, true);
                    }
                });

                //if (time) thumbsDraw(pos);

                setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max));
                slideNavShaft.l = l;
            }
        }

        function navUpdate() {
            deactivateFrames(navFrameKey);
            toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass));
        }

        function deactivateFrames(key) {
            var _toDeactivate = toDeactivate[key];

            while (_toDeactivate.length) {
                _toDeactivate.shift().removeClass(activeClass);
            }
        }

        function detachFrames(key) {
            var _toDetach = toDetach[key];

            //////console.log('_toDetach', _toDetach);
            //////console.log('activeIndexes', activeIndexes);

            $.each(activeIndexes, function (i, index) {
                delete _toDetach[normalizeIndex(index)];
            });

            $.each(_toDetach, function (index, $frame) {
                delete _toDetach[index];
                //////console.log('Detach', index);
                $frame.detach();
            });
        }

        function stageShaftReposition(skipOnEnd) {

            repositionIndex = dirtyIndex = activeIndex;

            var $frame = activeFrame[STAGE_FRAME_KEY];

            if ($frame) {
                deactivateFrames(STAGE_FRAME_KEY);
                toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass));

                skipOnEnd || that.show.onEnd(true);
                stop($stageShaft, 0, true);

                detachFrames(STAGE_FRAME_KEY);
                stageFramePosition(activeIndexes);
                setStageShaftMinmaxAndSnap();
                setNavShaftMinMax();
            }
        }

        function extendMeasures(options, measuresArray) {
            if (!options) return;

            $.each(measuresArray, function (i, measures) {
                if (!measures) return;

                $.extend(measures, {
                    width: options.width || measures.width,
                    height: options.height,
                    minwidth: options.minwidth,
                    maxwidth: options.maxwidth,
                    minheight: options.minheight,
                    maxheight: options.maxheight,
                    ratio: getRatio(options.ratio)
                })
            });
        }

        function triggerEvent(event, extra) {
            $fotorama.trigger(_fotoramaClass + ':' + event, [that, extra]);
        }

        function onTouchStart() {
            clearTimeout(onTouchEnd.t);
            touchedFLAG = 1;

            if (opts.stopautoplayontouch) {
                that.stopAutoplay();
            } else {
                pausedAutoplayFLAG = true;
            }
        }

        function onTouchEnd() {
            if (!touchedFLAG) return;
            if (!opts.stopautoplayontouch) {
                releaseAutoplay();
                changeAutoplay();
            }

            onTouchEnd.t = setTimeout(function () {
                touchedFLAG = 0;
            }, TRANSITION_DURATION + TOUCH_TIMEOUT);
            //////console.timeEnd('onTouchEnd');
        }

        function releaseAutoplay() {
            ////console.log('releaseAutoplay');
            pausedAutoplayFLAG = !!($videoPlaying || stoppedAutoplayFLAG);
        }

        function changeAutoplay() {
            ////console.log('changeAutoplay');

            clearTimeout(changeAutoplay.t);
            waitFor.stop(changeAutoplay.w);

            if (!opts.autoplay || pausedAutoplayFLAG) {
                if (that.autoplay) {
                    that.autoplay = false;
                    triggerEvent('stopautoplay');
                }

                return;
            }

            ////console.log('changeAutoplay continue');

            if (!that.autoplay) {
                that.autoplay = true;
                triggerEvent('startautoplay');
            }

            var _activeIndex = activeIndex;


            var frameData = activeFrame[STAGE_FRAME_KEY].data();
            changeAutoplay.w = waitFor(function () {
                ////console.log('wait for the state of the current frame');
                return frameData.state || _activeIndex !== activeIndex;
            }, function () {
                ////console.log('the current frame is ready');
                changeAutoplay.t = setTimeout(function () {
                    ////console.log('changeAutoplay.t setTimeout', pausedAutoplayFLAG, _activeIndex !== activeIndex);
                    if (pausedAutoplayFLAG || _activeIndex !== activeIndex) return;

                    var _nextAutoplayIndex = nextAutoplayIndex,
                        nextFrameData = data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();

                    changeAutoplay.w = waitFor(function () {
                        ////console.log('wait for the state of the next frame');
                        return nextFrameData.state || _nextAutoplayIndex !== nextAutoplayIndex;
                    }, function () {
                        if (pausedAutoplayFLAG || _nextAutoplayIndex !== nextAutoplayIndex) return;
                        that.show(o_loop ? getDirectionSign(!o_rtl) : nextAutoplayIndex);
                    });
                }, opts.autoplay);
            });

        }

        that.startAutoplay = function (interval) {
            if (that.autoplay) return this;
            pausedAutoplayFLAG = stoppedAutoplayFLAG = false;
            setAutoplayInterval(interval || opts.autoplay);
            changeAutoplay();

            return this;
        };

        that.stopAutoplay = function () {
            if (that.autoplay) {
                pausedAutoplayFLAG = stoppedAutoplayFLAG = true;
                changeAutoplay();
            }
            return this;
        };

        that.show = function (options) {
            ////console.log('that.show');
            //////console.time('that.show prepare');
            var index;

            if (typeof options !== 'object') {
                index = options;
                options = {};
            } else {
                index = options.index;
            }

            index = index === '>' ? dirtyIndex + 1 : index === '<' ? dirtyIndex - 1 : index === '<<' ? 0 : index === '>>' ? size - 1 : index;
            index = isNaN(index) ? getIndexFromHash(index, data, true) : index;
            index = typeof index === 'undefined' ? activeIndex || 0 : index;

            that.activeIndex = activeIndex = edgeIndex(index);
            prevIndex = getPrevIndex(activeIndex);
            nextIndex = getNextIndex(activeIndex);
            nextAutoplayIndex = normalizeIndex(activeIndex + (o_rtl ? -1 : 1));
            activeIndexes = [activeIndex, prevIndex, nextIndex];

            dirtyIndex = o_loop ? index : activeIndex;

            var diffIndex = Math.abs(lastActiveIndex - dirtyIndex),
                time = getNumber(options.time, function () {
                    return Math.min(o_transitionDuration * (1 + (diffIndex - 1) / 12), o_transitionDuration * 2);
                }),
                overPos = options.overPos;

            if (options.slow) time *= 10;

            var _activeFrame = activeFrame;
            that.activeFrame = activeFrame = data[activeIndex];
            //////console.timeEnd('that.show prepare');

            var silent = _activeFrame === activeFrame && !options.user;

            //setTimeout(function () {
            //////console.time('unloadVideo');
            unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i);
            //////console.timeEnd('unloadVideo');
            //////console.time('frameDraw');
            frameDraw(activeIndexes, 'stage');
            //////console.timeEnd('frameDraw');
            //////console.time('stageFramePosition');
            stageFramePosition(SLOW ? [dirtyIndex] : [dirtyIndex, getPrevIndex(dirtyIndex), getNextIndex(dirtyIndex)]);
            //////console.timeEnd('stageFramePosition');
            //////console.time('updateTouchTails');
            updateTouchTails('go', true);
            //////console.timeEnd('updateTouchTails');
            //////console.time('triggerEvent');

            silent || triggerEvent('show', {
                user: options.user,
                time: time
            });
            //////console.timeEnd('triggerEvent');
            //}, 0);

            //////console.time('bind onEnd');

            pausedAutoplayFLAG = true;

            var onEnd = that.show.onEnd = function (skipReposition) {
                if (onEnd.ok) return;
                onEnd.ok = true;

                skipReposition || stageShaftReposition(true);

                if (!silent) {
                    triggerEvent('showend', {
                        user: options.user
                    });
                }

                ////console.log('o_transition', o_transition);

                if (!skipReposition && o_transition && o_transition !== opts.transition) {
                    ////console.log('set transition back to: ' + o_transition);
                    that.setOptions({ transition: o_transition });
                    o_transition = false;
                    return;
                }

                updateFotoramaState();
                loadImg(activeIndexes, 'stage');

                updateTouchTails('go', false);
                stageWheelUpdate();

                stageCursor();
                releaseAutoplay();
                changeAutoplay();
            };
            //////console.timeEnd('bind onEnd');

            if (!o_fade) {
                //////console.time('slide');
                slide($stageShaft, {
                    pos: -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex),
                    overPos: overPos,
                    time: time,
                    onEnd: onEnd/*,
        _001: true*/
                });
                //////console.timeEnd('slide');
            } else {
                var $activeFrame = activeFrame[STAGE_FRAME_KEY],
                    $prevActiveFrame = activeIndex !== lastActiveIndex ? data[lastActiveIndex][STAGE_FRAME_KEY] : null;

                fade($activeFrame, $prevActiveFrame, $stageFrame, {
                    time: time,
                    method: opts.transition,
                    onEnd: onEnd
                }, fadeStack);
            }

            //////console.time('arrsUpdate');
            arrsUpdate();
            //////console.timeEnd('arrsUpdate');

            if (o_nav) {
                //////console.time('navUpdate');
                navUpdate();
                //////console.timeEnd('navUpdate');

                //////console.time('slideNavShaft');
                var guessIndex = limitIndex(activeIndex + minMaxLimit(dirtyIndex - lastActiveIndex, -1, 1));
                slideNavShaft({ time: time, coo: guessIndex !== activeIndex && options.coo, guessIndex: typeof options.coo !== 'undefined' ? guessIndex : activeIndex, keep: silent });
                //////console.timeEnd('slideNavShaft');

                //////console.time('slideThumbBorder');
                if (o_navThumbs) slideThumbBorder(time);
                //////console.timeEnd('slideThumbBorder');
            }

            //////console.time('that.show end');
            showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;
            lastActiveIndex = activeIndex;
            opts.hash && showedFLAG && !that.eq && setHash(activeFrame.id || activeIndex + 1);
            //////console.timeEnd('that.show end');

            //////console.timeEnd('that.show');

            return this;
        };

        that.requestFullScreen = function () {
            if (o_allowFullScreen && !that.fullScreen) {
                scrollTop = $WINDOW.scrollTop();
                scrollLeft = $WINDOW.scrollLeft();

                lockScroll($WINDOW);

                updateTouchTails('x', true);

                measuresStash = $.extend({}, measures);

                $fotorama
                    .addClass(fullscreenClass)
                    .appendTo($BODY.addClass(_fullscreenClass));

                $HTML.addClass(_fullscreenClass);

                unloadVideo($videoPlaying, true, true);

                that.fullScreen = true;

                if (o_nativeFullScreen) {
                    fullScreenApi.request(fotorama);
                }

                that.resize();
                loadImg(activeIndexes, 'stage');
                updateFotoramaState();

                triggerEvent('fullscreenenter');
            }

            return this;
        };

        function cancelFullScreen() {
            if (that.fullScreen) {
                that.fullScreen = false;

                if (FULLSCREEN) {
                    fullScreenApi.cancel(fotorama);
                }

                $BODY.removeClass(_fullscreenClass);
                $HTML.removeClass(_fullscreenClass);

                $fotorama
                    .removeClass(fullscreenClass)
                    .insertAfter($anchor);

                measures = $.extend({}, measuresStash);

                unloadVideo($videoPlaying, true, true);

                updateTouchTails('x', false);

                that.resize();
                loadImg(activeIndexes, 'stage');

                lockScroll($WINDOW, scrollLeft, scrollTop);

                triggerEvent('fullscreenexit');
            }
        }

        that.cancelFullScreen = function () {
            if (o_nativeFullScreen && fullScreenApi.is()) {
                fullScreenApi.cancel(document);
            } else {
                cancelFullScreen();
            }

            return this;
        };

        that.toggleFullScreen = function () {
            return that[(that.fullScreen ? 'cancel' : 'request') + 'FullScreen']();
        };

        addEvent(document, fullScreenApi.event, function () {
            if (data && !fullScreenApi.is() && !$videoPlaying) {
                cancelFullScreen();
            }
        });

        that.resize = function (options) {
            if (!data) return this;

            var time = arguments[1] || 0,
                setFLAG = arguments[2];

            extendMeasures(!that.fullScreen ? optionsToLowerCase(options) : { width: '100%', maxwidth: null, minwidth: null, height: '100%', maxheight: null, minheight: null }, [measures, setFLAG || that.fullScreen || opts]);

            var width = measures.width,
                height = measures.height,
                ratio = measures.ratio,
                windowHeight = $WINDOW.height() - (o_nav ? $nav.height() : 0);

            if (measureIsValid(width)) {
                $wrap
                    .addClass(wrapOnlyActiveClass)
                    .css({ width: width, minWidth: measures.minwidth || 0, maxWidth: measures.maxwidth || MAX_WIDTH });

                width = measures.W = measures.w = $wrap.width();
                measures.nw = o_nav && numberFromWhatever(opts.navwidth, width) || width;

                if (opts.glimpse) {
                    // Glimpse
                    measures.w -= Math.round((numberFromWhatever(opts.glimpse, width) || 0) * 2);
                }

                $stageShaft.css({ width: measures.w, marginLeft: (measures.W - measures.w) / 2 });

                //////console.log('measures.W', measures.W);
                //////console.log('measures.w', measures.w);

                height = numberFromWhatever(height, windowHeight);

                height = height || (ratio && width / ratio);

                if (height) {
                    width = Math.round(width);
                    height = measures.h = Math.round(minMaxLimit(height, numberFromWhatever(measures.minheight, windowHeight), numberFromWhatever(measures.maxheight, windowHeight)));

                    $stage
                        .stop()
                        .animate({ width: width, height: height }, time, function () {
                            $wrap.removeClass(wrapOnlyActiveClass);
                        });

                    stageShaftReposition();

                    if (o_nav) {
                        $nav
                            .stop()
                            .animate({ width: measures.nw }, time);

                        slideNavShaft({ guessIndex: activeIndex, time: time, keep: true });
                        if (o_navThumbs && frameAppend.nav) slideThumbBorder(time);
                    }

                    measuresSetFLAG = setFLAG || true;

                    ready();
                }
            }

            stageLeft = $stage.offset().left;

            return this;
        };

        that.setOptions = function (options) {
            $.extend(opts, options);
            reset();
            return this;
        };

        that.shuffle = function () {
            data && shuffle(data) && reset();
            return this;
        };

        function setShadow($el, edge) {
            //////console.time('setShadow');
            if (o_shadows) {
                $el.removeClass(shadowsLeftClass + ' ' + shadowsRightClass);
                edge && !$videoPlaying && $el.addClass(edge.replace(/^|\s/g, ' ' + shadowsClass + '--'));
            }
            //////console.timeEnd('setShadow');
        }

        that.destroy = function () {
            that.cancelFullScreen();
            that.stopAutoplay();

            data = that.data = null;

            appendElements();

            activeIndexes = [];
            detachFrames(STAGE_FRAME_KEY);

            reset.ok = false;

            return this;
        };

        that.playVideo = function () {
            var dataFrame = activeFrame,
                video = dataFrame.video,
                _activeIndex = activeIndex;

            if (typeof video === 'object' && dataFrame.videoReady) {
                o_nativeFullScreen && that.fullScreen && that.cancelFullScreen();

                waitFor(function () {
                    return !fullScreenApi.is() || _activeIndex !== activeIndex;
                }, function () {
                    if (_activeIndex === activeIndex) {
                        dataFrame.$video = dataFrame.$video || $($.Fotorama.jst.video(video));
                        dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);

                        $wrap.addClass(wrapVideoClass);
                        $videoPlaying = dataFrame.$video;

                        stageNoMove();

                        $arrs.blur();
                        $fullscreenIcon.blur();

                        triggerEvent('loadvideo');
                    }
                });
            }

            return this;
        };

        that.stopVideo = function () {
            unloadVideo($videoPlaying, true, true);
            return this;
        };

        function unloadVideo($video, unloadActiveFLAG, releaseAutoplayFLAG) {
            if (unloadActiveFLAG) {
                $wrap.removeClass(wrapVideoClass);
                $videoPlaying = false;

                stageNoMove();
            }

            if ($video && $video !== $videoPlaying) {
                $video.remove();
                triggerEvent('unloadvideo');
            }

            if (releaseAutoplayFLAG) {
                releaseAutoplay();
                changeAutoplay();
            }
        }

        function toggleControlsClass(FLAG) {
            $wrap.toggleClass(wrapNoControlsClass, FLAG);
        }

        function stageCursor(e) {
            if (stageShaftTouchTail.flow) return;

            var x = e ? e.pageX : stageCursor.x,
                pointerFLAG = x && !disableDirrection(getDirection(x)) && opts.click;

            if (stageCursor.p !== pointerFLAG
                && $stage.toggleClass(pointerClass, pointerFLAG)) {
                stageCursor.p = pointerFLAG;
                stageCursor.x = x;
            }
        }

        $stage.on('mousemove', stageCursor);

        function clickToShow(showOptions) {
            clearTimeout(clickToShow.t);

            if (opts.clicktransition && opts.clicktransition !== opts.transition) {
                ////console.log('change transition to: ' + opts.clicktransition);

                // this timeout is for yield events flow
                setTimeout(function () {
                    // save original transition for later
                    var _o_transition = opts.transition;

                    that.setOptions({ transition: opts.clicktransition });

                    // now safe to pass base transition to o_transition, so that.show will restor it
                    o_transition = _o_transition;
                    // this timeout is here to prevent jerking in some browsers
                    clickToShow.t = setTimeout(function () {
                        that.show(showOptions);
                    }, 10);
                }, 0);
            } else {
                that.show(showOptions);
            }
        }

        function onStageTap(e, toggleControlsFLAG) {
            //////console.time('onStageTap');
            var target = e.target,
                $target = $(target);

            if ($target.hasClass(videoPlayClass)) {
                that.playVideo();
            } else if (target === fullscreenIcon) {
                that.toggleFullScreen();
            } else if ($videoPlaying) {
                target === videoClose && unloadVideo($videoPlaying, true, true);
            } else {
                if (toggleControlsFLAG) {
                    toggleControlsClass();
                } else if (opts.click) {

                    clickToShow({ index: e.shiftKey || getDirectionSign(getDirection(e._x)), slow: e.altKey, user: true });
                }
            }
            //////console.timeEnd('onStageTap');
        }

        function updateTouchTails(key, value) {
            stageShaftTouchTail[key] = navShaftTouchTail[key] = value;
        }

        stageShaftTouchTail = moveOnTouch($stageShaft, {
            onStart: onTouchStart,
            onMove: function (e, result) {
                setShadow($stage, result.edge);
            },
            onTouchEnd: onTouchEnd,
            onEnd: function (result) {
                //////console.time('stageShaftTouchTail.onEnd');
                setShadow($stage);

                //////console.log('result', result);

                var toggleControlsFLAG = (MS_POINTER && !hoverFLAG || result.touch) && opts.arrows && opts.arrows !== 'always';

                if (result.moved || (toggleControlsFLAG && result.pos !== result.newPos && !result.control)) {
                    var index = getIndexByPos(result.newPos, measures.w, opts.margin, repositionIndex);
                    that.show({
                        index: index,
                        time: o_fade ? o_transitionDuration : result.time,
                        overPos: result.overPos,
                        user: true
                    });
                } else if (!result.aborted && !result.control) {
                    onStageTap(result.startEvent, toggleControlsFLAG);
                }
                //////console.timeEnd('stageShaftTouchTail.onEnd');
            },
            //    getPos: function () {
            //      return -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex);
            //    },
            //_001: true,
            timeLow: 1,
            timeHigh: 1,
            friction: 2,
            select: '.' + selectClass + ', .' + selectClass + ' *',
            $wrap: $stage
        });

        navShaftTouchTail = moveOnTouch($navShaft, {
            onStart: onTouchStart,
            onMove: function (e, result) {
                setShadow($nav, result.edge);
            },
            onTouchEnd: onTouchEnd,
            onEnd: function (result) {

                function onEnd() {
                    slideNavShaft.l = result.newPos;
                    releaseAutoplay();
                    changeAutoplay();
                    thumbsDraw(result.newPos, true);
                }

                if (!result.moved) {
                    var target = result.$target.closest('.' + navFrameClass, $navShaft)[0];
                    target && onNavFrameClick.call(target, result.startEvent);
                } else if (result.pos !== result.newPos) {
                    pausedAutoplayFLAG = true;
                    slide($navShaft, {
                        time: result.time,
                        pos: result.newPos,
                        overPos: result.overPos,
                        onEnd: onEnd
                    });
                    thumbsDraw(result.newPos);
                    o_shadows && setShadow($nav, findShadowEdge(result.newPos, navShaftTouchTail.min, navShaftTouchTail.max));
                } else {
                    onEnd();
                }
            },
            timeLow: .5,
            timeHigh: 2,
            friction: 5,
            $wrap: $nav
        });

        stageWheelTail = wheel($stage, {
            shift: true,
            onEnd: function (e, direction) {
                //////console.log('wheel $stage onEnd', direction);
                onTouchStart();
                onTouchEnd();
                that.show({ index: direction, slow: e.altKey })
            }
        });

        navWheelTail = wheel($nav, {
            onEnd: function (e, direction) {
                //////console.log('wheel $nav onEnd', direction);
                onTouchStart();
                onTouchEnd();
                var newPos = stop($navShaft) + direction * .25;
                $navShaft.css(getTranslate(minMaxLimit(newPos, navShaftTouchTail.min, navShaftTouchTail.max)));
                o_shadows && setShadow($nav, findShadowEdge(newPos, navShaftTouchTail.min, navShaftTouchTail.max));
                navWheelTail.prevent = { '<': newPos >= navShaftTouchTail.max, '>': newPos <= navShaftTouchTail.min };
                clearTimeout(navWheelTail.t);
                navWheelTail.t = setTimeout(function () {
                    slideNavShaft.l = newPos;
                    thumbsDraw(newPos, true)
                }, TOUCH_TIMEOUT);
                thumbsDraw(newPos);
            }
        });

        $wrap.hover(
            function () {
                setTimeout(function () {
                    if (touchedFLAG) return;
                    toggleControlsClass(!(hoverFLAG = true));
                }, 0);
            }, function () {
                if (!hoverFLAG) return;
                toggleControlsClass(!(hoverFLAG = false));
            }
        );

        function onNavFrameClick(e) {
            var index = $(this).data().eq;
            clickToShow({ index: index, slow: e.altKey, user: true, coo: e._x - $nav.offset().left });
        }

        function onArrClick(e) {
            clickToShow({ index: $arrs.index(this) ? '>' : '<', slow: e.altKey, user: true });
        }

        smartClick($arrs, function (e) {
            stopEvent(e);
            onArrClick.call(this, e);
        }, {
            onStart: function () {
                onTouchStart();
                stageShaftTouchTail.control = true;
            },
            onTouchEnd: onTouchEnd
        });

        function addFocusOnControls(el) {
            addFocus(el, function () {
                setTimeout(function () {
                    lockScroll($stage);
                }, 0);
                toggleControlsClass(false);
            });
        }

        $arrs.each(function () {
            addEnterUp(this, function (e) {
                onArrClick.call(this, e);
            });
            addFocusOnControls(this);
        });

        addEnterUp(fullscreenIcon, that.toggleFullScreen);
        addFocusOnControls(fullscreenIcon);

        function reset() {
            setData();
            setOptions();

            if (!reset.i) {
                reset.i = true;
                // Only once
                var _startindex = opts.startindex;
                if (_startindex || opts.hash && location.hash) {
                    startIndex = getIndexFromHash(_startindex || location.hash.replace(/^#/, ''), data, that.index === 0 || _startindex, _startindex);
                }
                activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex = edgeIndex(startIndex) || 0;/*(o_rtl ? size - 1 : 0)*///;
            }

            if (size) {
                if (changeToRtl()) return;

                if ($videoPlaying) {
                    unloadVideo($videoPlaying, true);
                }

                activeIndexes = [];
                detachFrames(STAGE_FRAME_KEY);

                reset.ok = true;

                that.show({ index: activeIndex, time: 0 });
                that.resize();
            } else {
                that.destroy();
            }
        }

        function changeToRtl() {
            //////console.log('changeToRtl');
            if (!changeToRtl.f === o_rtl) {
                changeToRtl.f = o_rtl;
                activeIndex = size - 1 - activeIndex;
                //////console.log('changeToRtl execute, activeIndex is', activeIndex);
                that.reverse();

                return true;
            }
        }

        $.each('load push pop shift unshift reverse sort splice'.split(' '), function (i, method) {
            that[method] = function () {
                data = data || [];
                if (method !== 'load') {
                    Array.prototype[method].apply(data, arguments);
                } else if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].length) {
                    data = clone(arguments[0]);
                }
                reset();
                return that;
            }
        });

        function ready() {
            if (!ready.ok) {
                ready.ok = true;
                triggerEvent('ready');
            }
        }

        reset();
    };


    $.fn.fotorama = function (opts) {
        return this.each(function () {
            var that = this,
                $fotorama = $(this),
                fotoramaData = $fotorama.data(),
                fotorama = fotoramaData.fotorama;

            if (!fotorama) {
                waitFor(function () {
                    return !isHidden(that);
                }, function () {
                    fotoramaData.urtext = $fotorama.html();
                    new $.Fotorama($fotorama,
                        /* Priority for options:
                         * 1. <div data-loop="true"></div>
                         * 2. $('div').fotorama({loop: false})
                         * 3. Defaults */
                        $.extend(
                            {},
                            OPTIONS,
                            window.fotoramaDefaults,
                            opts,
                            fotoramaData
                        )
                    );
                });
            } else {
                fotorama.setOptions(opts, true);
            }
        });
    };
    $.Fotorama.instances = [];

    function calculateIndexes() {
        $.each($.Fotorama.instances, function (index, instance) {
            instance.index = index;
        });
    }

    function addInstance(instance) {
        $.Fotorama.instances.push(instance);
        calculateIndexes();
    }

    function hideInstance(instance) {
        $.Fotorama.instances.splice(instance.index, 1);
        calculateIndexes();
    }
    $.Fotorama.cache = {};
    $.Fotorama.measures = {};
    $ = $ || {};
    $.Fotorama = $.Fotorama || {};
    $.Fotorama.jst = $.Fotorama.jst || {};

    $.Fotorama.jst.style = function (v) {
        var __t, __p = '', __e = _.escape;
        __p += '.fotorama' +
        ((__t = (v.s)) == null ? '' : __t) +
        ' .fotorama__nav--thumbs .fotorama__nav__frame{\npadding:' +
        ((__t = (v.m)) == null ? '' : __t) +
        'px;\nheight:' +
        ((__t = (v.h)) == null ? '' : __t) +
        'px}\n.fotorama' +
        ((__t = (v.s)) == null ? '' : __t) +
        ' .fotorama__thumb-border{\nheight:' +
        ((__t = (v.h - v.b * (v.q ? 0 : 2))) == null ? '' : __t) +
        'px;\nborder-width:' +
        ((__t = (v.b)) == null ? '' : __t) +
        'px;\nmargin-top:' +
        ((__t = (v.m)) == null ? '' : __t) +
        'px}';
        return __p
    };

    $.Fotorama.jst.video = function (v) {
        var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
        function print() { __p += __j.call(arguments, '') }
        __p += '<div class="fotorama__video"><iframe src="';
        print((v.type == 'youtube' ? v.p + 'youtube.com/embed/' + v.id + '?autoplay=1' : v.type == 'vimeo' ? v.p + 'player.vimeo.com/video/' + v.id + '?autoplay=1&badge=0' : v.id) + (v.s && v.type != 'custom' ? '&' + v.s : ''));
        __p += '" frameborder="0" allowfullscreen></iframe></div>\n';
        return __p
    };
    $(function () {
        $('.' + _fotoramaClass + ':not([data-auto="false"])').fotorama();
    });
})(window, document, location, typeof jQuery !== 'undefined' && jQuery);
;
/* perfect-scrollbar v0.6.12 */
!function t(e,n,r){function o(i,a){if(!n[i]){if(!e[i]){var s="function"==typeof require&&require;if(!a&&s)return s(i,!0);if(l)return l(i,!0);var c=new Error("Cannot find module '"+i+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[i]={exports:{}};e[i][0].call(u.exports,function(t){var n=e[i][1][t];return o(n?n:t)},u,u.exports,t,e,n,r)}return n[i].exports}for(var l="function"==typeof require&&require,i=0;i<r.length;i++)o(r[i]);return o}({1:[function(t,e,n){"use strict";var r=t("../main");"function"==typeof define&&define.amd?define(r):(window.PerfectScrollbar=r,"undefined"==typeof window.Ps&&(window.Ps=r))},{"../main":7}],2:[function(t,e,n){"use strict";function r(t,e){var n=t.className.split(" ");n.indexOf(e)<0&&n.push(e),t.className=n.join(" ")}function o(t,e){var n=t.className.split(" "),r=n.indexOf(e);r>=0&&n.splice(r,1),t.className=n.join(" ")}n.add=function(t,e){t.classList?t.classList.add(e):r(t,e)},n.remove=function(t,e){t.classList?t.classList.remove(e):o(t,e)},n.list=function(t){return t.classList?Array.prototype.slice.apply(t.classList):t.className.split(" ")}},{}],3:[function(t,e,n){"use strict";function r(t,e){return window.getComputedStyle(t)[e]}function o(t,e,n){return"number"==typeof n&&(n=n.toString()+"px"),t.style[e]=n,t}function l(t,e){for(var n in e){var r=e[n];"number"==typeof r&&(r=r.toString()+"px"),t.style[n]=r}return t}var i={};i.e=function(t,e){var n=document.createElement(t);return n.className=e,n},i.appendTo=function(t,e){return e.appendChild(t),t},i.css=function(t,e,n){return"object"==typeof e?l(t,e):"undefined"==typeof n?r(t,e):o(t,e,n)},i.matches=function(t,e){return"undefined"!=typeof t.matches?t.matches(e):"undefined"!=typeof t.matchesSelector?t.matchesSelector(e):"undefined"!=typeof t.webkitMatchesSelector?t.webkitMatchesSelector(e):"undefined"!=typeof t.mozMatchesSelector?t.mozMatchesSelector(e):"undefined"!=typeof t.msMatchesSelector?t.msMatchesSelector(e):void 0},i.remove=function(t){"undefined"!=typeof t.remove?t.remove():t.parentNode&&t.parentNode.removeChild(t)},i.queryChildren=function(t,e){return Array.prototype.filter.call(t.childNodes,function(t){return i.matches(t,e)})},e.exports=i},{}],4:[function(t,e,n){"use strict";var r=function(t){this.element=t,this.events={}};r.prototype.bind=function(t,e){"undefined"==typeof this.events[t]&&(this.events[t]=[]),this.events[t].push(e),this.element.addEventListener(t,e,!1)},r.prototype.unbind=function(t,e){var n="undefined"!=typeof e;this.events[t]=this.events[t].filter(function(r){return!(!n||r===e)||(this.element.removeEventListener(t,r,!1),!1)},this)},r.prototype.unbindAll=function(){for(var t in this.events)this.unbind(t)};var o=function(){this.eventElements=[]};o.prototype.eventElement=function(t){var e=this.eventElements.filter(function(e){return e.element===t})[0];return"undefined"==typeof e&&(e=new r(t),this.eventElements.push(e)),e},o.prototype.bind=function(t,e,n){this.eventElement(t).bind(e,n)},o.prototype.unbind=function(t,e,n){this.eventElement(t).unbind(e,n)},o.prototype.unbindAll=function(){for(var t=0;t<this.eventElements.length;t++)this.eventElements[t].unbindAll()},o.prototype.once=function(t,e,n){var r=this.eventElement(t),o=function(t){r.unbind(e,o),n(t)};r.bind(e,o)},e.exports=o},{}],5:[function(t,e,n){"use strict";e.exports=function(){function t(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()}}()},{}],6:[function(t,e,n){"use strict";var r=t("./class"),o=t("./dom"),l=n.toInt=function(t){return parseInt(t,10)||0},i=n.clone=function(t){if(null===t)return null;if(t.constructor===Array)return t.map(i);if("object"==typeof t){var e={};for(var n in t)e[n]=i(t[n]);return e}return t};n.extend=function(t,e){var n=i(t);for(var r in e)n[r]=i(e[r]);return n},n.isEditable=function(t){return o.matches(t,"input,[contenteditable]")||o.matches(t,"select,[contenteditable]")||o.matches(t,"textarea,[contenteditable]")||o.matches(t,"button,[contenteditable]")},n.removePsClasses=function(t){for(var e=r.list(t),n=0;n<e.length;n++){var o=e[n];0===o.indexOf("ps-")&&r.remove(t,o)}},n.outerWidth=function(t){return l(o.css(t,"width"))+l(o.css(t,"paddingLeft"))+l(o.css(t,"paddingRight"))+l(o.css(t,"borderLeftWidth"))+l(o.css(t,"borderRightWidth"))},n.startScrolling=function(t,e){r.add(t,"ps-in-scrolling"),"undefined"!=typeof e?r.add(t,"ps-"+e):(r.add(t,"ps-x"),r.add(t,"ps-y"))},n.stopScrolling=function(t,e){r.remove(t,"ps-in-scrolling"),"undefined"!=typeof e?r.remove(t,"ps-"+e):(r.remove(t,"ps-x"),r.remove(t,"ps-y"))},n.env={isWebKit:"WebkitAppearance"in document.documentElement.style,supportsTouch:"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,supportsIePointer:null!==window.navigator.msMaxTouchPoints}},{"./class":2,"./dom":3}],7:[function(t,e,n){"use strict";var r=t("./plugin/destroy"),o=t("./plugin/initialize"),l=t("./plugin/update");e.exports={initialize:o,update:l,destroy:r}},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(t,e,n){"use strict";e.exports={handlers:["click-rail","drag-scrollbar","keyboard","wheel","touch"],maxScrollbarLength:null,minScrollbarLength:null,scrollXMarginOffset:0,scrollYMarginOffset:0,stopPropagationOnClick:!0,suppressScrollX:!1,suppressScrollY:!1,swipePropagation:!0,useBothWheelAxes:!1,wheelPropagation:!1,wheelSpeed:1,theme:"default"}},{}],9:[function(t,e,n){"use strict";var r=t("../lib/helper"),o=t("../lib/dom"),l=t("./instances");e.exports=function(t){var e=l.get(t);e&&(e.event.unbindAll(),o.remove(e.scrollbarX),o.remove(e.scrollbarY),o.remove(e.scrollbarXRail),o.remove(e.scrollbarYRail),r.removePsClasses(t),l.remove(t))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(t,e,n){"use strict";function r(t,e){function n(t){return t.getBoundingClientRect()}var r=function(t){t.stopPropagation()};e.settings.stopPropagationOnClick&&e.event.bind(e.scrollbarY,"click",r),e.event.bind(e.scrollbarYRail,"click",function(r){var l=o.toInt(e.scrollbarYHeight/2),s=e.railYRatio*(r.pageY-window.pageYOffset-n(e.scrollbarYRail).top-l),c=e.railYRatio*(e.railYHeight-e.scrollbarYHeight),u=s/c;u<0?u=0:u>1&&(u=1),a(t,"top",(e.contentHeight-e.containerHeight)*u),i(t),r.stopPropagation()}),e.settings.stopPropagationOnClick&&e.event.bind(e.scrollbarX,"click",r),e.event.bind(e.scrollbarXRail,"click",function(r){var l=o.toInt(e.scrollbarXWidth/2),s=e.railXRatio*(r.pageX-window.pageXOffset-n(e.scrollbarXRail).left-l),c=e.railXRatio*(e.railXWidth-e.scrollbarXWidth),u=s/c;u<0?u=0:u>1&&(u=1),a(t,"left",(e.contentWidth-e.containerWidth)*u-e.negativeScrollAdjustment),i(t),r.stopPropagation()})}var o=t("../../lib/helper"),l=t("../instances"),i=t("../update-geometry"),a=t("../update-scroll");e.exports=function(t){var e=l.get(t);r(t,e)}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(t,e,n){"use strict";function r(t,e){function n(n){var o=r+n*e.railXRatio,i=Math.max(0,e.scrollbarXRail.getBoundingClientRect().left)+e.railXRatio*(e.railXWidth-e.scrollbarXWidth);o<0?e.scrollbarXLeft=0:o>i?e.scrollbarXLeft=i:e.scrollbarXLeft=o;var a=l.toInt(e.scrollbarXLeft*(e.contentWidth-e.containerWidth)/(e.containerWidth-e.railXRatio*e.scrollbarXWidth))-e.negativeScrollAdjustment;c(t,"left",a)}var r=null,o=null,a=function(e){n(e.pageX-o),s(t),e.stopPropagation(),e.preventDefault()},u=function(){l.stopScrolling(t,"x"),e.event.unbind(e.ownerDocument,"mousemove",a)};e.event.bind(e.scrollbarX,"mousedown",function(n){o=n.pageX,r=l.toInt(i.css(e.scrollbarX,"left"))*e.railXRatio,l.startScrolling(t,"x"),e.event.bind(e.ownerDocument,"mousemove",a),e.event.once(e.ownerDocument,"mouseup",u),n.stopPropagation(),n.preventDefault()})}function o(t,e){function n(n){var o=r+n*e.railYRatio,i=Math.max(0,e.scrollbarYRail.getBoundingClientRect().top)+e.railYRatio*(e.railYHeight-e.scrollbarYHeight);o<0?e.scrollbarYTop=0:o>i?e.scrollbarYTop=i:e.scrollbarYTop=o;var a=l.toInt(e.scrollbarYTop*(e.contentHeight-e.containerHeight)/(e.containerHeight-e.railYRatio*e.scrollbarYHeight));c(t,"top",a)}var r=null,o=null,a=function(e){n(e.pageY-o),s(t),e.stopPropagation(),e.preventDefault()},u=function(){l.stopScrolling(t,"y"),e.event.unbind(e.ownerDocument,"mousemove",a)};e.event.bind(e.scrollbarY,"mousedown",function(n){o=n.pageY,r=l.toInt(i.css(e.scrollbarY,"top"))*e.railYRatio,l.startScrolling(t,"y"),e.event.bind(e.ownerDocument,"mousemove",a),e.event.once(e.ownerDocument,"mouseup",u),n.stopPropagation(),n.preventDefault()})}var l=t("../../lib/helper"),i=t("../../lib/dom"),a=t("../instances"),s=t("../update-geometry"),c=t("../update-scroll");e.exports=function(t){var e=a.get(t);r(t,e),o(t,e)}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(t,e,n){"use strict";function r(t,e){function n(n,r){var o=t.scrollTop;if(0===n){if(!e.scrollbarYActive)return!1;if(0===o&&r>0||o>=e.contentHeight-e.containerHeight&&r<0)return!e.settings.wheelPropagation}var l=t.scrollLeft;if(0===r){if(!e.scrollbarXActive)return!1;if(0===l&&n<0||l>=e.contentWidth-e.containerWidth&&n>0)return!e.settings.wheelPropagation}return!0}var r=!1;e.event.bind(t,"mouseenter",function(){r=!0}),e.event.bind(t,"mouseleave",function(){r=!1});var i=!1;e.event.bind(e.ownerDocument,"keydown",function(c){if(!(c.isDefaultPrevented&&c.isDefaultPrevented()||c.defaultPrevented)){var u=l.matches(e.scrollbarX,":focus")||l.matches(e.scrollbarY,":focus");if(r||u){var d=document.activeElement?document.activeElement:e.ownerDocument.activeElement;if(d){if("IFRAME"===d.tagName)d=d.contentDocument.activeElement;else for(;d.shadowRoot;)d=d.shadowRoot.activeElement;if(o.isEditable(d))return}var p=0,f=0;switch(c.which){case 37:p=-30;break;case 38:f=30;break;case 39:p=30;break;case 40:f=-30;break;case 33:f=90;break;case 32:f=c.shiftKey?90:-90;break;case 34:f=-90;break;case 35:f=c.ctrlKey?-e.contentHeight:-e.containerHeight;break;case 36:f=c.ctrlKey?t.scrollTop:e.containerHeight;break;default:return}s(t,"top",t.scrollTop-f),s(t,"left",t.scrollLeft+p),a(t),i=n(p,f),i&&c.preventDefault()}}})}var o=t("../../lib/helper"),l=t("../../lib/dom"),i=t("../instances"),a=t("../update-geometry"),s=t("../update-scroll");e.exports=function(t){var e=i.get(t);r(t,e)}},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(t,e,n){"use strict";function r(t,e){function n(n,r){var o=t.scrollTop;if(0===n){if(!e.scrollbarYActive)return!1;if(0===o&&r>0||o>=e.contentHeight-e.containerHeight&&r<0)return!e.settings.wheelPropagation}var l=t.scrollLeft;if(0===r){if(!e.scrollbarXActive)return!1;if(0===l&&n<0||l>=e.contentWidth-e.containerWidth&&n>0)return!e.settings.wheelPropagation}return!0}function r(t){var e=t.deltaX,n=-1*t.deltaY;return"undefined"!=typeof e&&"undefined"!=typeof n||(e=-1*t.wheelDeltaX/6,n=t.wheelDeltaY/6),t.deltaMode&&1===t.deltaMode&&(e*=10,n*=10),e!==e&&n!==n&&(e=0,n=t.wheelDelta),[e,n]}function o(e,n){var r=t.querySelector("textarea:hover, select[multiple]:hover, .ps-child:hover");if(r){if("TEXTAREA"!==r.tagName&&!window.getComputedStyle(r).overflow.match(/(scroll|auto)/))return!1;var o=r.scrollHeight-r.clientHeight;if(o>0&&!(0===r.scrollTop&&n>0||r.scrollTop===o&&n<0))return!0;var l=r.scrollLeft-r.clientWidth;if(l>0&&!(0===r.scrollLeft&&e<0||r.scrollLeft===l&&e>0))return!0}return!1}function a(a){var c=r(a),u=c[0],d=c[1];o(u,d)||(s=!1,e.settings.useBothWheelAxes?e.scrollbarYActive&&!e.scrollbarXActive?(d?i(t,"top",t.scrollTop-d*e.settings.wheelSpeed):i(t,"top",t.scrollTop+u*e.settings.wheelSpeed),s=!0):e.scrollbarXActive&&!e.scrollbarYActive&&(u?i(t,"left",t.scrollLeft+u*e.settings.wheelSpeed):i(t,"left",t.scrollLeft-d*e.settings.wheelSpeed),s=!0):(i(t,"top",t.scrollTop-d*e.settings.wheelSpeed),i(t,"left",t.scrollLeft+u*e.settings.wheelSpeed)),l(t),s=s||n(u,d),s&&(a.stopPropagation(),a.preventDefault()))}var s=!1;"undefined"!=typeof window.onwheel?e.event.bind(t,"wheel",a):"undefined"!=typeof window.onmousewheel&&e.event.bind(t,"mousewheel",a)}var o=t("../instances"),l=t("../update-geometry"),i=t("../update-scroll");e.exports=function(t){var e=o.get(t);r(t,e)}},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(t,e,n){"use strict";function r(t,e){e.event.bind(t,"scroll",function(){l(t)})}var o=t("../instances"),l=t("../update-geometry");e.exports=function(t){var e=o.get(t);r(t,e)}},{"../instances":18,"../update-geometry":19}],15:[function(t,e,n){"use strict";function r(t,e){function n(){var t=window.getSelection?window.getSelection():document.getSelection?document.getSelection():"";return 0===t.toString().length?null:t.getRangeAt(0).commonAncestorContainer}function r(){c||(c=setInterval(function(){return l.get(t)?(a(t,"top",t.scrollTop+u.top),a(t,"left",t.scrollLeft+u.left),void i(t)):void clearInterval(c)},50))}function s(){c&&(clearInterval(c),c=null),o.stopScrolling(t)}var c=null,u={top:0,left:0},d=!1;e.event.bind(e.ownerDocument,"selectionchange",function(){t.contains(n())?d=!0:(d=!1,s())}),e.event.bind(window,"mouseup",function(){d&&(d=!1,s())}),e.event.bind(window,"mousemove",function(e){if(d){var n={x:e.pageX,y:e.pageY},l={left:t.offsetLeft,right:t.offsetLeft+t.offsetWidth,top:t.offsetTop,bottom:t.offsetTop+t.offsetHeight};n.x<l.left+3?(u.left=-5,o.startScrolling(t,"x")):n.x>l.right-3?(u.left=5,o.startScrolling(t,"x")):u.left=0,n.y<l.top+3?(l.top+3-n.y<5?u.top=-5:u.top=-20,o.startScrolling(t,"y")):n.y>l.bottom-3?(n.y-l.bottom+3<5?u.top=5:u.top=20,o.startScrolling(t,"y")):u.top=0,0===u.top&&0===u.left?s():r()}})}var o=t("../../lib/helper"),l=t("../instances"),i=t("../update-geometry"),a=t("../update-scroll");e.exports=function(t){var e=l.get(t);r(t,e)}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(t,e,n){"use strict";function r(t,e,n,r){function o(n,r){var o=t.scrollTop,l=t.scrollLeft,i=Math.abs(n),a=Math.abs(r);if(a>i){if(r<0&&o===e.contentHeight-e.containerHeight||r>0&&0===o)return!e.settings.swipePropagation}else if(i>a&&(n<0&&l===e.contentWidth-e.containerWidth||n>0&&0===l))return!e.settings.swipePropagation;return!0}function s(e,n){a(t,"top",t.scrollTop-n),a(t,"left",t.scrollLeft-e),i(t)}function c(){w=!0}function u(){w=!1}function d(t){return t.targetTouches?t.targetTouches[0]:t}function p(t){return!(!t.targetTouches||1!==t.targetTouches.length)||!(!t.pointerType||"mouse"===t.pointerType||t.pointerType===t.MSPOINTER_TYPE_MOUSE)}function f(t){if(p(t)){y=!0;var e=d(t);v.pageX=e.pageX,v.pageY=e.pageY,g=(new Date).getTime(),null!==Y&&clearInterval(Y),t.stopPropagation()}}function h(t){if(!y&&e.settings.swipePropagation&&f(t),!w&&y&&p(t)){var n=d(t),r={pageX:n.pageX,pageY:n.pageY},l=r.pageX-v.pageX,i=r.pageY-v.pageY;s(l,i),v=r;var a=(new Date).getTime(),c=a-g;c>0&&(m.x=l/c,m.y=i/c,g=a),o(l,i)&&(t.stopPropagation(),t.preventDefault())}}function b(){!w&&y&&(y=!1,clearInterval(Y),Y=setInterval(function(){return l.get(t)?Math.abs(m.x)<.01&&Math.abs(m.y)<.01?void clearInterval(Y):(s(30*m.x,30*m.y),m.x*=.8,void(m.y*=.8)):void clearInterval(Y)},10))}var v={},g=0,m={},Y=null,w=!1,y=!1;n&&(e.event.bind(window,"touchstart",c),e.event.bind(window,"touchend",u),e.event.bind(t,"touchstart",f),e.event.bind(t,"touchmove",h),e.event.bind(t,"touchend",b)),r&&(window.PointerEvent?(e.event.bind(window,"pointerdown",c),e.event.bind(window,"pointerup",u),e.event.bind(t,"pointerdown",f),e.event.bind(t,"pointermove",h),e.event.bind(t,"pointerup",b)):window.MSPointerEvent&&(e.event.bind(window,"MSPointerDown",c),e.event.bind(window,"MSPointerUp",u),e.event.bind(t,"MSPointerDown",f),e.event.bind(t,"MSPointerMove",h),e.event.bind(t,"MSPointerUp",b)))}var o=t("../../lib/helper"),l=t("../instances"),i=t("../update-geometry"),a=t("../update-scroll");e.exports=function(t){if(o.env.supportsTouch||o.env.supportsIePointer){var e=l.get(t);r(t,e,o.env.supportsTouch,o.env.supportsIePointer)}}},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(t,e,n){"use strict";var r=t("../lib/helper"),o=t("../lib/class"),l=t("./instances"),i=t("./update-geometry"),a={"click-rail":t("./handler/click-rail"),"drag-scrollbar":t("./handler/drag-scrollbar"),keyboard:t("./handler/keyboard"),wheel:t("./handler/mouse-wheel"),touch:t("./handler/touch"),selection:t("./handler/selection")},s=t("./handler/native-scroll");e.exports=function(t,e){e="object"==typeof e?e:{},o.add(t,"ps-container");var n=l.add(t);n.settings=r.extend(n.settings,e),o.add(t,"ps-theme-"+n.settings.theme),n.settings.handlers.forEach(function(e){a[e](t)}),s(t),i(t)}},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(t,e,n){"use strict";function r(t){function e(){s.add(t,"ps-focus")}function n(){s.remove(t,"ps-focus")}var r=this;r.settings=a.clone(c),r.containerWidth=null,r.containerHeight=null,r.contentWidth=null,r.contentHeight=null,r.isRtl="rtl"===u.css(t,"direction"),r.isNegativeScroll=function(){var e=t.scrollLeft,n=null;return t.scrollLeft=-1,n=t.scrollLeft<0,t.scrollLeft=e,n}(),r.negativeScrollAdjustment=r.isNegativeScroll?t.scrollWidth-t.clientWidth:0,r.event=new d,r.ownerDocument=t.ownerDocument||document,r.scrollbarXRail=u.appendTo(u.e("div","ps-scrollbar-x-rail"),t),r.scrollbarX=u.appendTo(u.e("div","ps-scrollbar-x"),r.scrollbarXRail),r.scrollbarX.setAttribute("tabindex",0),r.event.bind(r.scrollbarX,"focus",e),r.event.bind(r.scrollbarX,"blur",n),r.scrollbarXActive=null,r.scrollbarXWidth=null,r.scrollbarXLeft=null,r.scrollbarXBottom=a.toInt(u.css(r.scrollbarXRail,"bottom")),r.isScrollbarXUsingBottom=r.scrollbarXBottom===r.scrollbarXBottom,r.scrollbarXTop=r.isScrollbarXUsingBottom?null:a.toInt(u.css(r.scrollbarXRail,"top")),r.railBorderXWidth=a.toInt(u.css(r.scrollbarXRail,"borderLeftWidth"))+a.toInt(u.css(r.scrollbarXRail,"borderRightWidth")),u.css(r.scrollbarXRail,"display","block"),r.railXMarginWidth=a.toInt(u.css(r.scrollbarXRail,"marginLeft"))+a.toInt(u.css(r.scrollbarXRail,"marginRight")),u.css(r.scrollbarXRail,"display",""),r.railXWidth=null,r.railXRatio=null,r.scrollbarYRail=u.appendTo(u.e("div","ps-scrollbar-y-rail"),t),r.scrollbarY=u.appendTo(u.e("div","ps-scrollbar-y"),r.scrollbarYRail),r.scrollbarY.setAttribute("tabindex",0),r.event.bind(r.scrollbarY,"focus",e),r.event.bind(r.scrollbarY,"blur",n),r.scrollbarYActive=null,r.scrollbarYHeight=null,r.scrollbarYTop=null,r.scrollbarYRight=a.toInt(u.css(r.scrollbarYRail,"right")),r.isScrollbarYUsingRight=r.scrollbarYRight===r.scrollbarYRight,r.scrollbarYLeft=r.isScrollbarYUsingRight?null:a.toInt(u.css(r.scrollbarYRail,"left")),r.scrollbarYOuterWidth=r.isRtl?a.outerWidth(r.scrollbarY):null,r.railBorderYWidth=a.toInt(u.css(r.scrollbarYRail,"borderTopWidth"))+a.toInt(u.css(r.scrollbarYRail,"borderBottomWidth")),u.css(r.scrollbarYRail,"display","block"),r.railYMarginHeight=a.toInt(u.css(r.scrollbarYRail,"marginTop"))+a.toInt(u.css(r.scrollbarYRail,"marginBottom")),u.css(r.scrollbarYRail,"display",""),r.railYHeight=null,r.railYRatio=null}function o(t){return t.getAttribute("data-ps-id")}function l(t,e){t.setAttribute("data-ps-id",e)}function i(t){t.removeAttribute("data-ps-id")}var a=t("../lib/helper"),s=t("../lib/class"),c=t("./default-setting"),u=t("../lib/dom"),d=t("../lib/event-manager"),p=t("../lib/guid"),f={};n.add=function(t){var e=p();return l(t,e),f[e]=new r(t),f[e]},n.remove=function(t){delete f[o(t)],i(t)},n.get=function(t){return f[o(t)]}},{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(t,e,n){"use strict";function r(t,e){return t.settings.minScrollbarLength&&(e=Math.max(e,t.settings.minScrollbarLength)),t.settings.maxScrollbarLength&&(e=Math.min(e,t.settings.maxScrollbarLength)),e}function o(t,e){var n={width:e.railXWidth};e.isRtl?n.left=e.negativeScrollAdjustment+t.scrollLeft+e.containerWidth-e.contentWidth:n.left=t.scrollLeft,e.isScrollbarXUsingBottom?n.bottom=e.scrollbarXBottom-t.scrollTop:n.top=e.scrollbarXTop+t.scrollTop,a.css(e.scrollbarXRail,n);var r={top:t.scrollTop,height:e.railYHeight};e.isScrollbarYUsingRight?e.isRtl?r.right=e.contentWidth-(e.negativeScrollAdjustment+t.scrollLeft)-e.scrollbarYRight-e.scrollbarYOuterWidth:r.right=e.scrollbarYRight-t.scrollLeft:e.isRtl?r.left=e.negativeScrollAdjustment+t.scrollLeft+2*e.containerWidth-e.contentWidth-e.scrollbarYLeft-e.scrollbarYOuterWidth:r.left=e.scrollbarYLeft+t.scrollLeft,a.css(e.scrollbarYRail,r),a.css(e.scrollbarX,{left:e.scrollbarXLeft,width:e.scrollbarXWidth-e.railBorderXWidth}),a.css(e.scrollbarY,{top:e.scrollbarYTop,height:e.scrollbarYHeight-e.railBorderYWidth})}var l=t("../lib/helper"),i=t("../lib/class"),a=t("../lib/dom"),s=t("./instances"),c=t("./update-scroll");e.exports=function(t){var e=s.get(t);e.containerWidth=t.clientWidth,e.containerHeight=t.clientHeight,e.contentWidth=t.scrollWidth,e.contentHeight=t.scrollHeight;var n;t.contains(e.scrollbarXRail)||(n=a.queryChildren(t,".ps-scrollbar-x-rail"),n.length>0&&n.forEach(function(t){a.remove(t)}),a.appendTo(e.scrollbarXRail,t)),t.contains(e.scrollbarYRail)||(n=a.queryChildren(t,".ps-scrollbar-y-rail"),n.length>0&&n.forEach(function(t){a.remove(t)}),a.appendTo(e.scrollbarYRail,t)),!e.settings.suppressScrollX&&e.containerWidth+e.settings.scrollXMarginOffset<e.contentWidth?(e.scrollbarXActive=!0,e.railXWidth=e.containerWidth-e.railXMarginWidth,e.railXRatio=e.containerWidth/e.railXWidth,e.scrollbarXWidth=r(e,l.toInt(e.railXWidth*e.containerWidth/e.contentWidth)),e.scrollbarXLeft=l.toInt((e.negativeScrollAdjustment+t.scrollLeft)*(e.railXWidth-e.scrollbarXWidth)/(e.contentWidth-e.containerWidth))):e.scrollbarXActive=!1,!e.settings.suppressScrollY&&e.containerHeight+e.settings.scrollYMarginOffset<e.contentHeight?(e.scrollbarYActive=!0,e.railYHeight=e.containerHeight-e.railYMarginHeight,e.railYRatio=e.containerHeight/e.railYHeight,e.scrollbarYHeight=r(e,l.toInt(e.railYHeight*e.containerHeight/e.contentHeight)),e.scrollbarYTop=l.toInt(t.scrollTop*(e.railYHeight-e.scrollbarYHeight)/(e.contentHeight-e.containerHeight))):e.scrollbarYActive=!1,e.scrollbarXLeft>=e.railXWidth-e.scrollbarXWidth&&(e.scrollbarXLeft=e.railXWidth-e.scrollbarXWidth),e.scrollbarYTop>=e.railYHeight-e.scrollbarYHeight&&(e.scrollbarYTop=e.railYHeight-e.scrollbarYHeight),o(t,e),e.scrollbarXActive?i.add(t,"ps-active-x"):(i.remove(t,"ps-active-x"),e.scrollbarXWidth=0,e.scrollbarXLeft=0,c(t,"left",0)),e.scrollbarYActive?i.add(t,"ps-active-y"):(i.remove(t,"ps-active-y"),e.scrollbarYHeight=0,e.scrollbarYTop=0,c(t,"top",0))}},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(t,e,n){"use strict";var r,o,l=t("./instances"),i=document.createEvent("Event"),a=document.createEvent("Event"),s=document.createEvent("Event"),c=document.createEvent("Event"),u=document.createEvent("Event"),d=document.createEvent("Event"),p=document.createEvent("Event"),f=document.createEvent("Event"),h=document.createEvent("Event"),b=document.createEvent("Event");i.initEvent("ps-scroll-up",!0,!0),a.initEvent("ps-scroll-down",!0,!0),s.initEvent("ps-scroll-left",!0,!0),c.initEvent("ps-scroll-right",!0,!0),u.initEvent("ps-scroll-y",!0,!0),d.initEvent("ps-scroll-x",!0,!0),p.initEvent("ps-x-reach-start",!0,!0),f.initEvent("ps-x-reach-end",!0,!0),h.initEvent("ps-y-reach-start",!0,!0),b.initEvent("ps-y-reach-end",!0,!0),e.exports=function(t,e,n){if("undefined"==typeof t)throw"You must provide an element to the update-scroll function";if("undefined"==typeof e)throw"You must provide an axis to the update-scroll function";if("undefined"==typeof n)throw"You must provide a value to the update-scroll function";"top"===e&&n<=0&&(t.scrollTop=n=0,t.dispatchEvent(h)),"left"===e&&n<=0&&(t.scrollLeft=n=0,t.dispatchEvent(p));var v=l.get(t);"top"===e&&n>=v.contentHeight-v.containerHeight&&(n=v.contentHeight-v.containerHeight,n-t.scrollTop<=1?n=t.scrollTop:t.scrollTop=n,t.dispatchEvent(b)),"left"===e&&n>=v.contentWidth-v.containerWidth&&(n=v.contentWidth-v.containerWidth,n-t.scrollLeft<=1?n=t.scrollLeft:t.scrollLeft=n,t.dispatchEvent(f)),r||(r=t.scrollTop),o||(o=t.scrollLeft),"top"===e&&n<r&&t.dispatchEvent(i),"top"===e&&n>r&&t.dispatchEvent(a),"left"===e&&n<o&&t.dispatchEvent(s),"left"===e&&n>o&&t.dispatchEvent(c),"top"===e&&(t.scrollTop=r=n,t.dispatchEvent(u)),"left"===e&&(t.scrollLeft=o=n,t.dispatchEvent(d))}},{"./instances":18}],21:[function(t,e,n){"use strict";var r=t("../lib/helper"),o=t("../lib/dom"),l=t("./instances"),i=t("./update-geometry"),a=t("./update-scroll");e.exports=function(t){var e=l.get(t);e&&(e.negativeScrollAdjustment=e.isNegativeScroll?t.scrollWidth-t.clientWidth:0,o.css(e.scrollbarXRail,"display","block"),o.css(e.scrollbarYRail,"display","block"),e.railXMarginWidth=r.toInt(o.css(e.scrollbarXRail,"marginLeft"))+r.toInt(o.css(e.scrollbarXRail,"marginRight")),e.railYMarginHeight=r.toInt(o.css(e.scrollbarYRail,"marginTop"))+r.toInt(o.css(e.scrollbarYRail,"marginBottom")),o.css(e.scrollbarXRail,"display","none"),o.css(e.scrollbarYRail,"display","none"),i(t),a(t,"top",t.scrollTop),a(t,"left",t.scrollLeft),o.css(e.scrollbarXRail,"display",""),o.css(e.scrollbarYRail,"display",""))}},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]);;
/**
 * Owl Carousel v2.2.0
 * Copyright 2013-2016 David Deutsch
 * Licensed under MIT (https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE)
 */
/**
 * Owl carousel
 * @version 2.1.6
 * @author Bartosz Wojciechowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 * @todo Lazy Load Icon
 * @todo prevent animationend bubling
 * @todo itemsScaleUp
 * @todo Test Zepto
 * @todo stagePadding calculate wrong active classes
 */
; (function ($, window, document, undefined) {

    /**
	 * Creates a carousel.
	 * @class The Owl Carousel.
	 * @public
	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
	 * @param {Object} [options] - The options
	 */
    function Owl(element, options) {

        /**
		 * Current settings for the carousel.
		 * @public
		 */
        this.settings = null;

        /**
		 * Current options set by the caller including defaults.
		 * @public
		 */
        this.options = $.extend({}, Owl.Defaults, options);

        /**
		 * Plugin element.
		 * @public
		 */
        this.$element = $(element);

        /**
		 * Proxied event handlers.
		 * @protected
		 */
        this._handlers = {};

        /**
		 * References to the running plugins of this carousel.
		 * @protected
		 */
        this._plugins = {};

        /**
		 * Currently suppressed events to prevent them from beeing retriggered.
		 * @protected
		 */
        this._supress = {};

        /**
		 * Absolute current position.
		 * @protected
		 */
        this._current = null;

        /**
		 * Animation speed in milliseconds.
		 * @protected
		 */
        this._speed = null;

        /**
		 * Coordinates of all items in pixel.
		 * @todo The name of this member is missleading.
		 * @protected
		 */
        this._coordinates = [];

        /**
		 * Current breakpoint.
		 * @todo Real media queries would be nice.
		 * @protected
		 */
        this._breakpoint = null;

        /**
		 * Current width of the plugin element.
		 */
        this._width = null;

        /**
		 * All real items.
		 * @protected
		 */
        this._items = [];

        /**
		 * All cloned items.
		 * @protected
		 */
        this._clones = [];

        /**
		 * Merge values of all items.
		 * @todo Maybe this could be part of a plugin.
		 * @protected
		 */
        this._mergers = [];

        /**
		 * Widths of all items.
		 */
        this._widths = [];

        /**
		 * Invalidated parts within the update process.
		 * @protected
		 */
        this._invalidated = {};

        /**
		 * Ordered list of workers for the update process.
		 * @protected
		 */
        this._pipe = [];

        /**
		 * Current state information for the drag operation.
		 * @todo #261
		 * @protected
		 */
        this._drag = {
            time: null,
            target: null,
            pointer: null,
            stage: {
                start: null,
                current: null
            },
            direction: null
        };

        /**
		 * Current state information and their tags.
		 * @type {Object}
		 * @protected
		 */
        this._states = {
            current: {},
            tags: {
                'initializing': ['busy'],
                'animating': ['busy'],
                'dragging': ['interacting']
            }
        };

        $.each(['onResize', 'onThrottledResize'], $.proxy(function (i, handler) {
            this._handlers[handler] = $.proxy(this[handler], this);
        }, this));

        $.each(Owl.Plugins, $.proxy(function (key, plugin) {
            this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
				= new plugin(this);
        }, this));

        $.each(Owl.Workers, $.proxy(function (priority, worker) {
            this._pipe.push({
                'filter': worker.filter,
                'run': $.proxy(worker.run, this)
            });
        }, this));

        this.setup();
        this.initialize();
    }

    /**
	 * Default options for the carousel.
	 * @public
	 */
    Owl.Defaults = {
        items: 3,
        loop: false,
        center: false,
        rewind: false,

        mouseDrag: true,
        touchDrag: true,
        pullDrag: true,
        freeDrag: false,

        margin: 0,
        stagePadding: 0,

        merge: false,
        mergeFit: true,
        autoWidth: false,

        startPosition: 0,
        rtl: false,

        smartSpeed: 250,
        fluidSpeed: false,
        dragEndSpeed: false,

        responsive: {},
        responsiveRefreshRate: 200,
        responsiveBaseElement: window,

        fallbackEasing: 'swing',

        info: false,

        nestedItemSelector: false,
        itemElement: 'div',
        stageElement: 'div',

        refreshClass: 'owl-refresh',
        loadedClass: 'owl-loaded',
        loadingClass: 'owl-loading',
        rtlClass: 'owl-rtl',
        responsiveClass: 'owl-responsive',
        dragClass: 'owl-drag',
        itemClass: 'owl-item',
        stageClass: 'owl-stage',
        stageOuterClass: 'owl-stage-outer',
        grabClass: 'owl-grab'
    };

    /**
	 * Enumeration for width.
	 * @public
	 * @readonly
	 * @enum {String}
	 */
    Owl.Width = {
        Default: 'default',
        Inner: 'inner',
        Outer: 'outer'
    };

    /**
	 * Enumeration for types.
	 * @public
	 * @readonly
	 * @enum {String}
	 */
    Owl.Type = {
        Event: 'event',
        State: 'state'
    };

    /**
	 * Contains all registered plugins.
	 * @public
	 */
    Owl.Plugins = {};

    /**
	 * List of workers involved in the update process.
	 */
    Owl.Workers = [{
        filter: ['width', 'settings'],
        run: function () {
            this._width = this.$element.width();
        }
    }, {
        filter: ['width', 'items', 'settings'],
        run: function (cache) {
            cache.current = this._items && this._items[this.relative(this._current)];
        }
    }, {
        filter: ['items', 'settings'],
        run: function () {
            this.$stage.children('.cloned').remove();
        }
    }, {
        filter: ['width', 'items', 'settings'],
        run: function (cache) {
            var margin = this.settings.margin || '',
				grid = !this.settings.autoWidth,
				rtl = this.settings.rtl,
				css = {
				    'width': 'auto',
				    'margin-left': rtl ? margin : '',
				    'margin-right': rtl ? '' : margin
				};

            !grid && this.$stage.children().css(css);

            cache.css = css;
        }
    }, {
        filter: ['width', 'items', 'settings'],
        run: function (cache) {
            var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,
				merge = null,
				iterator = this._items.length,
				grid = !this.settings.autoWidth,
				widths = [];

            cache.items = {
                merge: false,
                width: width
            };

            while (iterator--) {
                merge = this._mergers[iterator];
                merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;

                cache.items.merge = merge > 1 || cache.items.merge;

                widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
            }

            this._widths = widths;
        }
    }, {
        filter: ['items', 'settings'],
        run: function () {
            var clones = [],
				items = this._items,
				settings = this.settings,
				// TODO: Should be computed from number of min width items in stage
				view = Math.max(settings.items * 2, 4),
				size = Math.ceil(items.length / 2) * 2,
				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
				append = '',
				prepend = '';

            repeat /= 2;

            while (repeat--) {
                // Switch to only using appended clones
                clones.push(this.normalize(clones.length / 2, true));
                append = append + items[clones[clones.length - 1]][0].outerHTML;
                clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
                prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
            }

            this._clones = clones;

            var $append = $(append);
            var $prepend = $(prepend);

            $append.find('a').attr('tabindex', '-1').attr('aria-hidden', 'true');
            $prepend.find('a').attr('tabindex', '-1').attr('aria-hidden', 'true');

            $append.addClass('cloned').appendTo(this.$stage);
            $prepend.addClass('cloned').prependTo(this.$stage);
        }
    }, {
        filter: ['width', 'items', 'settings'],
        run: function () {
            var rtl = this.settings.rtl ? 1 : -1,
				size = this._clones.length + this._items.length,
				iterator = -1,
				previous = 0,
				current = 0,
				coordinates = [];

            while (++iterator < size) {
                previous = coordinates[iterator - 1] || 0;
                current = this._widths[this.relative(iterator)] + this.settings.margin;
                coordinates.push(previous + current * rtl);
            }

            this._coordinates = coordinates;
        }
    }, {
        filter: ['width', 'items', 'settings'],
        run: function () {
            var padding = this.settings.stagePadding,
				coordinates = this._coordinates,
				css = {
				    'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
				    'padding-left': padding || '',
				    'padding-right': padding || ''
				};

            this.$stage.css(css);
        }
    }, {
        filter: ['width', 'items', 'settings'],
        run: function (cache) {
            var iterator = this._coordinates.length,
				grid = !this.settings.autoWidth,
				items = this.$stage.children();

            if (grid && cache.items.merge) {
                while (iterator--) {
                    cache.css.width = this._widths[this.relative(iterator)];
                    items.eq(iterator).css(cache.css);
                }
            } else if (grid) {
                cache.css.width = cache.items.width;
                items.css(cache.css);
            }
        }
    }, {
        filter: ['items'],
        run: function () {
            this._coordinates.length < 1 && this.$stage.removeAttr('style');
        }
    }, {
        filter: ['width', 'items', 'settings'],
        run: function (cache) {
            cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
            cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
            this.reset(cache.current);
        }
    }, {
        filter: ['position'],
        run: function () {
            this.animate(this.coordinates(this._current));
        }
    }, {
        filter: ['width', 'position', 'items', 'settings'],
        run: function () {
            var rtl = this.settings.rtl ? 1 : -1,
				padding = this.settings.stagePadding * 2,
				begin = this.coordinates(this.current()) + padding,
				end = begin + this.width() * rtl,
				inner, outer, matches = [], i, n;

            for (i = 0, n = this._coordinates.length; i < n; i++) {
                inner = this._coordinates[i - 1] || 0;
                outer = Math.abs(this._coordinates[i]) + padding * rtl;

                if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
                    matches.push(i);
                }
            }

            this.$stage.children('.active').removeClass('active');
            this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');

            if (this.settings.center) {
                this.$stage.children('.center').removeClass('center');
                this.$stage.children().eq(this.current()).addClass('center');
            }
        }
    }];

    /**
	 * Initializes the carousel.
	 * @protected
	 */
    Owl.prototype.initialize = function () {
        this.enter('initializing');
        this.trigger('initialize');

        this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);

        if (this.settings.autoWidth && !this.is('pre-loading')) {
            var imgs, nestedSelector, width;
            imgs = this.$element.find('img');
            nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
            width = this.$element.children(nestedSelector).width();

            if (imgs.length && width <= 0) {
                this.preloadAutoWidthImages(imgs);
            }
        }

        this.$element.addClass(this.options.loadingClass);

        // create stage
        this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')
			.wrap('<div class="' + this.settings.stageOuterClass + '"/>');

        // append stage
        this.$element.append(this.$stage.parent());

        // append content
        this.replace(this.$element.children().not(this.$stage.parent()));

        // check visibility
        if (this.$element.is(':visible')) {
            // update view
            this.refresh();
        } else {
            // invalidate width
            this.invalidate('width');
        }

        this.$element
			.removeClass(this.options.loadingClass)
			.addClass(this.options.loadedClass);

        // register event handlers
        this.registerEventHandlers();

        this.leave('initializing');
        this.trigger('initialized');
    };

    /**
	 * Setups the current settings.
	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
	 * @todo Support for media queries by using `matchMedia` would be nice.
	 * @public
	 */
    Owl.prototype.setup = function () {
        var viewport = this.viewport(),
			overwrites = this.options.responsive,
			match = -1,
			settings = null;

        if (!overwrites) {
            settings = $.extend({}, this.options);
        } else {
            $.each(overwrites, function (breakpoint) {
                if (breakpoint <= viewport && breakpoint > match) {
                    match = Number(breakpoint);
                }
            });

            settings = $.extend({}, this.options, overwrites[match]);
            if (typeof settings.stagePadding === 'function') {
                settings.stagePadding = settings.stagePadding();
            }
            delete settings.responsive;

            // responsive class
            if (settings.responsiveClass) {
                this.$element.attr('class',
					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
				);
            }
        }

        this.trigger('change', { property: { name: 'settings', value: settings } });
        this._breakpoint = match;
        this.settings = settings;
        this.invalidate('settings');
        this.trigger('changed', { property: { name: 'settings', value: this.settings } });
    };

    /**
	 * Updates option logic if necessery.
	 * @protected
	 */
    Owl.prototype.optionsLogic = function () {
        if (this.settings.autoWidth) {
            this.settings.stagePadding = false;
            this.settings.merge = false;
        }
    };

    /**
	 * Prepares an item before add.
	 * @todo Rename event parameter `content` to `item`.
	 * @protected
	 * @returns {jQuery|HTMLElement} - The item container.
	 */
    Owl.prototype.prepare = function (item) {
        var event = this.trigger('prepare', { content: item });

        if (!event.data) {
            event.data = $('<' + this.settings.itemElement + '/>')
				.addClass(this.options.itemClass).append(item)
        }

        this.trigger('prepared', { content: event.data });

        return event.data;
    };

    /**
	 * Updates the view.
	 * @public
	 */
    Owl.prototype.update = function () {
        var i = 0,
			n = this._pipe.length,
			filter = $.proxy(function (p) { return this[p] }, this._invalidated),
			cache = {};

        while (i < n) {
            if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
                this._pipe[i].run(cache);
            }
            i++;
        }

        this._invalidated = {};

        !this.is('valid') && this.enter('valid');
    };

    /**
	 * Gets the width of the view.
	 * @public
	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
	 * @returns {Number} - The width of the view in pixel.
	 */
    Owl.prototype.width = function (dimension) {
        dimension = dimension || Owl.Width.Default;
        switch (dimension) {
            case Owl.Width.Inner:
            case Owl.Width.Outer:
                return this._width;
            default:
                return this._width - this.settings.stagePadding * 2 + this.settings.margin;
        }
    };

    /**
	 * Refreshes the carousel primarily for adaptive purposes.
	 * @public
	 */
    Owl.prototype.refresh = function () {
        this.enter('refreshing');
        this.trigger('refresh');

        this.setup();

        this.optionsLogic();

        this.$element.addClass(this.options.refreshClass);

        this.update();

        this.$element.removeClass(this.options.refreshClass);

        this.leave('refreshing');
        this.trigger('refreshed');
    };

    /**
	 * Checks window `resize` event.
	 * @protected
	 */
    Owl.prototype.onThrottledResize = function () {
        window.clearTimeout(this.resizeTimer);
        this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
    };

    /**
	 * Checks window `resize` event.
	 * @protected
	 */
    Owl.prototype.onResize = function () {
        if (!this._items.length) {
            return false;
        }

        if (this._width === this.$element.width()) {
            return false;
        }

        if (!this.$element.is(':visible')) {
            return false;
        }

        this.enter('resizing');

        if (this.trigger('resize').isDefaultPrevented()) {
            this.leave('resizing');
            return false;
        }

        this.invalidate('width');

        this.refresh();

        this.leave('resizing');
        this.trigger('resized');
    };

    /**
	 * Registers event handlers.
	 * @todo Check `msPointerEnabled`
	 * @todo #261
	 * @protected
	 */
    Owl.prototype.registerEventHandlers = function () {
        if ($.support.transition) {
            this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
        }

        if (this.settings.responsive !== false) {
            this.on(window, 'resize', this._handlers.onThrottledResize);
        }

        if (this.settings.mouseDrag) {
            this.$element.addClass(this.options.dragClass);
            this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
            this.$stage.on('dragstart.owl.core selectstart.owl.core', function () { return false });
        }

        if (this.settings.touchDrag) {
            this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
            this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
        }
    };

    /**
	 * Handles `touchstart` and `mousedown` events.
	 * @todo Horizontal swipe threshold as option
	 * @todo #261
	 * @protected
	 * @param {Event} event - The event arguments.
	 */
    Owl.prototype.onDragStart = function (event) {
        var stage = null;

        if (event.which === 3) {
            return;
        }

        if ($.support.transform) {
            stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
            stage = {
                x: stage[stage.length === 16 ? 12 : 4],
                y: stage[stage.length === 16 ? 13 : 5]
            };
        } else {
            stage = this.$stage.position();
            stage = {
                x: this.settings.rtl ?
					stage.left + this.$stage.width() - this.width() + this.settings.margin :
					stage.left,
                y: stage.top
            };
        }

        if (this.is('animating')) {
            $.support.transform ? this.animate(stage.x) : this.$stage.stop()
            this.invalidate('position');
        }

        this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');

        this.speed(0);

        this._drag.time = new Date().getTime();
        this._drag.target = $(event.target);
        this._drag.stage.start = stage;
        this._drag.stage.current = stage;
        this._drag.pointer = this.pointer(event);

        $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));

        $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function (event) {
            var delta = this.difference(this._drag.pointer, this.pointer(event));

            $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));

            if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
                return;
            }

            event.preventDefault();

            this.enter('dragging');
            this.trigger('drag');
        }, this));
    };

    /**
	 * Handles the `touchmove` and `mousemove` events.
	 * @todo #261
	 * @protected
	 * @param {Event} event - The event arguments.
	 */
    Owl.prototype.onDragMove = function (event) {
        var minimum = null,
			maximum = null,
			pull = null,
			delta = this.difference(this._drag.pointer, this.pointer(event)),
			stage = this.difference(this._drag.stage.start, delta);

        if (!this.is('dragging')) {
            return;
        }

        event.preventDefault();

        if (this.settings.loop) {
            minimum = this.coordinates(this.minimum());
            maximum = this.coordinates(this.maximum() + 1) - minimum;
            stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
        } else {
            minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
            maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
            pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
            stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
        }

        this._drag.stage.current = stage;

        this.animate(stage.x);
    };

    /**
	 * Handles the `touchend` and `mouseup` events.
	 * @todo #261
	 * @todo Threshold for click event
	 * @protected
	 * @param {Event} event - The event arguments.
	 */
    Owl.prototype.onDragEnd = function (event) {
        var delta = this.difference(this._drag.pointer, this.pointer(event)),
			stage = this._drag.stage.current,
			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';

        $(document).off('.owl.core');

        this.$element.removeClass(this.options.grabClass);

        if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
            this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
            this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
            this.invalidate('position');
            this.update();

            this._drag.direction = direction;

            if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
                this._drag.target.one('click.owl.core', function () { return false; });
            }
        }

        if (!this.is('dragging')) {
            return;
        }

        this.leave('dragging');
        this.trigger('dragged');
    };

    /**
	 * Gets absolute position of the closest item for a coordinate.
	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
	 * @protected
	 * @param {Number} coordinate - The coordinate in pixel.
	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
	 * @return {Number} - The absolute position of the closest item.
	 */
    Owl.prototype.closest = function (coordinate, direction) {
        var position = -1,
			pull = 30,
			width = this.width(),
			coordinates = this.coordinates();

        if (!this.settings.freeDrag) {
            // check closest item
            $.each(coordinates, $.proxy(function (index, value) {
                // on a left pull, check on current index
                if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) {
                    position = index;
                    // on a right pull, check on previous index
                    // to do so, subtract width from value and set position = index + 1
                } else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) {
                    position = index + 1;
                } else if (this.op(coordinate, '<', value)
					&& this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
                    position = direction === 'left' ? index + 1 : index;
                }
                return position === -1;
            }, this));
        }

        if (!this.settings.loop) {
            // non loop boundries
            if (this.op(coordinate, '>', coordinates[this.minimum()])) {
                position = coordinate = this.minimum();
            } else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
                position = coordinate = this.maximum();
            }
        }

        return position;
    };

    /**
	 * Animates the stage.
	 * @todo #270
	 * @public
	 * @param {Number} coordinate - The coordinate in pixels.
	 */
    Owl.prototype.animate = function (coordinate) {
        var animate = this.speed() > 0;

        this.is('animating') && this.onTransitionEnd();

        if (animate) {
            this.enter('animating');
            this.trigger('translate');
        }

        if ($.support.transform3d && $.support.transition) {
            this.$stage.css({
                transform: 'translate3d(' + coordinate + 'px,0px,0px)',
                transition: (this.speed() / 1000) + 's'
            });
        } else if (animate) {
            this.$stage.animate({
                left: coordinate + 'px'
            }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
        } else {
            this.$stage.css({
                left: coordinate + 'px'
            });
        }
    };

    /**
	 * Checks whether the carousel is in a specific state or not.
	 * @param {String} state - The state to check.
	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
	 */
    Owl.prototype.is = function (state) {
        return this._states.current[state] && this._states.current[state] > 0;
    };

    /**
	 * Sets the absolute position of the current item.
	 * @public
	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
	 * @returns {Number} - The absolute position of the current item.
	 */
    Owl.prototype.current = function (position) {
        if (position === undefined) {
            return this._current;
        }

        if (this._items.length === 0) {
            return undefined;
        }

        position = this.normalize(position);

        if (this._current !== position) {
            var event = this.trigger('change', { property: { name: 'position', value: position } });

            if (event.data !== undefined) {
                position = this.normalize(event.data);
            }

            this._current = position;

            this.invalidate('position');

            this.trigger('changed', { property: { name: 'position', value: this._current } });
        }

        return this._current;
    };

    /**
	 * Invalidates the given part of the update routine.
	 * @param {String} [part] - The part to invalidate.
	 * @returns {Array.<String>} - The invalidated parts.
	 */
    Owl.prototype.invalidate = function (part) {
        if ($.type(part) === 'string') {
            this._invalidated[part] = true;
            this.is('valid') && this.leave('valid');
        }
        return $.map(this._invalidated, function (v, i) { return i });
    };

    /**
	 * Resets the absolute position of the current item.
	 * @public
	 * @param {Number} position - The absolute position of the new item.
	 */
    Owl.prototype.reset = function (position) {
        position = this.normalize(position);

        if (position === undefined) {
            return;
        }

        this._speed = 0;
        this._current = position;

        this.suppress(['translate', 'translated']);

        this.animate(this.coordinates(position));

        this.release(['translate', 'translated']);
    };

    /**
	 * Normalizes an absolute or a relative position of an item.
	 * @public
	 * @param {Number} position - The absolute or relative position to normalize.
	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
	 * @returns {Number} - The normalized position.
	 */
    Owl.prototype.normalize = function (position, relative) {
        var n = this._items.length,
			m = relative ? 0 : this._clones.length;

        if (!this.isNumeric(position) || n < 1) {
            position = undefined;
        } else if (position < 0 || position >= n + m) {
            position = ((position - m / 2) % n + n) % n + m / 2;
        }

        return position;
    };

    /**
	 * Converts an absolute position of an item into a relative one.
	 * @public
	 * @param {Number} position - The absolute position to convert.
	 * @returns {Number} - The converted position.
	 */
    Owl.prototype.relative = function (position) {
        position -= this._clones.length / 2;
        return this.normalize(position, true);
    };

    /**
	 * Gets the maximum position for the current item.
	 * @public
	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
	 * @returns {Number}
	 */
    Owl.prototype.maximum = function (relative) {
        var settings = this.settings,
			maximum = this._coordinates.length,
			iterator,
			reciprocalItemsWidth,
			elementWidth;

        if (settings.loop) {
            maximum = this._clones.length / 2 + this._items.length - 1;
        } else if (settings.autoWidth || settings.merge) {
            iterator = this._items.length;
            reciprocalItemsWidth = this._items[--iterator].width();
            elementWidth = this.$element.width();
            while (iterator--) {
                reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin;
                if (reciprocalItemsWidth > elementWidth) {
                    break;
                }
            }
            maximum = iterator + 1;
        } else if (settings.center) {
            maximum = this._items.length - 1;
        } else {
            maximum = this._items.length - settings.items;
        }

        if (relative) {
            maximum -= this._clones.length / 2;
        }

        return Math.max(maximum, 0);
    };

    /**
	 * Gets the minimum position for the current item.
	 * @public
	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
	 * @returns {Number}
	 */
    Owl.prototype.minimum = function (relative) {
        return relative ? 0 : this._clones.length / 2;
    };

    /**
	 * Gets an item at the specified relative position.
	 * @public
	 * @param {Number} [position] - The relative position of the item.
	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
	 */
    Owl.prototype.items = function (position) {
        if (position === undefined) {
            return this._items.slice();
        }

        position = this.normalize(position, true);
        return this._items[position];
    };

    /**
	 * Gets an item at the specified relative position.
	 * @public
	 * @param {Number} [position] - The relative position of the item.
	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
	 */
    Owl.prototype.mergers = function (position) {
        if (position === undefined) {
            return this._mergers.slice();
        }

        position = this.normalize(position, true);
        return this._mergers[position];
    };

    /**
	 * Gets the absolute positions of clones for an item.
	 * @public
	 * @param {Number} [position] - The relative position of the item.
	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
	 */
    Owl.prototype.clones = function (position) {
        var odd = this._clones.length / 2,
			even = odd + this._items.length,
			map = function (index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };

        if (position === undefined) {
            return $.map(this._clones, function (v, i) { return map(i) });
        }

        return $.map(this._clones, function (v, i) { return v === position ? map(i) : null });
    };

    /**
	 * Sets the current animation speed.
	 * @public
	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
	 * @returns {Number} - The current animation speed in milliseconds.
	 */
    Owl.prototype.speed = function (speed) {
        if (speed !== undefined) {
            this._speed = speed;
        }

        return this._speed;
    };

    /**
	 * Gets the coordinate of an item.
	 * @todo The name of this method is missleanding.
	 * @public
	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
	 */
    Owl.prototype.coordinates = function (position) {
        var multiplier = 1,
			newPosition = position - 1,
			coordinate;

        if (position === undefined) {
            return $.map(this._coordinates, $.proxy(function (coordinate, index) {
                return this.coordinates(index);
            }, this));
        }

        if (this.settings.center) {
            if (this.settings.rtl) {
                multiplier = -1;
                newPosition = position + 1;
            }

            coordinate = this._coordinates[position];
            coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier;
        } else {
            coordinate = this._coordinates[newPosition] || 0;
        }

        coordinate = Math.ceil(coordinate);

        return coordinate;
    };

    /**
	 * Calculates the speed for a translation.
	 * @protected
	 * @param {Number} from - The absolute position of the start item.
	 * @param {Number} to - The absolute position of the target item.
	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
	 * @returns {Number} - The time in milliseconds for the translation.
	 */
    Owl.prototype.duration = function (from, to, factor) {
        if (factor === 0) {
            return 0;
        }

        return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
    };

    /**
	 * Slides to the specified item.
	 * @public
	 * @param {Number} position - The position of the item.
	 * @param {Number} [speed] - The time in milliseconds for the transition.
	 */
    Owl.prototype.to = function (position, speed) {
        var current = this.current(),
			revert = null,
			distance = position - this.relative(current),
			direction = (distance > 0) - (distance < 0),
			items = this._items.length,
			minimum = this.minimum(),
			maximum = this.maximum();

        if (this.settings.loop) {
            if (!this.settings.rewind && Math.abs(distance) > items / 2) {
                distance += direction * -1 * items;
            }

            position = current + distance;
            revert = ((position - minimum) % items + items) % items + minimum;

            if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
                current = revert - distance;
                position = revert;
                this.reset(current);
            }
        } else if (this.settings.rewind) {
            maximum += 1;
            position = (position % maximum + maximum) % maximum;
        } else {
            position = Math.max(minimum, Math.min(maximum, position));
        }

        this.speed(this.duration(current, position, speed));
        this.current(position);

        if (this.$element.is(':visible')) {
            this.update();
        }
    };

    /**
	 * Slides to the next item.
	 * @public
	 * @param {Number} [speed] - The time in milliseconds for the transition.
	 */
    Owl.prototype.next = function (speed) {
        speed = speed || false;
        this.to(this.relative(this.current()) + 1, speed);
    };

    /**
	 * Slides to the previous item.
	 * @public
	 * @param {Number} [speed] - The time in milliseconds for the transition.
	 */
    Owl.prototype.prev = function (speed) {
        speed = speed || false;
        this.to(this.relative(this.current()) - 1, speed);
    };

    /**
	 * Handles the end of an animation.
	 * @protected
	 * @param {Event} event - The event arguments.
	 */
    Owl.prototype.onTransitionEnd = function (event) {

        // if css2 animation then event object is undefined
        if (event !== undefined) {
            event.stopPropagation();

            // Catch only owl-stage transitionEnd event
            if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
                return false;
            }
        }

        this.leave('animating');
        this.trigger('translated');
    };

    /**
	 * Gets viewport width.
	 * @protected
	 * @return {Number} - The width in pixel.
	 */
    Owl.prototype.viewport = function () {
        var width;
        if (this.options.responsiveBaseElement !== window) {
            width = $(this.options.responsiveBaseElement).width();
        } else if (window.innerWidth) {
            width = window.innerWidth;
        } else if (document.documentElement && document.documentElement.clientWidth) {
            width = document.documentElement.clientWidth;
        } else {
            throw 'Can not detect viewport width.';
        }
        return width;
    };

    /**
	 * Replaces the current content.
	 * @public
	 * @param {HTMLElement|jQuery|String} content - The new content.
	 */
    Owl.prototype.replace = function (content) {
        this.$stage.empty();
        this._items = [];

        if (content) {
            content = (content instanceof jQuery) ? content : $(content);
        }

        if (this.settings.nestedItemSelector) {
            content = content.find('.' + this.settings.nestedItemSelector);
        }

        content.filter(function () {
            return this.nodeType === 1;
        }).each($.proxy(function (index, item) {
            item = this.prepare(item);
            this.$stage.append(item);
            this._items.push(item);
            this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
        }, this));

        this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);

        this.invalidate('items');
    };

    /**
	 * Adds an item.
	 * @todo Use `item` instead of `content` for the event arguments.
	 * @public
	 * @param {HTMLElement|jQuery|String} content - The item content to add.
	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
	 */
    Owl.prototype.add = function (content, position) {
        var current = this.relative(this._current);

        position = position === undefined ? this._items.length : this.normalize(position, true);
        content = content instanceof jQuery ? content : $(content);

        this.trigger('add', { content: content, position: position });

        content = this.prepare(content);

        if (this._items.length === 0 || position === this._items.length) {
            this._items.length === 0 && this.$stage.append(content);
            this._items.length !== 0 && this._items[position - 1].after(content);
            this._items.push(content);
            this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
        } else {
            this._items[position].before(content);
            this._items.splice(position, 0, content);
            this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
        }

        this._items[current] && this.reset(this._items[current].index());

        this.invalidate('items');

        this.trigger('added', { content: content, position: position });
    };

    /**
	 * Removes an item by its position.
	 * @todo Use `item` instead of `content` for the event arguments.
	 * @public
	 * @param {Number} position - The relative position of the item to remove.
	 */
    Owl.prototype.remove = function (position) {
        position = this.normalize(position, true);

        if (position === undefined) {
            return;
        }

        this.trigger('remove', { content: this._items[position], position: position });

        this._items[position].remove();
        this._items.splice(position, 1);
        this._mergers.splice(position, 1);

        this.invalidate('items');

        this.trigger('removed', { content: null, position: position });
    };

    /**
	 * Preloads images with auto width.
	 * @todo Replace by a more generic approach
	 * @protected
	 */
    Owl.prototype.preloadAutoWidthImages = function (images) {
        images.each($.proxy(function (i, element) {
            this.enter('pre-loading');
            element = $(element);
            $(new Image()).one('load', $.proxy(function (e) {
                element.attr('src', e.target.src);
                element.css('opacity', 1);
                this.leave('pre-loading');
                !this.is('pre-loading') && !this.is('initializing') && this.refresh();
            }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
        }, this));
    };

    /**
	 * Destroys the carousel.
	 * @public
	 */
    Owl.prototype.destroy = function () {

        this.$element.off('.owl.core');
        this.$stage.off('.owl.core');
        $(document).off('.owl.core');

        if (this.settings.responsive !== false) {
            window.clearTimeout(this.resizeTimer);
            this.off(window, 'resize', this._handlers.onThrottledResize);
        }

        for (var i in this._plugins) {
            this._plugins[i].destroy();
        }

        this.$stage.children('.cloned').remove();

        this.$stage.unwrap();
        this.$stage.children().contents().unwrap();
        this.$stage.children().unwrap();

        this.$element
			.removeClass(this.options.refreshClass)
			.removeClass(this.options.loadingClass)
			.removeClass(this.options.loadedClass)
			.removeClass(this.options.rtlClass)
			.removeClass(this.options.dragClass)
			.removeClass(this.options.grabClass)
			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
			.removeData('owl.carousel');
    };

    /**
	 * Operators to calculate right-to-left and left-to-right.
	 * @protected
	 * @param {Number} [a] - The left side operand.
	 * @param {String} [o] - The operator.
	 * @param {Number} [b] - The right side operand.
	 */
    Owl.prototype.op = function (a, o, b) {
        var rtl = this.settings.rtl;
        switch (o) {
            case '<':
                return rtl ? a > b : a < b;
            case '>':
                return rtl ? a < b : a > b;
            case '>=':
                return rtl ? a <= b : a >= b;
            case '<=':
                return rtl ? a >= b : a <= b;
            default:
                break;
        }
    };

    /**
	 * Attaches to an internal event.
	 * @protected
	 * @param {HTMLElement} element - The event source.
	 * @param {String} event - The event name.
	 * @param {Function} listener - The event handler to attach.
	 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
	 */
    Owl.prototype.on = function (element, event, listener, capture) {
        if (element.addEventListener) {
            element.addEventListener(event, listener, capture);
        } else if (element.attachEvent) {
            element.attachEvent('on' + event, listener);
        }
    };

    /**
	 * Detaches from an internal event.
	 * @protected
	 * @param {HTMLElement} element - The event source.
	 * @param {String} event - The event name.
	 * @param {Function} listener - The attached event handler to detach.
	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
	 */
    Owl.prototype.off = function (element, event, listener, capture) {
        if (element.removeEventListener) {
            element.removeEventListener(event, listener, capture);
        } else if (element.detachEvent) {
            element.detachEvent('on' + event, listener);
        }
    };

    /**
	 * Triggers a public event.
	 * @todo Remove `status`, `relatedTarget` should be used instead.
	 * @protected
	 * @param {String} name - The event name.
	 * @param {*} [data=null] - The event data.
	 * @param {String} [namespace=carousel] - The event namespace.
	 * @param {String} [state] - The state which is associated with the event.
	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
	 * @returns {Event} - The event arguments.
	 */
    Owl.prototype.trigger = function (name, data, namespace, state, enter) {
        var status = {
            item: { count: this._items.length, index: this.current() }
        }, handler = $.camelCase(
			$.grep(['on', name, namespace], function (v) { return v })
				.join('-').toLowerCase()
		), event = $.Event(
			[name, 'owl', namespace || 'carousel'].join('.').toLowerCase(),
			$.extend({ relatedTarget: this }, status, data)
		);

        if (!this._supress[name]) {
            $.each(this._plugins, function (name, plugin) {
                if (plugin.onTrigger) {
                    plugin.onTrigger(event);
                }
            });

            this.register({ type: Owl.Type.Event, name: name });
            this.$element.trigger(event);

            if (this.settings && typeof this.settings[handler] === 'function') {
                this.settings[handler].call(this, event);
            }
        }

        return event;
    };

    /**
	 * Enters a state.
	 * @param name - The state name.
	 */
    Owl.prototype.enter = function (name) {
        $.each([name].concat(this._states.tags[name] || []), $.proxy(function (i, name) {
            if (this._states.current[name] === undefined) {
                this._states.current[name] = 0;
            }

            this._states.current[name]++;
        }, this));
    };

    /**
	 * Leaves a state.
	 * @param name - The state name.
	 */
    Owl.prototype.leave = function (name) {
        $.each([name].concat(this._states.tags[name] || []), $.proxy(function (i, name) {
            this._states.current[name]--;
        }, this));
    };

    /**
	 * Registers an event or state.
	 * @public
	 * @param {Object} object - The event or state to register.
	 */
    Owl.prototype.register = function (object) {
        if (object.type === Owl.Type.Event) {
            if (!$.event.special[object.name]) {
                $.event.special[object.name] = {};
            }

            if (!$.event.special[object.name].owl) {
                var _default = $.event.special[object.name]._default;
                $.event.special[object.name]._default = function (e) {
                    if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
                        return _default.apply(this, arguments);
                    }
                    return e.namespace && e.namespace.indexOf('owl') > -1;
                };
                $.event.special[object.name].owl = true;
            }
        } else if (object.type === Owl.Type.State) {
            if (!this._states.tags[object.name]) {
                this._states.tags[object.name] = object.tags;
            } else {
                this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
            }

            this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function (tag, i) {
                return $.inArray(tag, this._states.tags[object.name]) === i;
            }, this));
        }
    };

    /**
	 * Suppresses events.
	 * @protected
	 * @param {Array.<String>} events - The events to suppress.
	 */
    Owl.prototype.suppress = function (events) {
        $.each(events, $.proxy(function (index, event) {
            this._supress[event] = true;
        }, this));
    };

    /**
	 * Releases suppressed events.
	 * @protected
	 * @param {Array.<String>} events - The events to release.
	 */
    Owl.prototype.release = function (events) {
        $.each(events, $.proxy(function (index, event) {
            delete this._supress[event];
        }, this));
    };

    /**
	 * Gets unified pointer coordinates from event.
	 * @todo #261
	 * @protected
	 * @param {Event} - The `mousedown` or `touchstart` event.
	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
	 */
    Owl.prototype.pointer = function (event) {
        var result = { x: null, y: null };

        event = event.originalEvent || event || window.event;

        event = event.touches && event.touches.length ?
			event.touches[0] : event.changedTouches && event.changedTouches.length ?
				event.changedTouches[0] : event;

        if (event.pageX) {
            result.x = event.pageX;
            result.y = event.pageY;
        } else {
            result.x = event.clientX;
            result.y = event.clientY;
        }

        return result;
    };

    /**
	 * Determines if the input is a Number or something that can be coerced to a Number
	 * @protected
	 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested
	 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number
	 */
    Owl.prototype.isNumeric = function (number) {
        return !isNaN(parseFloat(number));
    };

    /**
	 * Gets the difference of two vectors.
	 * @todo #261
	 * @protected
	 * @param {Object} - The first vector.
	 * @param {Object} - The second vector.
	 * @returns {Object} - The difference.
	 */
    Owl.prototype.difference = function (first, second) {
        return {
            x: first.x - second.x,
            y: first.y - second.y
        };
    };

    /**
	 * The jQuery Plugin for the Owl Carousel
	 * @todo Navigation plugin `next` and `prev`
	 * @public
	 */
    $.fn.owlCarousel = function (option) {
        var args = Array.prototype.slice.call(arguments, 1);

        return this.each(function () {
            var $this = $(this),
				data = $this.data('owl.carousel');

            if (!data) {
                data = new Owl(this, typeof option == 'object' && option);
                $this.data('owl.carousel', data);

                $.each([
					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
                ], function (i, event) {
                    data.register({ type: Owl.Type.Event, name: event });
                    data.$element.on(event + '.owl.carousel.core', $.proxy(function (e) {
                        if (e.namespace && e.relatedTarget !== this) {
                            this.suppress([event]);
                            data[event].apply(this, [].slice.call(arguments, 1));
                            this.release([event]);
                        }
                    }, data));
                });
            }

            if (typeof option == 'string' && option.charAt(0) !== '_') {
                data[option].apply(data, args);
            }
        });
    };

    /**
	 * The constructor for the jQuery Plugin
	 * @public
	 */
    $.fn.owlCarousel.Constructor = Owl;

})(window.Zepto || window.jQuery, window, document);

/**
 * AutoRefresh Plugin
 * @version 2.1.0
 * @author Artus Kolanowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {

    /**
	 * Creates the auto refresh plugin.
	 * @class The Auto Refresh Plugin
	 * @param {Owl} carousel - The Owl Carousel
	 */
    var AutoRefresh = function (carousel) {
        /**
		 * Reference to the core.
		 * @protected
		 * @type {Owl}
		 */
        this._core = carousel;

        /**
		 * Refresh interval.
		 * @protected
		 * @type {number}
		 */
        this._interval = null;

        /**
		 * Whether the element is currently visible or not.
		 * @protected
		 * @type {Boolean}
		 */
        this._visible = null;

        /**
		 * All event handlers.
		 * @protected
		 * @type {Object}
		 */
        this._handlers = {
            'initialized.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.autoRefresh) {
                    this.watch();
                }
            }, this)
        };

        // set default options
        this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);

        // register event handlers
        this._core.$element.on(this._handlers);
    };

    /**
	 * Default options.
	 * @public
	 */
    AutoRefresh.Defaults = {
        autoRefresh: true,
        autoRefreshInterval: 500
    };

    /**
	 * Watches the element.
	 */
    AutoRefresh.prototype.watch = function () {
        if (this._interval) {
            return;
        }

        this._visible = this._core.$element.is(':visible');
        this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
    };

    /**
	 * Refreshes the element.
	 */
    AutoRefresh.prototype.refresh = function () {
        if (this._core.$element.is(':visible') === this._visible) {
            return;
        }

        this._visible = !this._visible;

        this._core.$element.toggleClass('owl-hidden', !this._visible);

        this._visible && (this._core.invalidate('width') && this._core.refresh());
    };

    /**
	 * Destroys the plugin.
	 */
    AutoRefresh.prototype.destroy = function () {
        var handler, property;

        window.clearInterval(this._interval);

        for (handler in this._handlers) {
            this._core.$element.off(handler, this._handlers[handler]);
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;

})(window.Zepto || window.jQuery, window, document);

/**
 * Lazy Plugin
 * @version 2.1.0
 * @author Bartosz Wojciechowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {

    /**
	 * Creates the lazy plugin.
	 * @class The Lazy Plugin
	 * @param {Owl} carousel - The Owl Carousel
	 */
    var Lazy = function (carousel) {

        /**
		 * Reference to the core.
		 * @protected
		 * @type {Owl}
		 */
        this._core = carousel;

        /**
		 * Already loaded items.
		 * @protected
		 * @type {Array.<jQuery>}
		 */
        this._loaded = [];

        /**
		 * Event handlers.
		 * @protected
		 * @type {Object}
		 */
        this._handlers = {
            'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function (e) {
                if (!e.namespace) {
                    return;
                }

                if (!this._core.settings || !this._core.settings.lazyLoad) {
                    return;
                }

                if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
                    var settings = this._core.settings,
						n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
						i = ((settings.center && n * -1) || 0),
						position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i,
						clones = this._core.clones().length,
						load = $.proxy(function (i, v) { this.load(v) }, this);

                    while (i++ < n) {
                        this.load(clones / 2 + this._core.relative(position));
                        clones && $.each(this._core.clones(this._core.relative(position)), load);
                        position++;
                    }
                }
            }, this)
        };

        // set the default options
        this._core.options = $.extend({}, Lazy.Defaults, this._core.options);

        // register event handler
        this._core.$element.on(this._handlers);
    };

    /**
	 * Default options.
	 * @public
	 */
    Lazy.Defaults = {
        lazyLoad: false
    };

    /**
	 * Loads all resources of an item at the specified position.
	 * @param {Number} position - The absolute position of the item.
	 * @protected
	 */
    Lazy.prototype.load = function (position) {
        var $item = this._core.$stage.children().eq(position),
			$elements = $item && $item.find('.owl-lazy');

        if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
            return;
        }

        $elements.each($.proxy(function (index, element) {
            var $element = $(element), image,
				url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');

            this._core.trigger('load', { element: $element, url: url }, 'lazy');

            if ($element.is('img')) {
                $element.one('load.owl.lazy', $.proxy(function () {
                    $element.css('opacity', 1);
                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
                }, this)).attr('src', url);
            } else {
                image = new Image();
                image.onload = $.proxy(function () {
                    $element.css({
                        'background-image': 'url(' + url + ')',
                        'opacity': '1'
                    });
                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
                }, this);
                image.src = url;
            }
        }, this));

        this._loaded.push($item.get(0));
    };

    /**
	 * Destroys the plugin.
	 * @public
	 */
    Lazy.prototype.destroy = function () {
        var handler, property;

        for (handler in this.handlers) {
            this._core.$element.off(handler, this.handlers[handler]);
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;

})(window.Zepto || window.jQuery, window, document);

/**
 * AutoHeight Plugin
 * @version 2.1.0
 * @author Bartosz Wojciechowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {

    /**
	 * Creates the auto height plugin.
	 * @class The Auto Height Plugin
	 * @param {Owl} carousel - The Owl Carousel
	 */
    var AutoHeight = function (carousel) {
        /**
		 * Reference to the core.
		 * @protected
		 * @type {Owl}
		 */
        this._core = carousel;

        /**
		 * All event handlers.
		 * @protected
		 * @type {Object}
		 */
        this._handlers = {
            'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.autoHeight) {
                    this.update();
                }
            }, this),
            'changed.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position') {
                    this.update();
                }
            }, this),
            'loaded.owl.lazy': $.proxy(function (e) {
                if (e.namespace && this._core.settings.autoHeight
					&& e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
                    this.update();
                }
            }, this)
        };

        // set default options
        this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);

        // register event handlers
        this._core.$element.on(this._handlers);
    };

    /**
	 * Default options.
	 * @public
	 */
    AutoHeight.Defaults = {
        autoHeight: false,
        autoHeightClass: 'owl-height'
    };

    /**
	 * Updates the view.
	 */
    AutoHeight.prototype.update = function () {
        var start = this._core._current,
			end = start + this._core.settings.items,
			visible = this._core.$stage.children().toArray().slice(start, end),
			heights = [],
			maxheight = 0;

        $.each(visible, function (index, item) {
            heights.push($(item).height());
        });

        maxheight = Math.max.apply(null, heights);

        this._core.$stage.parent()
			.height(maxheight)
			.addClass(this._core.settings.autoHeightClass);
    };

    AutoHeight.prototype.destroy = function () {
        var handler, property;

        for (handler in this._handlers) {
            this._core.$element.off(handler, this._handlers[handler]);
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;

})(window.Zepto || window.jQuery, window, document);

/**
 * Video Plugin
 * @version 2.1.0
 * @author Bartosz Wojciechowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {

    /**
	 * Creates the video plugin.
	 * @class The Video Plugin
	 * @param {Owl} carousel - The Owl Carousel
	 */
    var Video = function (carousel) {
        /**
		 * Reference to the core.
		 * @protected
		 * @type {Owl}
		 */
        this._core = carousel;

        /**
		 * Cache all video URLs.
		 * @protected
		 * @type {Object}
		 */
        this._videos = {};

        /**
		 * Current playing item.
		 * @protected
		 * @type {jQuery}
		 */
        this._playing = null;

        /**
		 * All event handlers.
		 * @todo The cloned content removale is too late
		 * @protected
		 * @type {Object}
		 */
        this._handlers = {
            'initialized.owl.carousel': $.proxy(function (e) {
                if (e.namespace) {
                    this._core.register({ type: 'state', name: 'playing', tags: ['interacting'] });
                }
            }, this),
            'resize.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
                    e.preventDefault();
                }
            }, this),
            'refreshed.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.is('resizing')) {
                    this._core.$stage.find('.cloned .owl-video-frame').remove();
                }
            }, this),
            'changed.owl.carousel': $.proxy(function (e) {
                if (e.namespace && e.property.name === 'position' && this._playing) {
                    this.stop();
                }
            }, this),
            'prepared.owl.carousel': $.proxy(function (e) {
                if (!e.namespace) {
                    return;
                }

                var $element = $(e.content).find('.owl-video');

                if ($element.length) {
                    $element.css('display', 'none');
                    this.fetch($element, $(e.content));
                }
            }, this)
        };

        // set default options
        this._core.options = $.extend({}, Video.Defaults, this._core.options);

        // register event handlers
        this._core.$element.on(this._handlers);

        this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function (e) {
            this.play(e);
        }, this));
    };

    /**
	 * Default options.
	 * @public
	 */
    Video.Defaults = {
        video: false,
        videoHeight: false,
        videoWidth: false
    };

    /**
	 * Gets the video ID and the type (YouTube/Vimeo/vzaar only).
	 * @protected
	 * @param {jQuery} target - The target containing the video data.
	 * @param {jQuery} item - The item containing the video.
	 */
    Video.prototype.fetch = function (target, item) {
        var type = (function () {
            if (target.attr('data-vimeo-id')) {
                return 'vimeo';
            } else if (target.attr('data-vzaar-id')) {
                return 'vzaar'
            } else {
                return 'youtube';
            }
        })(),
            id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'),
            width = target.attr('data-width') || this._core.settings.videoWidth,
            height = target.attr('data-height') || this._core.settings.videoHeight,
            url = target.attr('href');

        if (url) {

            /*
					Parses the id's out of the following urls (and probably more):
					https://www.youtube.com/watch?v=:id
					https://youtu.be/:id
					https://vimeo.com/:id
					https://vimeo.com/channels/:channel/:id
					https://vimeo.com/groups/:group/videos/:id
					https://app.vzaar.com/videos/:id

					Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F
			*/

            id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);

            if (id[3].indexOf('youtu') > -1) {
                type = 'youtube';
            } else if (id[3].indexOf('vimeo') > -1) {
                type = 'vimeo';
            } else if (id[3].indexOf('vzaar') > -1) {
                type = 'vzaar';
            } else {
                throw new Error('Video URL not supported.');
            }
            id = id[6];
        } else {
            throw new Error('Missing video URL.');
        }

        this._videos[url] = {
            type: type,
            id: id,
            width: width,
            height: height
        };

        item.attr('data-video', url);

        this.thumbnail(target, this._videos[url]);
    };

    /**
	 * Creates video thumbnail.
	 * @protected
	 * @param {jQuery} target - The target containing the video data.
	 * @param {Object} info - The video info object.
	 * @see `fetch`
	 */
    Video.prototype.thumbnail = function (target, video) {
        var tnLink,
			icon,
			path,
			dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
			customTn = target.find('img'),
			srcType = 'src',
			lazyClass = '',
			settings = this._core.settings,
			create = function (path) {
			    icon = '<div class="owl-video-play-icon"></div>';

			    if (settings.lazyLoad) {
			        tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';
			    } else {
			        tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';
			    }
			    target.after(tnLink);
			    target.after(icon);
			};

        // wrap video content into owl-video-wrapper div
        target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');

        if (this._core.settings.lazyLoad) {
            srcType = 'data-src';
            lazyClass = 'owl-lazy';
        }

        // custom thumbnail
        if (customTn.length) {
            create(customTn.attr(srcType));
            customTn.remove();
            return false;
        }

        if (video.type === 'youtube') {
            path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
            create(path);
        } else if (video.type === 'vimeo') {
            $.ajax({
                type: 'GET',
                url: '//vimeo.com/api/v2/video/' + video.id + '.json',
                jsonp: 'callback',
                dataType: 'jsonp',
                success: function (data) {
                    path = data[0].thumbnail_large;
                    create(path);
                }
            });
        } else if (video.type === 'vzaar') {
            $.ajax({
                type: 'GET',
                url: '//vzaar.com/api/videos/' + video.id + '.json',
                jsonp: 'callback',
                dataType: 'jsonp',
                success: function (data) {
                    path = data.framegrab_url;
                    create(path);
                }
            });
        }
    };

    /**
	 * Stops the current video.
	 * @public
	 */
    Video.prototype.stop = function () {
        this._core.trigger('stop', null, 'video');
        this._playing.find('.owl-video-frame').remove();
        this._playing.removeClass('owl-video-playing');
        this._playing = null;
        this._core.leave('playing');
        this._core.trigger('stopped', null, 'video');
    };

    /**
	 * Starts the current video.
	 * @public
	 * @param {Event} event - The event arguments.
	 */
    Video.prototype.play = function (event) {
        var target = $(event.target),
			item = target.closest('.' + this._core.settings.itemClass),
			video = this._videos[item.attr('data-video')],
			width = video.width || '100%',
			height = video.height || this._core.$stage.height(),
			html;

        if (this._playing) {
            return;
        }

        this._core.enter('playing');
        this._core.trigger('play', null, 'video');

        item = this._core.items(this._core.relative(item.index()));

        this._core.reset(item.index());

        if (video.type === 'youtube') {
            html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' +
				video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';
        } else if (video.type === 'vimeo') {
            html = '<iframe src="//player.vimeo.com/video/' + video.id +
				'?autoplay=1" width="' + width + '" height="' + height +
				'" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
        } else if (video.type === 'vzaar') {
            html = '<iframe frameborder="0"' + 'height="' + height + '"' + 'width="' + width +
				'" allowfullscreen mozallowfullscreen webkitAllowFullScreen ' +
				'src="//view.vzaar.com/' + video.id + '/player?autoplay=true"></iframe>';
        }

        $('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video'));

        this._playing = item.addClass('owl-video-playing');
    };

    /**
	 * Checks whether an video is currently in full screen mode or not.
	 * @todo Bad style because looks like a readonly method but changes members.
	 * @protected
	 * @returns {Boolean}
	 */
    Video.prototype.isInFullScreen = function () {
        var element = document.fullscreenElement || document.mozFullScreenElement ||
				document.webkitFullscreenElement;

        return element && $(element).parent().hasClass('owl-video-frame');
    };

    /**
	 * Destroys the plugin.
	 */
    Video.prototype.destroy = function () {
        var handler, property;

        this._core.$element.off('click.owl.video');

        for (handler in this._handlers) {
            this._core.$element.off(handler, this._handlers[handler]);
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.Video = Video;

})(window.Zepto || window.jQuery, window, document);

/**
 * Animate Plugin
 * @version 2.1.0
 * @author Bartosz Wojciechowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {

    /**
	 * Creates the animate plugin.
	 * @class The Navigation Plugin
	 * @param {Owl} scope - The Owl Carousel
	 */
    var Animate = function (scope) {
        this.core = scope;
        this.core.options = $.extend({}, Animate.Defaults, this.core.options);
        this.swapping = true;
        this.previous = undefined;
        this.next = undefined;

        this.handlers = {
            'change.owl.carousel': $.proxy(function (e) {
                if (e.namespace && e.property.name == 'position') {
                    this.previous = this.core.current();
                    this.next = e.property.value;
                }
            }, this),
            'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function (e) {
                if (e.namespace) {
                    this.swapping = e.type == 'translated';
                }
            }, this),
            'translate.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
                    this.swap();
                }
            }, this)
        };

        this.core.$element.on(this.handlers);
    };

    /**
	 * Default options.
	 * @public
	 */
    Animate.Defaults = {
        animateOut: false,
        animateIn: false
    };

    /**
	 * Toggles the animation classes whenever an translations starts.
	 * @protected
	 * @returns {Boolean|undefined}
	 */
    Animate.prototype.swap = function () {

        if (this.core.settings.items !== 1) {
            return;
        }

        if (!$.support.animation || !$.support.transition) {
            return;
        }

        this.core.speed(0);

        var left,
			clear = $.proxy(this.clear, this),
			previous = this.core.$stage.children().eq(this.previous),
			next = this.core.$stage.children().eq(this.next),
			incoming = this.core.settings.animateIn,
			outgoing = this.core.settings.animateOut;

        if (this.core.current() === this.previous) {
            return;
        }

        if (outgoing) {
            left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
            previous.one($.support.animation.end, clear)
				.css({ 'left': left + 'px' })
				.addClass('animated owl-animated-out')
				.addClass(outgoing);
        }

        if (incoming) {
            next.one($.support.animation.end, clear)
				.addClass('animated owl-animated-in')
				.addClass(incoming);
        }
    };

    Animate.prototype.clear = function (e) {
        $(e.target).css({ 'left': '' })
			.removeClass('animated owl-animated-out owl-animated-in')
			.removeClass(this.core.settings.animateIn)
			.removeClass(this.core.settings.animateOut);
        this.core.onTransitionEnd();
    };

    /**
	 * Destroys the plugin.
	 * @public
	 */
    Animate.prototype.destroy = function () {
        var handler, property;

        for (handler in this.handlers) {
            this.core.$element.off(handler, this.handlers[handler]);
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.Animate = Animate;

})(window.Zepto || window.jQuery, window, document);

/**
 * Autoplay Plugin
 * @version 2.1.0
 * @author Bartosz Wojciechowski
 * @author Artus Kolanowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {

    /**
	 * Creates the autoplay plugin.
	 * @class The Autoplay Plugin
	 * @param {Owl} scope - The Owl Carousel
	 */
    var Autoplay = function (carousel) {
        /**
		 * Reference to the core.
		 * @protected
		 * @type {Owl}
		 */
        this._core = carousel;

        /**
		 * The autoplay timeout.
		 * @type {Timeout}
		 */
        this._timeout = null;

        /**
		 * Indicates whenever the autoplay is paused.
		 * @type {Boolean}
		 */
        this._paused = false;

        /**
		 * All event handlers.
		 * @protected
		 * @type {Object}
		 */
        this._handlers = {
            'changed.owl.carousel': $.proxy(function (e) {
                if (e.namespace && e.property.name === 'settings') {
                    if (this._core.settings.autoplay) {
                        this.play();
                    } else {
                        this.stop();
                    }
                } else if (e.namespace && e.property.name === 'position') {
                    //console.log('play?', e);
                    if (this._core.settings.autoplay) {
                        this._setAutoPlayInterval();
                    }
                }
            }, this),
            'initialized.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.autoplay) {
                    this.play();
                }
            }, this),
            'play.owl.autoplay': $.proxy(function (e, t, s) {
                if (e.namespace) {
                    this.play(t, s);
                }
            }, this),
            'stop.owl.autoplay': $.proxy(function (e) {
               
                if (e.namespace) {
                    this.stop();
                }
            }, this),
            'mouseover.owl.autoplay': $.proxy(function () {
                if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
                    this.pause();
                }
            }, this),
            'mouseleave.owl.autoplay': $.proxy(function () {
                if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
                    this.play();
                }
            }, this),
            'touchstart.owl.core': $.proxy(function () {
                if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
                    this.pause();
                }
            }, this),
            'touchend.owl.core': $.proxy(function () {
                if (this._core.settings.autoplayHoverPause) {
                    this.play();
                }
            }, this)
        };

        // register event handlers
        this._core.$element.on(this._handlers);

        // set default options
        this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
    };

    /**
	 * Default options.
	 * @public
	 */
    Autoplay.Defaults = {
        autoplay: false,
        autoplayTimeout: 5000,
        autoplayHoverPause: false,
        autoplaySpeed: false
    };

    /**
	 * Starts the autoplay.
	 * @public
	 * @param {Number} [timeout] - The interval before the next animation starts.
	 * @param {Number} [speed] - The animation speed for the animations.
	 */
    Autoplay.prototype.play = function (timeout, speed) {
        this._paused = false;

        if (this._core.is('rotating')) {
            return;
        }

        this._core.enter('rotating');

        this._setAutoPlayInterval();
    };

    /**
	 * Gets a new timeout
	 * @private
	 * @param {Number} [timeout] - The interval before the next animation starts.
	 * @param {Number} [speed] - The animation speed for the animations.
	 * @return {Timeout}
	 */
    Autoplay.prototype._getNextTimeout = function (timeout, speed) {
        if (this._timeout) {
            window.clearTimeout(this._timeout);
        }
        return window.setTimeout($.proxy(function () {
            if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) {
                return;
            }
            this._core.next(speed || this._core.settings.autoplaySpeed);
        }, this), timeout || this._core.settings.autoplayTimeout);
    };

    /**
	 * Sets autoplay in motion.
	 * @private
	 */
    Autoplay.prototype._setAutoPlayInterval = function () {
        this._timeout = this._getNextTimeout();
    };

    /**
	 * Stops the autoplay.
	 * @public
	 */
    Autoplay.prototype.stop = function () {
        if (!this._core.is('rotating')) {
            return;
        }

        window.clearTimeout(this._timeout);
        this._core.settings.autoplay = false; //Add this line.	
        this._core.leave('rotating');
    };

    /**
	 * Stops the autoplay.
	 * @public
	 */
    Autoplay.prototype.pause = function () {
        if (!this._core.is('rotating')) {
            return;
        }

        this._paused = true;
    };

    /**
	 * Destroys the plugin.
	 */
    Autoplay.prototype.destroy = function () {
        var handler, property;

        this.stop();

        for (handler in this._handlers) {
            this._core.$element.off(handler, this._handlers[handler]);
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;

})(window.Zepto || window.jQuery, window, document);

/**
 * Navigation Plugin
 * @version 2.1.0
 * @author Artus Kolanowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {
    'use strict';

    /**
	 * Creates the navigation plugin.
	 * @class The Navigation Plugin
	 * @param {Owl} carousel - The Owl Carousel.
	 */
    var Navigation = function (carousel) {
        /**
		 * Reference to the core.
		 * @protected
		 * @type {Owl}
		 */
        this._core = carousel;

        /**
		 * Indicates whether the plugin is initialized or not.
		 * @protected
		 * @type {Boolean}
		 */
        this._initialized = false;

        /**
		 * The current paging indexes.
		 * @protected
		 * @type {Array}
		 */
        this._pages = [];

        /**
		 * All DOM elements of the user interface.
		 * @protected
		 * @type {Object}
		 */
        this._controls = {};

        /**
		 * Markup for an indicator.
		 * @protected
		 * @type {Array.<String>}
		 */
        this._templates = [];

        /**
		 * The carousel element.
		 * @type {jQuery}
		 */
        this.$element = this._core.$element;

        /**
		 * Overridden methods of the carousel.
		 * @protected
		 * @type {Object}
		 */
        this._overrides = {
            next: this._core.next,
            prev: this._core.prev,
            to: this._core.to
        };

        /**
		 * All event handlers.
		 * @protected
		 * @type {Object}
		 */
        this._handlers = {
            'prepared.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.dotsData) {
                    this._templates.push('<div class="' + this._core.settings.dotClass + '">' +
						$(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '</div>');
                }
            }, this),
            'added.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.dotsData) {
                    this._templates.splice(e.position, 0, this._templates.pop());
                }
            }, this),
            'remove.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.dotsData) {
                    this._templates.splice(e.position, 1);
                }
            }, this),
            'changed.owl.carousel': $.proxy(function (e) {
                if (e.namespace && e.property.name == 'position') {
                    this.draw();
                }
            }, this),
            'initialized.owl.carousel': $.proxy(function (e) {
                if (e.namespace && !this._initialized) {
                    this._core.trigger('initialize', null, 'navigation');
                    this.initialize();
                    this.update();
                    this.draw();
                    this._initialized = true;
                    this._core.trigger('initialized', null, 'navigation');
                }
            }, this),
            'refreshed.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._initialized) {
                    this._core.trigger('refresh', null, 'navigation');
                    this.update();
                    this.draw();
                    this._core.trigger('refreshed', null, 'navigation');
                }
            }, this)
        };

        // set default options
        this._core.options = $.extend({}, Navigation.Defaults, this._core.options);

        // register event handlers
        this.$element.on(this._handlers);
    };

    /**
	 * Default options.
	 * @public
	 * @todo Rename `slideBy` to `navBy`
	 */
    Navigation.Defaults = {
        nav: false,
        navText: ['prev', 'next'],
        navSpeed: false,
        navElement: 'div',
        navContainer: false,
        navContainerClass: 'owl-nav',
        navClass: ['owl-prev', 'owl-next'],
        slideBy: 1,
        dotClass: 'owl-dot',
        dotsClass: 'owl-dots',
        dots: true,
        dotsEach: false,
        dotsData: false,
        dotsSpeed: false,
        dotsContainer: false
    };

    /**
	 * Initializes the layout of the plugin and extends the carousel.
	 * @protected
	 */
    Navigation.prototype.initialize = function () {
        var override,
			settings = this._core.settings;

        // create DOM structure for relative navigation
        this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
			: $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');

        this._controls.$previous = $('<' + settings.navElement + '>')
			.addClass(settings.navClass[0])
			.html(settings.navText[0])
			.prependTo(this._controls.$relative)
			.on('click', $.proxy(function (e) {
			    this.prev(settings.navSpeed);
			}, this));
        this._controls.$next = $('<' + settings.navElement + '>')
			.addClass(settings.navClass[1])
			.html(settings.navText[1])
			.appendTo(this._controls.$relative)
			.on('click', $.proxy(function (e) {
			    this.next(settings.navSpeed);
			}, this));

        // create DOM structure for absolute navigation
        if (!settings.dotsData) {
            this._templates = [$('<div>')
				.addClass(settings.dotClass)
				.append($('<span>'))
				.prop('outerHTML')];
        }

        this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
			: $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');

        this._controls.$absolute.on('click', 'div', $.proxy(function (e) {
            var index = $(e.target).parent().is(this._controls.$absolute)
				? $(e.target).index() : $(e.target).parent().index();

            e.preventDefault();

            this.to(index, settings.dotsSpeed);
        }, this));

        // override public methods of the carousel
        for (override in this._overrides) {
            this._core[override] = $.proxy(this[override], this);
        }
    };

    /**
	 * Destroys the plugin.
	 * @protected
	 */
    Navigation.prototype.destroy = function () {
        var handler, control, property, override;

        for (handler in this._handlers) {
            this.$element.off(handler, this._handlers[handler]);
        }
        for (control in this._controls) {
            this._controls[control].remove();
        }
        for (override in this.overides) {
            this._core[override] = this._overrides[override];
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    /**
	 * Updates the internal state.
	 * @protected
	 */
    Navigation.prototype.update = function () {
        var i, j, k,
			lower = this._core.clones().length / 2,
			upper = lower + this._core.items().length,
			maximum = this._core.maximum(true),
			settings = this._core.settings,
			size = settings.center || settings.autoWidth || settings.dotsData
				? 1 : settings.dotsEach || settings.items;

        if (settings.slideBy !== 'page') {
            settings.slideBy = Math.min(settings.slideBy, settings.items);
        }

        if (settings.dots || settings.slideBy == 'page') {
            this._pages = [];

            for (i = lower, j = 0, k = 0; i < upper; i++) {
                if (j >= size || j === 0) {
                    this._pages.push({
                        start: Math.min(maximum, i - lower),
                        end: i - lower + size - 1
                    });
                    if (Math.min(maximum, i - lower) === maximum) {
                        break;
                    }
                    j = 0, ++k;
                }
                j += this._core.mergers(this._core.relative(i));
            }
        }
    };

    /**
	 * Draws the user interface.
	 * @todo The option `dotsData` wont work.
	 * @protected
	 */
    Navigation.prototype.draw = function () {
        var difference,
			settings = this._core.settings,
			disabled = this._core.items().length <= settings.items,
			index = this._core.relative(this._core.current()),
			loop = settings.loop || settings.rewind;

        this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);

        if (settings.nav) {
            this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
            this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
        }

        this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);

        if (settings.dots) {
            difference = this._pages.length - this._controls.$absolute.children().length;

            if (settings.dotsData && difference !== 0) {
                this._controls.$absolute.html(this._templates.join(''));
            } else if (difference > 0) {
                this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
            } else if (difference < 0) {
                this._controls.$absolute.children().slice(difference).remove();
            }

            this._controls.$absolute.find('.active').removeClass('active');
            this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
        }
    };

    /**
	 * Extends event data.
	 * @protected
	 * @param {Event} event - The event object which gets thrown.
	 */
    Navigation.prototype.onTrigger = function (event) {
        var settings = this._core.settings;

        event.page = {
            index: $.inArray(this.current(), this._pages),
            count: this._pages.length,
            size: settings && (settings.center || settings.autoWidth || settings.dotsData
				? 1 : settings.dotsEach || settings.items)
        };
    };

    /**
	 * Gets the current page position of the carousel.
	 * @protected
	 * @returns {Number}
	 */
    Navigation.prototype.current = function () {
        var current = this._core.relative(this._core.current());
        return $.grep(this._pages, $.proxy(function (page, index) {
            return page.start <= current && page.end >= current;
        }, this)).pop();
    };

    /**
	 * Gets the current succesor/predecessor position.
	 * @protected
	 * @returns {Number}
	 */
    Navigation.prototype.getPosition = function (successor) {
        var position, length,
			settings = this._core.settings;

        if (settings.slideBy == 'page') {
            position = $.inArray(this.current(), this._pages);
            length = this._pages.length;
            successor ? ++position : --position;
            position = this._pages[((position % length) + length) % length].start;
        } else {
            position = this._core.relative(this._core.current());
            length = this._core.items().length;
            successor ? position += settings.slideBy : position -= settings.slideBy;
        }

        return position;
    };

    /**
	 * Slides to the next item or page.
	 * @public
	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
	 */
    Navigation.prototype.next = function (speed) {
        $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
    };

    /**
	 * Slides to the previous item or page.
	 * @public
	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
	 */
    Navigation.prototype.prev = function (speed) {
        $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
    };

    /**
	 * Slides to the specified item or page.
	 * @public
	 * @param {Number} position - The position of the item or page.
	 * @param {Number} [speed] - The time in milliseconds for the transition.
	 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
	 */
    Navigation.prototype.to = function (position, speed, standard) {
        var length;

        if (!standard && this._pages.length) {
            length = this._pages.length;
            $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
        } else {
            $.proxy(this._overrides.to, this._core)(position, speed);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;

})(window.Zepto || window.jQuery, window, document);

/**
 * Hash Plugin
 * @version 2.1.0
 * @author Artus Kolanowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {
    'use strict';

    /**
	 * Creates the hash plugin.
	 * @class The Hash Plugin
	 * @param {Owl} carousel - The Owl Carousel
	 */
    var Hash = function (carousel) {
        /**
		 * Reference to the core.
		 * @protected
		 * @type {Owl}
		 */
        this._core = carousel;

        /**
		 * Hash index for the items.
		 * @protected
		 * @type {Object}
		 */
        this._hashes = {};

        /**
		 * The carousel element.
		 * @type {jQuery}
		 */
        this.$element = this._core.$element;

        /**
		 * All event handlers.
		 * @protected
		 * @type {Object}
		 */
        this._handlers = {
            'initialized.owl.carousel': $.proxy(function (e) {
                if (e.namespace && this._core.settings.startPosition === 'URLHash') {
                    $(window).trigger('hashchange.owl.navigation');
                }
            }, this),
            'prepared.owl.carousel': $.proxy(function (e) {
                if (e.namespace) {
                    var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');

                    if (!hash) {
                        return;
                    }

                    this._hashes[hash] = e.content;
                }
            }, this),
            'changed.owl.carousel': $.proxy(function (e) {
                if (e.namespace && e.property.name === 'position') {
                    var current = this._core.items(this._core.relative(this._core.current())),
						hash = $.map(this._hashes, function (item, hash) {
						    return item === current ? hash : null;
						}).join();

                    if (!hash || window.location.hash.slice(1) === hash) {
                        return;
                    }

                    window.location.hash = hash;
                }
            }, this)
        };

        // set default options
        this._core.options = $.extend({}, Hash.Defaults, this._core.options);

        // register the event handlers
        this.$element.on(this._handlers);

        // register event listener for hash navigation
        $(window).on('hashchange.owl.navigation', $.proxy(function (e) {
            var hash = window.location.hash.substring(1),
				items = this._core.$stage.children(),
				position = this._hashes[hash] && items.index(this._hashes[hash]);

            if (position === undefined || position === this._core.current()) {
                return;
            }

            this._core.to(this._core.relative(position), false, true);
        }, this));
    };

    /**
	 * Default options.
	 * @public
	 */
    Hash.Defaults = {
        URLhashListener: false
    };

    /**
	 * Destroys the plugin.
	 * @public
	 */
    Hash.prototype.destroy = function () {
        var handler, property;

        $(window).off('hashchange.owl.navigation');

        for (handler in this._handlers) {
            this._core.$element.off(handler, this._handlers[handler]);
        }
        for (property in Object.getOwnPropertyNames(this)) {
            typeof this[property] != 'function' && (this[property] = null);
        }
    };

    $.fn.owlCarousel.Constructor.Plugins.Hash = Hash;

})(window.Zepto || window.jQuery, window, document);

/**
 * Support Plugin
 *
 * @version 2.1.0
 * @author Vivid Planet Software GmbH
 * @author Artus Kolanowski
 * @author David Deutsch
 * @license The MIT License (MIT)
 */
; (function ($, window, document, undefined) {

    var style = $('<support>').get(0).style,
		prefixes = 'Webkit Moz O ms'.split(' '),
		events = {
		    transition: {
		        end: {
		            WebkitTransition: 'webkitTransitionEnd',
		            MozTransition: 'transitionend',
		            OTransition: 'oTransitionEnd',
		            transition: 'transitionend'
		        }
		    },
		    animation: {
		        end: {
		            WebkitAnimation: 'webkitAnimationEnd',
		            MozAnimation: 'animationend',
		            OAnimation: 'oAnimationEnd',
		            animation: 'animationend'
		        }
		    }
		},
		tests = {
		    csstransforms: function () {
		        return !!test('transform');
		    },
		    csstransforms3d: function () {
		        return !!test('perspective');
		    },
		    csstransitions: function () {
		        return !!test('transition');
		    },
		    cssanimations: function () {
		        return !!test('animation');
		    }
		};

    function test(property, prefixed) {
        var result = false,
			upper = property.charAt(0).toUpperCase() + property.slice(1);

        $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function (i, property) {
            if (style[property] !== undefined) {
                result = prefixed ? property : true;
                return false;
            }
        });

        return result;
    }

    function prefixed(property) {
        return test(property, true);
    }

    if (tests.csstransitions()) {
        /* jshint -W053 */
        $.support.transition = new String(prefixed('transition'))
        $.support.transition.end = events.transition.end[$.support.transition];
    }

    if (tests.cssanimations()) {
        /* jshint -W053 */
        $.support.animation = new String(prefixed('animation'))
        $.support.animation.end = events.animation.end[$.support.animation];
    }

    if (tests.csstransforms()) {
        /* jshint -W053 */
        $.support.transform = new String(prefixed('transform'));
        $.support.transform3d = tests.csstransforms3d();
    }

})(window.Zepto || window.jQuery, window, document);;
/*
 * ----------------------------- JSTORAGE -------------------------------------
 * Simple local storage wrapper to save data on the browser side, supporting
 * all major browsers - IE6+, Firefox2+, Safari4+, Chrome4+ and Opera 10.5+
 *
 * Author: Andris Reinman, andris.reinman@gmail.com
 * Project homepage: www.jstorage.info
 *
 * Licensed under Unlicense:
 *
 * This is free and unencumbered software released into the public domain.
 *
 * Anyone is free to copy, modify, publish, use, compile, sell, or
 * distribute this software, either in source code form or as a compiled
 * binary, for any purpose, commercial or non-commercial, and by any
 * means.
 *
 * In jurisdictions that recognize copyright laws, the author or authors
 * of this software dedicate any and all copyright interest in the
 * software to the public domain. We make this dedication for the benefit
 * of the public at large and to the detriment of our heirs and
 * successors. We intend this dedication to be an overt act of
 * relinquishment in perpetuity of all present and future rights to this
 * software under copyright law.
 *
 * 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 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.
 *
 * For more information, please refer to <http://unlicense.org/>
 */

/* global ActiveXObject: false */
/* jshint browser: true */

(function() {
    'use strict';

    var
    /* jStorage version */
        JSTORAGE_VERSION = '0.4.12',

        /* detect a dollar object or create one if not found */
        $ = window.jQuery || window.$ || (window.$ = {}),

        /* check for a JSON handling support */
        JSON = {
            parse: window.JSON && (window.JSON.parse || window.JSON.decode) ||
                String.prototype.evalJSON && function(str) {
                    return String(str).evalJSON();
            } ||
                $.parseJSON ||
                $.evalJSON,
            stringify: Object.toJSON ||
                window.JSON && (window.JSON.stringify || window.JSON.encode) ||
                $.toJSON
        };

    // Break if no JSON support was found
    if (typeof JSON.parse !== 'function' || typeof JSON.stringify !== 'function') {
        throw new Error('No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page');
    }

    var
    /* This is the object, that holds the cached values */
        _storage = {
            __jstorage_meta: {
                CRC32: {}
            }
        },

        /* Actual browser storage (localStorage or globalStorage['domain']) */
        _storage_service = {
            jStorage: '{}'
        },

        /* DOM element for older IE versions, holds userData behavior */
        _storage_elm = null,

        /* How much space does the storage take */
        _storage_size = 0,

        /* which backend is currently used */
        _backend = false,

        /* onchange observers */
        _observers = {},

        /* timeout to wait after onchange event */
        _observer_timeout = false,

        /* last update time */
        _observer_update = 0,

        /* pubsub observers */
        _pubsub_observers = {},

        /* skip published items older than current timestamp */
        _pubsub_last = +new Date(),

        /* Next check for TTL */
        _ttl_timeout,

        /**
         * XML encoding and decoding as XML nodes can't be JSON'ized
         * XML nodes are encoded and decoded if the node is the value to be saved
         * but not if it's as a property of another object
         * Eg. -
         *   $.jStorage.set('key', xmlNode);        // IS OK
         *   $.jStorage.set('key', {xml: xmlNode}); // NOT OK
         */
        _XMLService = {

            /**
             * Validates a XML node to be XML
             * based on jQuery.isXML function
             */
            isXML: function(elm) {
                var documentElement = (elm ? elm.ownerDocument || elm : 0).documentElement;
                return documentElement ? documentElement.nodeName !== 'HTML' : false;
            },

            /**
             * Encodes a XML node to string
             * based on http://www.mercurytide.co.uk/news/article/issues-when-working-ajax/
             */
            encode: function(xmlNode) {
                if (!this.isXML(xmlNode)) {
                    return false;
                }
                try { // Mozilla, Webkit, Opera
                    return new XMLSerializer().serializeToString(xmlNode);
                } catch (E1) {
                    try { // IE
                        return xmlNode.xml;
                    } catch (E2) {}
                }
                return false;
            },

            /**
             * Decodes a XML node from string
             * loosely based on http://outwestmedia.com/jquery-plugins/xmldom/
             */
            decode: function(xmlString) {
                var dom_parser = ('DOMParser' in window && (new DOMParser()).parseFromString) ||
                    (window.ActiveXObject && function(_xmlString) {
                        var xml_doc = new ActiveXObject('Microsoft.XMLDOM');
                        xml_doc.async = 'false';
                        xml_doc.loadXML(_xmlString);
                        return xml_doc;
                    }),
                    resultXML;
                if (!dom_parser) {
                    return false;
                }
                resultXML = dom_parser.call('DOMParser' in window && (new DOMParser()) || window, xmlString, 'text/xml');
                return this.isXML(resultXML) ? resultXML : false;
            }
        };


    ////////////////////////// PRIVATE METHODS ////////////////////////

    /**
     * Initialization function. Detects if the browser supports DOM Storage
     * or userData behavior and behaves accordingly.
     */
    function _init() {
        /* Check if browser supports localStorage */
        var localStorageReallyWorks = false;
        if ('localStorage' in window) {
            try {
                window.localStorage.setItem('_tmptest', 'tmpval');
                localStorageReallyWorks = true;
                window.localStorage.removeItem('_tmptest');
            } catch (BogusQuotaExceededErrorOnIos5) {
                // Thanks be to iOS5 Private Browsing mode which throws
                // QUOTA_EXCEEDED_ERRROR DOM Exception 22.
            }
        }

        if (localStorageReallyWorks) {
            try {
                if (window.localStorage) {
                    _storage_service = window.localStorage;
                    _backend = 'localStorage';
                    _observer_update = _storage_service.jStorage_update;
                }
            } catch (E3) { /* Firefox fails when touching localStorage and cookies are disabled */ }
        }
        /* Check if browser supports globalStorage */
        else if ('globalStorage' in window) {
            try {
                if (window.globalStorage) {
                    if (window.location.hostname == 'localhost') {
                        _storage_service = window.globalStorage['localhost.localdomain'];
                    } else {
                        _storage_service = window.globalStorage[window.location.hostname];
                    }
                    _backend = 'globalStorage';
                    _observer_update = _storage_service.jStorage_update;
                }
            } catch (E4) { /* Firefox fails when touching localStorage and cookies are disabled */ }
        }
        /* Check if browser supports userData behavior */
        else {
            _storage_elm = document.createElement('link');
            if (_storage_elm.addBehavior) {

                /* Use a DOM element to act as userData storage */
                _storage_elm.style.behavior = 'url(#default#userData)';

                /* userData element needs to be inserted into the DOM! */
                document.getElementsByTagName('head')[0].appendChild(_storage_elm);

                try {
                    _storage_elm.load('jStorage');
                } catch (E) {
                    // try to reset cache
                    _storage_elm.setAttribute('jStorage', '{}');
                    _storage_elm.save('jStorage');
                    _storage_elm.load('jStorage');
                }

                var data = '{}';
                try {
                    data = _storage_elm.getAttribute('jStorage');
                } catch (E5) {}

                try {
                    _observer_update = _storage_elm.getAttribute('jStorage_update');
                } catch (E6) {}

                _storage_service.jStorage = data;
                _backend = 'userDataBehavior';
            } else {
                _storage_elm = null;
                return;
            }
        }

        // Load data from storage
        _load_storage();

        // remove dead keys
        _handleTTL();

        // start listening for changes
        _setupObserver();

        // initialize publish-subscribe service
        _handlePubSub();

        // handle cached navigation
        if ('addEventListener' in window) {
            window.addEventListener('pageshow', function(event) {
                if (event.persisted) {
                    _storageObserver();
                }
            }, false);
        }
    }

    /**
     * Reload data from storage when needed
     */
    function _reloadData() {
        var data = '{}';

        if (_backend == 'userDataBehavior') {
            _storage_elm.load('jStorage');

            try {
                data = _storage_elm.getAttribute('jStorage');
            } catch (E5) {}

            try {
                _observer_update = _storage_elm.getAttribute('jStorage_update');
            } catch (E6) {}

            _storage_service.jStorage = data;
        }

        _load_storage();

        // remove dead keys
        _handleTTL();

        _handlePubSub();
    }

    /**
     * Sets up a storage change observer
     */
    function _setupObserver() {
        if (_backend == 'localStorage' || _backend == 'globalStorage') {
            if ('addEventListener' in window) {
                window.addEventListener('storage', _storageObserver, false);
            } else {
                document.attachEvent('onstorage', _storageObserver);
            }
        } else if (_backend == 'userDataBehavior') {
            setInterval(_storageObserver, 1000);
        }
    }

    /**
     * Fired on any kind of data change, needs to check if anything has
     * really been changed
     */
    function _storageObserver() {
        var updateTime;
        // cumulate change notifications with timeout
        clearTimeout(_observer_timeout);
        _observer_timeout = setTimeout(function() {

            if (_backend == 'localStorage' || _backend == 'globalStorage') {
                updateTime = _storage_service.jStorage_update;
            } else if (_backend == 'userDataBehavior') {
                _storage_elm.load('jStorage');
                try {
                    updateTime = _storage_elm.getAttribute('jStorage_update');
                } catch (E5) {}
            }

            if (updateTime && updateTime != _observer_update) {
                _observer_update = updateTime;
                _checkUpdatedKeys();
            }

        }, 25);
    }

    /**
     * Reloads the data and checks if any keys are changed
     */
    function _checkUpdatedKeys() {
        var oldCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32)),
            newCrc32List;

        _reloadData();
        newCrc32List = JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32));

        var key,
            updated = [],
            removed = [];

        for (key in oldCrc32List) {
            if (oldCrc32List.hasOwnProperty(key)) {
                if (!newCrc32List[key]) {
                    removed.push(key);
                    continue;
                }
                if (oldCrc32List[key] != newCrc32List[key] && String(oldCrc32List[key]).substr(0, 2) == '2.') {
                    updated.push(key);
                }
            }
        }

        for (key in newCrc32List) {
            if (newCrc32List.hasOwnProperty(key)) {
                if (!oldCrc32List[key]) {
                    updated.push(key);
                }
            }
        }

        _fireObservers(updated, 'updated');
        _fireObservers(removed, 'deleted');
    }

    /**
     * Fires observers for updated keys
     *
     * @param {Array|String} keys Array of key names or a key
     * @param {String} action What happened with the value (updated, deleted, flushed)
     */
    function _fireObservers(keys, action) {
        keys = [].concat(keys || []);

        var i, j, len, jlen;

        if (action == 'flushed') {
            keys = [];
            for (var key in _observers) {
                if (_observers.hasOwnProperty(key)) {
                    keys.push(key);
                }
            }
            action = 'deleted';
        }
        for (i = 0, len = keys.length; i < len; i++) {
            if (_observers[keys[i]]) {
                for (j = 0, jlen = _observers[keys[i]].length; j < jlen; j++) {
                    _observers[keys[i]][j](keys[i], action);
                }
            }
            if (_observers['*']) {
                for (j = 0, jlen = _observers['*'].length; j < jlen; j++) {
                    _observers['*'][j](keys[i], action);
                }
            }
        }
    }

    /**
     * Publishes key change to listeners
     */
    function _publishChange() {
        var updateTime = (+new Date()).toString();

        if (_backend == 'localStorage' || _backend == 'globalStorage') {
            try {
                _storage_service.jStorage_update = updateTime;
            } catch (E8) {
                // safari private mode has been enabled after the jStorage initialization
                _backend = false;
            }
        } else if (_backend == 'userDataBehavior') {
            _storage_elm.setAttribute('jStorage_update', updateTime);
            _storage_elm.save('jStorage');
        }

        _storageObserver();
    }

    /**
     * Loads the data from the storage based on the supported mechanism
     */
    function _load_storage() {
        /* if jStorage string is retrieved, then decode it */
        if (_storage_service.jStorage) {
            try {
                _storage = JSON.parse(String(_storage_service.jStorage));
            } catch (E6) {
                _storage_service.jStorage = '{}';
            }
        } else {
            _storage_service.jStorage = '{}';
        }
        _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;

        if (!_storage.__jstorage_meta) {
            _storage.__jstorage_meta = {};
        }
        if (!_storage.__jstorage_meta.CRC32) {
            _storage.__jstorage_meta.CRC32 = {};
        }
    }

    /**
     * This functions provides the 'save' mechanism to store the jStorage object
     */
    function _save() {
        _dropOldEvents(); // remove expired events
        try {
            _storage_service.jStorage = JSON.stringify(_storage);
            // If userData is used as the storage engine, additional
            if (_storage_elm) {
                _storage_elm.setAttribute('jStorage', _storage_service.jStorage);
                _storage_elm.save('jStorage');
            }
            _storage_size = _storage_service.jStorage ? String(_storage_service.jStorage).length : 0;
        } catch (E7) { /* probably cache is full, nothing is saved this way*/ }
    }

    /**
     * Function checks if a key is set and is string or numberic
     *
     * @param {String} key Key name
     */
    function _checkKey(key) {
        if (typeof key != 'string' && typeof key != 'number') {
            throw new TypeError('Key name must be string or numeric');
        }
        if (key == '__jstorage_meta') {
            throw new TypeError('Reserved key name');
        }
        return true;
    }

    /**
     * Removes expired keys
     */
    function _handleTTL() {
        var curtime, i, TTL, CRC32, nextExpire = Infinity,
            changed = false,
            deleted = [];

        clearTimeout(_ttl_timeout);

        if (!_storage.__jstorage_meta || typeof _storage.__jstorage_meta.TTL != 'object') {
            // nothing to do here
            return;
        }

        curtime = +new Date();
        TTL = _storage.__jstorage_meta.TTL;

        CRC32 = _storage.__jstorage_meta.CRC32;
        for (i in TTL) {
            if (TTL.hasOwnProperty(i)) {
                if (TTL[i] <= curtime) {
                    delete TTL[i];
                    delete CRC32[i];
                    delete _storage[i];
                    changed = true;
                    deleted.push(i);
                } else if (TTL[i] < nextExpire) {
                    nextExpire = TTL[i];
                }
            }
        }

        // set next check
        if (nextExpire != Infinity) {
            _ttl_timeout = setTimeout(_handleTTL, Math.min(nextExpire - curtime, 0x7FFFFFFF));
        }

        // save changes
        if (changed) {
            _save();
            _publishChange();
            _fireObservers(deleted, 'deleted');
        }
    }

    /**
     * Checks if there's any events on hold to be fired to listeners
     */
    function _handlePubSub() {
        var i, len;
        if (!_storage.__jstorage_meta.PubSub) {
            return;
        }
        var pubelm,
            _pubsubCurrent = _pubsub_last,
            needFired = [];

        for (i = len = _storage.__jstorage_meta.PubSub.length - 1; i >= 0; i--) {
            pubelm = _storage.__jstorage_meta.PubSub[i];
            if (pubelm[0] > _pubsub_last) {
                _pubsubCurrent = pubelm[0];
                needFired.unshift(pubelm);
            }
        }

        for (i = needFired.length - 1; i >= 0; i--) {
            _fireSubscribers(needFired[i][1], needFired[i][2]);
        }

        _pubsub_last = _pubsubCurrent;
    }

    /**
     * Fires all subscriber listeners for a pubsub channel
     *
     * @param {String} channel Channel name
     * @param {Mixed} payload Payload data to deliver
     */
    function _fireSubscribers(channel, payload) {
        if (_pubsub_observers[channel]) {
            for (var i = 0, len = _pubsub_observers[channel].length; i < len; i++) {
                // send immutable data that can't be modified by listeners
                try {
                    _pubsub_observers[channel][i](channel, JSON.parse(JSON.stringify(payload)));
                } catch (E) {}
            }
        }
    }

    /**
     * Remove old events from the publish stream (at least 2sec old)
     */
    function _dropOldEvents() {
        if (!_storage.__jstorage_meta.PubSub) {
            return;
        }

        var retire = +new Date() - 2000;

        for (var i = 0, len = _storage.__jstorage_meta.PubSub.length; i < len; i++) {
            if (_storage.__jstorage_meta.PubSub[i][0] <= retire) {
                // deleteCount is needed for IE6
                _storage.__jstorage_meta.PubSub.splice(i, _storage.__jstorage_meta.PubSub.length - i);
                break;
            }
        }

        if (!_storage.__jstorage_meta.PubSub.length) {
            delete _storage.__jstorage_meta.PubSub;
        }

    }

    /**
     * Publish payload to a channel
     *
     * @param {String} channel Channel name
     * @param {Mixed} payload Payload to send to the subscribers
     */
    function _publish(channel, payload) {
        if (!_storage.__jstorage_meta) {
            _storage.__jstorage_meta = {};
        }
        if (!_storage.__jstorage_meta.PubSub) {
            _storage.__jstorage_meta.PubSub = [];
        }

        _storage.__jstorage_meta.PubSub.unshift([+new Date(), channel, payload]);

        _save();
        _publishChange();
    }


    /**
     * JS Implementation of MurmurHash2
     *
     *  SOURCE: https://github.com/garycourt/murmurhash-js (MIT licensed)
     *
     * @author <a href='mailto:gary.court@gmail.com'>Gary Court</a>
     * @see http://github.com/garycourt/murmurhash-js
     * @author <a href='mailto:aappleby@gmail.com'>Austin Appleby</a>
     * @see http://sites.google.com/site/murmurhash/
     *
     * @param {string} str ASCII only
     * @param {number} seed Positive integer only
     * @return {number} 32-bit positive integer hash
     */

    function murmurhash2_32_gc(str, seed) {
        var
            l = str.length,
            h = seed ^ l,
            i = 0,
            k;

        while (l >= 4) {
            k =
                ((str.charCodeAt(i) & 0xff)) |
                ((str.charCodeAt(++i) & 0xff) << 8) |
                ((str.charCodeAt(++i) & 0xff) << 16) |
                ((str.charCodeAt(++i) & 0xff) << 24);

            k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
            k ^= k >>> 24;
            k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));

            h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;

            l -= 4;
            ++i;
        }

        switch (l) {
            case 3:
                h ^= (str.charCodeAt(i + 2) & 0xff) << 16;
                /* falls through */
            case 2:
                h ^= (str.charCodeAt(i + 1) & 0xff) << 8;
                /* falls through */
            case 1:
                h ^= (str.charCodeAt(i) & 0xff);
                h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
        }

        h ^= h >>> 13;
        h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
        h ^= h >>> 15;

        return h >>> 0;
    }

    ////////////////////////// PUBLIC INTERFACE /////////////////////////

    $.jStorage = {
        /* Version number */
        version: JSTORAGE_VERSION,

        /**
         * Sets a key's value.
         *
         * @param {String} key Key to set. If this value is not set or not
         *              a string an exception is raised.
         * @param {Mixed} value Value to set. This can be any value that is JSON
         *              compatible (Numbers, Strings, Objects etc.).
         * @param {Object} [options] - possible options to use
         * @param {Number} [options.TTL] - optional TTL value, in milliseconds
         * @return {Mixed} the used value
         */
        set: function(key, value, options) {
            _checkKey(key);

            options = options || {};

            // undefined values are deleted automatically
            if (typeof value == 'undefined') {
                this.deleteKey(key);
                return value;
            }

            if (_XMLService.isXML(value)) {
                value = {
                    _is_xml: true,
                    xml: _XMLService.encode(value)
                };
            } else if (typeof value == 'function') {
                return undefined; // functions can't be saved!
            } else if (value && typeof value == 'object') {
                // clone the object before saving to _storage tree
                value = JSON.parse(JSON.stringify(value));
            }

            _storage[key] = value;

            _storage.__jstorage_meta.CRC32[key] = '2.' + murmurhash2_32_gc(JSON.stringify(value), 0x9747b28c);

            this.setTTL(key, options.TTL || 0); // also handles saving and _publishChange

            _fireObservers(key, 'updated');
            return value;
        },

        /**
         * Looks up a key in cache
         *
         * @param {String} key - Key to look up.
         * @param {mixed} def - Default value to return, if key didn't exist.
         * @return {Mixed} the key value, default value or null
         */
        get: function(key, def) {
            _checkKey(key);
            if (key in _storage) {
                if (_storage[key] && typeof _storage[key] == 'object' && _storage[key]._is_xml) {
                    return _XMLService.decode(_storage[key].xml);
                } else {
                    return _storage[key];
                }
            }
            return typeof(def) == 'undefined' ? null : def;
        },

        /**
         * Deletes a key from cache.
         *
         * @param {String} key - Key to delete.
         * @return {Boolean} true if key existed or false if it didn't
         */
        deleteKey: function(key) {
            _checkKey(key);
            if (key in _storage) {
                delete _storage[key];
                // remove from TTL list
                if (typeof _storage.__jstorage_meta.TTL == 'object' &&
                    key in _storage.__jstorage_meta.TTL) {
                    delete _storage.__jstorage_meta.TTL[key];
                }

                delete _storage.__jstorage_meta.CRC32[key];

                _save();
                _publishChange();
                _fireObservers(key, 'deleted');
                return true;
            }
            return false;
        },

        /**
         * Sets a TTL for a key, or remove it if ttl value is 0 or below
         *
         * @param {String} key - key to set the TTL for
         * @param {Number} ttl - TTL timeout in milliseconds
         * @return {Boolean} true if key existed or false if it didn't
         */
        setTTL: function(key, ttl) {
            var curtime = +new Date();
            _checkKey(key);
            ttl = Number(ttl) || 0;
            if (key in _storage) {

                if (!_storage.__jstorage_meta.TTL) {
                    _storage.__jstorage_meta.TTL = {};
                }

                // Set TTL value for the key
                if (ttl > 0) {
                    _storage.__jstorage_meta.TTL[key] = curtime + ttl;
                } else {
                    delete _storage.__jstorage_meta.TTL[key];
                }

                _save();

                _handleTTL();

                _publishChange();
                return true;
            }
            return false;
        },

        /**
         * Gets remaining TTL (in milliseconds) for a key or 0 when no TTL has been set
         *
         * @param {String} key Key to check
         * @return {Number} Remaining TTL in milliseconds
         */
        getTTL: function(key) {
            var curtime = +new Date(),
                ttl;
            _checkKey(key);
            if (key in _storage && _storage.__jstorage_meta.TTL && _storage.__jstorage_meta.TTL[key]) {
                ttl = _storage.__jstorage_meta.TTL[key] - curtime;
                return ttl || 0;
            }
            return 0;
        },

        /**
         * Deletes everything in cache.
         *
         * @return {Boolean} Always true
         */
        flush: function() {
            _storage = {
                __jstorage_meta: {
                    CRC32: {}
                }
            };
            _save();
            _publishChange();
            _fireObservers(null, 'flushed');
            return true;
        },

        /**
         * Returns a read-only copy of _storage
         *
         * @return {Object} Read-only copy of _storage
         */
        storageObj: function() {
            function F() {}
            F.prototype = _storage;
            return new F();
        },

        /**
         * Returns an index of all used keys as an array
         * ['key1', 'key2',..'keyN']
         *
         * @return {Array} Used keys
         */
        index: function() {
            var index = [],
                i;
            for (i in _storage) {
                if (_storage.hasOwnProperty(i) && i != '__jstorage_meta') {
                    index.push(i);
                }
            }
            return index;
        },

        /**
         * How much space in bytes does the storage take?
         *
         * @return {Number} Storage size in chars (not the same as in bytes,
         *                  since some chars may take several bytes)
         */
        storageSize: function() {
            return _storage_size;
        },

        /**
         * Which backend is currently in use?
         *
         * @return {String} Backend name
         */
        currentBackend: function() {
            return _backend;
        },

        /**
         * Test if storage is available
         *
         * @return {Boolean} True if storage can be used
         */
        storageAvailable: function() {
            return !!_backend;
        },

        /**
         * Register change listeners
         *
         * @param {String} key Key name
         * @param {Function} callback Function to run when the key changes
         */
        listenKeyChange: function(key, callback) {
            _checkKey(key);
            if (!_observers[key]) {
                _observers[key] = [];
            }
            _observers[key].push(callback);
        },

        /**
         * Remove change listeners
         *
         * @param {String} key Key name to unregister listeners against
         * @param {Function} [callback] If set, unregister the callback, if not - unregister all
         */
        stopListening: function(key, callback) {
            _checkKey(key);

            if (!_observers[key]) {
                return;
            }

            if (!callback) {
                delete _observers[key];
                return;
            }

            for (var i = _observers[key].length - 1; i >= 0; i--) {
                if (_observers[key][i] == callback) {
                    _observers[key].splice(i, 1);
                }
            }
        },

        /**
         * Subscribe to a Publish/Subscribe event stream
         *
         * @param {String} channel Channel name
         * @param {Function} callback Function to run when the something is published to the channel
         */
        subscribe: function(channel, callback) {
            channel = (channel || '').toString();
            if (!channel) {
                throw new TypeError('Channel not defined');
            }
            if (!_pubsub_observers[channel]) {
                _pubsub_observers[channel] = [];
            }
            _pubsub_observers[channel].push(callback);
        },

        /**
         * Publish data to an event stream
         *
         * @param {String} channel Channel name
         * @param {Mixed} payload Payload to deliver
         */
        publish: function(channel, payload) {
            channel = (channel || '').toString();
            if (!channel) {
                throw new TypeError('Channel not defined');
            }

            _publish(channel, payload);
        },

        /**
         * Reloads the data from browser storage
         */
        reInit: function() {
            _reloadData();
        },

        /**
         * Removes reference from global objects and saves it as jStorage
         *
         * @param {Boolean} option if needed to save object as simple 'jStorage' in windows context
         */
        noConflict: function(saveInGlobal) {
            delete window.$.jStorage;

            if (saveInGlobal) {
                window.jStorage = this;
            }

            return this;
        }
    };

    // Initialize jStorage
    _init();

})();;
!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,h=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,i=/Windows Phone/i,j=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,k=/BlackBerry/i,l=/BB10/i,m=/Opera Mini/i,n=/(CriOS|Chrome)(?=.*\bMobile\b)/i,o=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,p=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),q=function(a,b){return a.test(b)},r=function(a){var r=a||navigator.userAgent,s=r.split("[FBAN");if("undefined"!=typeof s[1]&&(r=s[0]),s=r.split("Twitter"),"undefined"!=typeof s[1]&&(r=s[0]),this.apple={phone:q(b,r),ipod:q(c,r),tablet:!q(b,r)&&q(d,r),device:q(b,r)||q(c,r)||q(d,r)},this.amazon={phone:q(g,r),tablet:!q(g,r)&&q(h,r),device:q(g,r)||q(h,r)},this.android={phone:q(g,r)||q(e,r),tablet:!q(g,r)&&!q(e,r)&&(q(h,r)||q(f,r)),device:q(g,r)||q(h,r)||q(e,r)||q(f,r)},this.windows={phone:q(i,r),tablet:q(j,r),device:q(i,r)||q(j,r)},this.other={blackberry:q(k,r),blackberry10:q(l,r),opera:q(m,r),firefox:q(o,r),chrome:q(n,r),device:q(k,r)||q(l,r)||q(m,r)||q(o,r)||q(n,r)},this.seven_inch=q(p,r),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window)return this},s=function(){var a=new r;return a.Class=r,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=r:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=s():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=s()):a.isMobile=s()}(this);;
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).Sqrl={})}(this,(function(e){"use strict";function t(e){var n,r,a=new Error(e);return n=a,r=t.prototype,Object.setPrototypeOf?Object.setPrototypeOf(n,r):n.__proto__=r,a}function n(e,n,r){var a=n.slice(0,r).split(/\n/),i=a.length,s=a[i-1].length+1;throw t(e+=" at line "+i+" col "+s+":\n\n  "+n.split(/\n/)[i-1]+"\n  "+Array(s).join(" ")+"^")}t.prototype=Object.create(Error.prototype,{name:{value:"Squirrelly Error",enumerable:!1}});var r=new Function("return this")().Promise,a=!1;try{a=new Function("return (async function(){}).constructor")()}catch(e){if(!(e instanceof SyntaxError))throw e}function i(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function s(e,t,n){for(var r in t)i(t,r)&&(null==t[r]||"object"!=typeof t[r]||"storage"!==r&&"prefixes"!==r||n?e[r]=t[r]:e[r]=s({},t[r]));return e}var c=/^async +/,o=/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})*}|(?!\${)[^\\`])*`/g,l=/'(?:\\[\s\w"'\\`]|[^\n\r'\\])*?'/g,f=/"(?:\\[\s\w"'\\`]|[^\n\r"\\])*?"/g,u=/[.*+\-?^${}()|[\]\\]/g;function p(e){return u.test(e)?e.replace(u,"\\$&"):e}function h(e,r){r.rmWhitespace&&(e=e.replace(/[\r\n]+/g,"\n").replace(/^\s+|\s+$/gm,"")),o.lastIndex=0,l.lastIndex=0,f.lastIndex=0;var a=r.prefixes,i=[a.h,a.b,a.i,a.r,a.c,a.e].reduce((function(e,t){return e&&t?e+"|"+p(t):t?p(t):e}),""),s=new RegExp("([|()]|=>)|('|\"|`|\\/\\*)|\\s*((\\/)?(-|_)?"+p(r.tags[1])+")","g"),u=new RegExp("([^]*?)"+p(r.tags[0])+"(-|_)?\\s*("+i+")?\\s*","g"),h=0,d=!1;function g(t,a){var i,p={f:[]},g=0,v="c";function m(t){var a=e.slice(h,t),i=a.trim();if("f"===v)"safe"===i?p.raw=!0:r.async&&c.test(i)?(i=i.replace(c,""),p.f.push([i,"",!0])):p.f.push([i,""]);else if("fp"===v)p.f[p.f.length-1][1]+=i;else if("err"===v){if(i){var s=a.search(/\S/);n("invalid syntax",e,h+s)}}else p[v]=i;h=t+1}for("h"===a||"b"===a||"c"===a?v="n":"r"===a&&(p.raw=!0,a="i"),s.lastIndex=h;null!==(i=s.exec(e));){var y=i[1],x=i[2],w=i[3],b=i[4],F=i[5],S=i.index;if(y)"("===y?(0===g&&("n"===v?(m(S),v="p"):"f"===v&&(m(S),v="fp")),g++):")"===y?0===--g&&"c"!==v&&(m(S),v="err"):0===g&&"|"===y?(m(S),v="f"):"=>"===y&&(m(S),h+=1,v="res");else if(x){if("/*"===x){var I=e.indexOf("*/",s.lastIndex);-1===I&&n("unclosed comment",e,i.index),s.lastIndex=I+2}else if("'"===x){l.lastIndex=i.index,l.exec(e)?s.lastIndex=l.lastIndex:n("unclosed string",e,i.index)}else if('"'===x){f.lastIndex=i.index,f.exec(e)?s.lastIndex=f.lastIndex:n("unclosed string",e,i.index)}else if("`"===x){o.lastIndex=i.index,o.exec(e)?s.lastIndex=o.lastIndex:n("unclosed string",e,i.index)}}else if(w)return m(S),h=S+i[0].length,u.lastIndex=h,d=F,b&&"h"===a&&(a="s"),p.t=a,p}return n("unclosed tag",e,t),p}var v=function i(s,o){s.b=[],s.d=[];var l,f=!1,p=[];function v(e,t){e&&(e=function(e,t,n,r){var a,i;return"string"==typeof t.autoTrim?a=i=t.autoTrim:Array.isArray(t.autoTrim)&&(a=t.autoTrim[1],i=t.autoTrim[0]),(n||!1===n)&&(a=n),(r||!1===r)&&(i=r),"slurp"===a&&"slurp"===i?e.trim():("_"===a||"slurp"===a?e=String.prototype.trimLeft?e.trimLeft():e.replace(/^[\s\uFEFF\xA0]+/,""):"-"!==a&&"nl"!==a||(e=e.replace(/^(?:\n|\r|\r\n)/,"")),"_"===i||"slurp"===i?e=String.prototype.trimRight?e.trimRight():e.replace(/[\s\uFEFF\xA0]+$/,""):"-"!==i&&"nl"!==i||(e=e.replace(/(?:\n|\r|\r\n)$/,"")),e)}(e,r,d,t))&&(e=e.replace(/\\|'/g,"\\$&").replace(/\r\n|\n|\r/g,"\\n"),p.push(e))}for(;null!==(l=u.exec(e));){var m,y=l[1],x=l[2],w=l[3]||"";for(var b in a)if(a[b]===w){m=b;break}v(y,x),h=l.index+l[0].length,m||n("unrecognized tag type: "+w,e,h);var F=g(l.index,m),S=F.t;if("h"===S){var I=F.n||"";r.async&&c.test(I)&&(F.a=!0,F.n=I.replace(c,"")),F=i(F),p.push(F)}else if("c"===S){if(s.n===F.n)return f?(f.d=p,s.b.push(f)):s.d=p,s;n("Helper start and end don't match",e,l.index+l[0].length)}else if("b"===S){f?(f.d=p,s.b.push(f)):s.d=p;var R=F.n||"";r.async&&c.test(R)&&(F.a=!0,F.n=R.replace(c,"")),f=F,p=[]}else if("s"===S){var E=F.n||"";r.async&&c.test(E)&&(F.a=!0,F.n=E.replace(c,"")),p.push(F)}else p.push(F)}if(!o)throw t('unclosed helper "'+s.n+'"');return v(e.slice(h,e.length),!1),s.d=p,s}({f:[]},!0);if(r.plugins)for(var m=0;m<r.plugins.length;m++){var y=r.plugins[m];y.processAST&&(v.d=y.processAST(v.d,r))}return v.d}function d(e,t){var n=h(e,t),r="var tR='';"+(t.useWith?"with("+t.varName+"||{}){":"")+x(n,t)+"if(cb){cb(null,tR)} return tR"+(t.useWith?"}":"");if(t.plugins)for(var a=0;a<t.plugins.length;a++){var i=t.plugins[a];i.processFnString&&(r=i.processFnString(r,t))}return r}function g(e,t){for(var n=0;n<t.length;n++){var r=t[n][0],a=t[n][1];e=(t[n][2]?"await ":"")+"c.l('F','"+r+"')("+e,a&&(e+=","+a),e+=")"}return e}function v(e,t,n,r,a,i){var s="{exec:"+(a?"async ":"")+y(n,t,e)+",params:["+r+"]";return i&&(s+=",name:'"+i+"'"),a&&(s+=",async:true"),s+="}"}function m(e,t){for(var n="[",r=0;r<e.length;r++){var a=e[r];n+=v(t,a.res||"",a.d,a.p||"",a.a,a.n),r<e.length&&(n+=",")}return n+="]"}function y(e,t,n){return"function("+t+"){var tR='';"+x(e,n)+"return tR}"}function x(e,t){for(var n=0,r=e.length,a="";n<r;n++){var i=e[n];if("string"==typeof i){a+="tR+='"+i+"';"}else{var s=i.t,c=i.c||"",o=i.f,l=i.n||"",f=i.p||"",u=i.res||"",p=i.b,h=!!i.a;if("i"===s)t.defaultFilter&&(c="c.l('F','"+t.defaultFilter+"')("+c+")"),!i.raw&&t.autoEscape&&(c="c.l('F','e')("+c+")"),a+="tR+="+g(c,o)+";";else if("h"===s)if(t.storage.nativeHelpers.get(l))a+=t.storage.nativeHelpers.get(l)(i,t);else{var d=(h?"await ":"")+"c.l('H','"+l+"')("+v(t,u,i.d,f,h);d+=p?","+m(p,t):",[]",a+="tR+="+g(d+=",c)",o)+";"}else"s"===s?a+="tR+="+g((h?"await ":"")+"c.l('H','"+l+"')({params:["+f+"]},[],c)",o)+";":"e"===s&&(a+=c+"\n")}}return a}var w=function(){function e(e){this.cache=e}return e.prototype.define=function(e,t){this.cache[e]=t},e.prototype.get=function(e){return this.cache[e]},e.prototype.remove=function(e){delete this.cache[e]},e.prototype.reset=function(){this.cache={}},e.prototype.load=function(e){s(this.cache,e,!0)},e}(),b=new w({});function F(e,n,r,a){if(n&&n.length>0)throw t((a?"Native":"")+"Helper '"+e+"' doesn't accept blocks");if(r&&r.length>0)throw t((a?"Native":"")+"Helper '"+e+"' doesn't accept filters")}var S=new w({each:function(e,t){var n="",r=e.params[0];if(F("each",t,!1),e.async)return new Promise((function(t){!function e(t,n,r,a,i){r(t[n],n).then((function(s){a+=s,n===t.length-1?i(a):e(t,n+1,r,a,i)}))}(r,0,e.exec,n,t)}));for(var a=0;a<r.length;a++)n+=e.exec(r[a],a);return n},foreach:function(e,t){var n=e.params[0];if(F("foreach",t,!1),e.async)return new Promise((function(t){!function e(t,n,r,a,i,s){a(n[r],t[n[r]]).then((function(c){i+=c,r===n.length-1?s(i):e(t,n,r+1,a,i,s)}))}(n,Object.keys(n),0,e.exec,"",t)}));var r="";for(var a in n)i(n,a)&&(r+=e.exec(a,n[a]));return r},include:function(e,n,r){F("include",n,!1);var a=r.storage.templates.get(e.params[0]);if(!a)throw t('Could not fetch template "'+e.params[0]+'"');return a(e.params[1],r)},extends:function(e,n,r){var a=e.params[1]||{};a.content=e.exec();for(var i=0;i<n.length;i++){var s=n[i];a[s.name]=s.exec()}var c=r.storage.templates.get(e.params[0]);if(!c)throw t('Could not fetch template "'+e.params[0]+'"');return c(a,r)},useScope:function(e,t){return F("useScope",t,!1),e.exec(e.params[0])}}),I=new w({if:function(e,t){F("if",!1,e.f,!0);var n="if("+e.p+"){"+x(e.d,t)+"}";if(e.b)for(var r=0;r<e.b.length;r++){var a=e.b[r];"else"===a.n?n+="else{"+x(a.d,t)+"}":"elif"===a.n&&(n+="else if("+a.p+"){"+x(a.d,t)+"}")}return n},try:function(e,n){if(F("try",!1,e.f,!0),!e.b||1!==e.b.length||"catch"!==e.b[0].n)throw t("native helper 'try' only accepts 1 block, 'catch'");var r="try{"+x(e.d,n)+"}",a=e.b[0];return r+="catch"+(a.res?"("+a.res+")":"")+"{"+x(a.d,n)+"}"},block:function(e,t){return F("block",e.b,e.f,!0),"if(!"+t.varName+"["+e.p+"]){tR+=("+y(e.d,"",t)+")()}else{tR+="+t.varName+"["+e.p+"]}"}}),R={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function E(e){return R[e]}var j=new w({e:function(e){var t=String(e);return/[&<>"']/.test(t)?t.replace(/[&<>"']/g,E):t}}),H={varName:"it",autoTrim:[!1,"nl"],autoEscape:!0,defaultFilter:!1,tags:["{{","}}"],l:function(e,n){if("H"===e){var r=this.storage.helpers.get(n);if(r)return r;throw t("Can't find helper '"+n+"'")}if("F"===e){var a=this.storage.filters.get(n);if(a)return a;throw t("Can't find filter '"+n+"'")}},async:!1,storage:{helpers:S,nativeHelpers:I,filters:j,templates:b},prefixes:{h:"@",b:"#",i:"",r:"*",c:"/",e:"!"},cache:!1,plugins:[],useWith:!1};function O(e,t){var n={};return s(n,H),t&&s(n,t),e&&s(n,e),n.l.bind(n),n}function T(e,n){var r=O(n||{}),i=Function;if(r.async){if(!a)throw t("This environment doesn't support async/await");i=a}try{return new i(r.varName,"c","cb",d(e,r))}catch(n){throw n instanceof SyntaxError?t("Bad template syntax\n\n"+n.message+"\n"+Array(n.message.length+1).join("=")+"\n"+d(e,r)):n}}function _(e,t){var n;return t.cache&&t.name&&t.storage.templates.get(t.name)?t.storage.templates.get(t.name):(n="function"==typeof e?e:T(e,t),t.cache&&t.name&&t.storage.templates.define(t.name,n),n)}H.l.bind(H),e.compile=T,e.compileScope=x,e.compileScopeIntoFunction=y,e.compileToString=d,e.defaultConfig=H,e.filters=j,e.getConfig=O,e.helpers=S,e.nativeHelpers=I,e.parse=h,e.render=function(e,n,a,i){var s=O(a||{});if(!s.async)return _(e,s)(n,s);if(!i){if("function"==typeof r)return new r((function(t,r){try{t(_(e,s)(n,s))}catch(e){r(e)}}));throw t("Please provide a callback function, this env doesn't support Promises")}try{_(e,s)(n,s,i)}catch(e){return i(e)}},e.templates=b,Object.defineProperty(e,"__esModule",{value:!0})}));;
if (Sqrl === undefined) {
	throw new Error('Sqrl squirrelly.js global object is not defined.');
}

// Filters

/**
 * This converts an amount to the actual currency value. { amount: 4550, scale: 2, currency: 'GBP' } -> £45.50
 * 
 * Dice API response data returns currency values as 4550 and they provide a scale and a currency ISO code.
 * The scale is used to know how many decimal places we should add to the ammount. So 4550 with scale 2 turns into 45.50.
 * The currency ISO code (GBP for example) will be used to transform it into a currency symbol.
 */
Sqrl.filters.define("diceAmountConverter", function(amount, scale, currency) {
	'use strict';

	var result = (amount/(Math.pow(10, scale))).toFixed(scale);

	return Number(result).toLocaleString(undefined, { style: 'currency', currency: currency });
});

Sqrl.filters.define("intlDateTimeFormat", function(date, format) {
	'use strict';

	return (date && date !== 'undefined' && date !== 'null') ? new Intl.DateTimeFormat(format).format(new Date(parseInt(date, 10))) : '';
});

Sqrl.filters.define("default", function(val, defaultVal) {
	'use strict';

	// eslint-disable-next-line no-void
	return (val === void 0 || val === 'undefined' || val === 'null') ? defaultVal : val;
});
;
/*
 * International Telephone Input v17.0.3
 * https://github.com/jackocnr/intl-tel-input.git
 * Licensed under the MIT license
 */

!function(a){"object"==typeof module&&module.exports?module.exports=a():window.intlTelInput=a()}(function(a){"use strict";return function(){function b(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function c(a,b){for(var c=0;c<b.length;c++){var d=b[c];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(a,d.key,d)}}function d(a,b,d){return b&&c(a.prototype,b),d&&c(a,d),a}for(var e=[["Afghanistan (‫افغانستان‬‎)","af","93"],["Albania (Shqipëri)","al","355"],["Algeria (‫الجزائر‬‎)","dz","213"],["American Samoa","as","1",5,["684"]],["Andorra","ad","376"],["Angola","ao","244"],["Anguilla","ai","1",6,["264"]],["Antigua and Barbuda","ag","1",7,["268"]],["Argentina","ar","54"],["Armenia (Հայաստան)","am","374"],["Aruba","aw","297"],["Australia","au","61",0],["Austria (Österreich)","at","43"],["Azerbaijan (Azərbaycan)","az","994"],["Bahamas","bs","1",8,["242"]],["Bahrain (‫البحرين‬‎)","bh","973"],["Bangladesh (বাংলাদেশ)","bd","880"],["Barbados","bb","1",9,["246"]],["Belarus (Беларусь)","by","375"],["Belgium (België)","be","32"],["Belize","bz","501"],["Benin (Bénin)","bj","229"],["Bermuda","bm","1",10,["441"]],["Bhutan (འབྲུག)","bt","975"],["Bolivia","bo","591"],["Bosnia and Herzegovina (Босна и Херцеговина)","ba","387"],["Botswana","bw","267"],["Brazil (Brasil)","br","55"],["British Indian Ocean Territory","io","246"],["British Virgin Islands","vg","1",11,["284"]],["Brunei","bn","673"],["Bulgaria (България)","bg","359"],["Burkina Faso","bf","226"],["Burundi (Uburundi)","bi","257"],["Cambodia (កម្ពុជា)","kh","855"],["Cameroon (Cameroun)","cm","237"],["Canada","ca","1",1,["204","226","236","249","250","289","306","343","365","387","403","416","418","431","437","438","450","506","514","519","548","579","581","587","604","613","639","647","672","705","709","742","778","780","782","807","819","825","867","873","902","905"]],["Cape Verde (Kabu Verdi)","cv","238"],["Caribbean Netherlands","bq","599",1,["3","4","7"]],["Cayman Islands","ky","1",12,["345"]],["Central African Republic (République centrafricaine)","cf","236"],["Chad (Tchad)","td","235"],["Chile","cl","56"],["China (中国)","cn","86"],["Christmas Island","cx","61",2,["89164"]],["Cocos (Keeling) Islands","cc","61",1,["89162"]],["Colombia","co","57"],["Comoros (‫جزر القمر‬‎)","km","269"],["Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)","cd","243"],["Congo (Republic) (Congo-Brazzaville)","cg","242"],["Cook Islands","ck","682"],["Costa Rica","cr","506"],["Côte d’Ivoire","ci","225"],["Croatia (Hrvatska)","hr","385"],["Cuba","cu","53"],["Curaçao","cw","599",0],["Cyprus (Κύπρος)","cy","357"],["Czech Republic (Česká republika)","cz","420"],["Denmark (Danmark)","dk","45"],["Djibouti","dj","253"],["Dominica","dm","1",13,["767"]],["Dominican Republic (República Dominicana)","do","1",2,["809","829","849"]],["Ecuador","ec","593"],["Egypt (‫مصر‬‎)","eg","20"],["El Salvador","sv","503"],["Equatorial Guinea (Guinea Ecuatorial)","gq","240"],["Eritrea","er","291"],["Estonia (Eesti)","ee","372"],["Ethiopia","et","251"],["Falkland Islands (Islas Malvinas)","fk","500"],["Faroe Islands (Føroyar)","fo","298"],["Fiji","fj","679"],["Finland (Suomi)","fi","358",0],["France","fr","33"],["French Guiana (Guyane française)","gf","594"],["French Polynesia (Polynésie française)","pf","689"],["Gabon","ga","241"],["Gambia","gm","220"],["Georgia (საქართველო)","ge","995"],["Germany (Deutschland)","de","49"],["Ghana (Gaana)","gh","233"],["Gibraltar","gi","350"],["Greece (Ελλάδα)","gr","30"],["Greenland (Kalaallit Nunaat)","gl","299"],["Grenada","gd","1",14,["473"]],["Guadeloupe","gp","590",0],["Guam","gu","1",15,["671"]],["Guatemala","gt","502"],["Guernsey","gg","44",1,["1481","7781","7839","7911"]],["Guinea (Guinée)","gn","224"],["Guinea-Bissau (Guiné Bissau)","gw","245"],["Guyana","gy","592"],["Haiti","ht","509"],["Honduras","hn","504"],["Hong Kong (香港)","hk","852"],["Hungary (Magyarország)","hu","36"],["Iceland (Ísland)","is","354"],["India (भारत)","in","91"],["Indonesia","id","62"],["Iran (‫ایران‬‎)","ir","98"],["Iraq (‫العراق‬‎)","iq","964"],["Ireland","ie","353"],["Isle of Man","im","44",2,["1624","74576","7524","7924","7624"]],["Israel (‫ישראל‬‎)","il","972"],["Italy (Italia)","it","39",0],["Jamaica","jm","1",4,["876","658"]],["Japan (日本)","jp","81"],["Jersey","je","44",3,["1534","7509","7700","7797","7829","7937"]],["Jordan (‫الأردن‬‎)","jo","962"],["Kazakhstan (Казахстан)","kz","7",1,["33","7"]],["Kenya","ke","254"],["Kiribati","ki","686"],["Kosovo","xk","383"],["Kuwait (‫الكويت‬‎)","kw","965"],["Kyrgyzstan (Кыргызстан)","kg","996"],["Laos (ລາວ)","la","856"],["Latvia (Latvija)","lv","371"],["Lebanon (‫لبنان‬‎)","lb","961"],["Lesotho","ls","266"],["Liberia","lr","231"],["Libya (‫ليبيا‬‎)","ly","218"],["Liechtenstein","li","423"],["Lithuania (Lietuva)","lt","370"],["Luxembourg","lu","352"],["Macau (澳門)","mo","853"],["Macedonia (FYROM) (Македонија)","mk","389"],["Madagascar (Madagasikara)","mg","261"],["Malawi","mw","265"],["Malaysia","my","60"],["Maldives","mv","960"],["Mali","ml","223"],["Malta","mt","356"],["Marshall Islands","mh","692"],["Martinique","mq","596"],["Mauritania (‫موريتانيا‬‎)","mr","222"],["Mauritius (Moris)","mu","230"],["Mayotte","yt","262",1,["269","639"]],["Mexico (México)","mx","52"],["Micronesia","fm","691"],["Moldova (Republica Moldova)","md","373"],["Monaco","mc","377"],["Mongolia (Монгол)","mn","976"],["Montenegro (Crna Gora)","me","382"],["Montserrat","ms","1",16,["664"]],["Morocco (‫المغرب‬‎)","ma","212",0],["Mozambique (Moçambique)","mz","258"],["Myanmar (Burma) (မြန်မာ)","mm","95"],["Namibia (Namibië)","na","264"],["Nauru","nr","674"],["Nepal (नेपाल)","np","977"],["Netherlands (Nederland)","nl","31"],["New Caledonia (Nouvelle-Calédonie)","nc","687"],["New Zealand","nz","64"],["Nicaragua","ni","505"],["Niger (Nijar)","ne","227"],["Nigeria","ng","234"],["Niue","nu","683"],["Norfolk Island","nf","672"],["North Korea (조선 민주주의 인민 공화국)","kp","850"],["Northern Mariana Islands","mp","1",17,["670"]],["Norway (Norge)","no","47",0],["Oman (‫عُمان‬‎)","om","968"],["Pakistan (‫پاکستان‬‎)","pk","92"],["Palau","pw","680"],["Palestine (‫فلسطين‬‎)","ps","970"],["Panama (Panamá)","pa","507"],["Papua New Guinea","pg","675"],["Paraguay","py","595"],["Peru (Perú)","pe","51"],["Philippines","ph","63"],["Poland (Polska)","pl","48"],["Portugal","pt","351"],["Puerto Rico","pr","1",3,["787","939"]],["Qatar (‫قطر‬‎)","qa","974"],["Réunion (La Réunion)","re","262",0],["Romania (România)","ro","40"],["Russia (Россия)","ru","7",0],["Rwanda","rw","250"],["Saint Barthélemy","bl","590",1],["Saint Helena","sh","290"],["Saint Kitts and Nevis","kn","1",18,["869"]],["Saint Lucia","lc","1",19,["758"]],["Saint Martin (Saint-Martin (partie française))","mf","590",2],["Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)","pm","508"],["Saint Vincent and the Grenadines","vc","1",20,["784"]],["Samoa","ws","685"],["San Marino","sm","378"],["São Tomé and Príncipe (São Tomé e Príncipe)","st","239"],["Saudi Arabia (‫المملكة العربية السعودية‬‎)","sa","966"],["Senegal (Sénégal)","sn","221"],["Serbia (Србија)","rs","381"],["Seychelles","sc","248"],["Sierra Leone","sl","232"],["Singapore","sg","65"],["Sint Maarten","sx","1",21,["721"]],["Slovakia (Slovensko)","sk","421"],["Slovenia (Slovenija)","si","386"],["Solomon Islands","sb","677"],["Somalia (Soomaaliya)","so","252"],["South Africa","za","27"],["South Korea (대한민국)","kr","82"],["South Sudan (‫جنوب السودان‬‎)","ss","211"],["Spain (España)","es","34"],["Sri Lanka (ශ්‍රී ලංකාව)","lk","94"],["Sudan (‫السودان‬‎)","sd","249"],["Suriname","sr","597"],["Svalbard and Jan Mayen","sj","47",1,["79"]],["Swaziland","sz","268"],["Sweden (Sverige)","se","46"],["Switzerland (Schweiz)","ch","41"],["Syria (‫سوريا‬‎)","sy","963"],["Taiwan (台灣)","tw","886"],["Tajikistan","tj","992"],["Tanzania","tz","255"],["Thailand (ไทย)","th","66"],["Timor-Leste","tl","670"],["Togo","tg","228"],["Tokelau","tk","690"],["Tonga","to","676"],["Trinidad and Tobago","tt","1",22,["868"]],["Tunisia (‫تونس‬‎)","tn","216"],["Turkey (Türkiye)","tr","90"],["Turkmenistan","tm","993"],["Turks and Caicos Islands","tc","1",23,["649"]],["Tuvalu","tv","688"],["U.S. Virgin Islands","vi","1",24,["340"]],["Uganda","ug","256"],["Ukraine (Україна)","ua","380"],["United Arab Emirates (‫الإمارات العربية المتحدة‬‎)","ae","971"],["United Kingdom","gb","44",0],["United States","us","1",0],["Uruguay","uy","598"],["Uzbekistan (Oʻzbekiston)","uz","998"],["Vanuatu","vu","678"],["Vatican City (Città del Vaticano)","va","39",1,["06698"]],["Venezuela","ve","58"],["Vietnam (Việt Nam)","vn","84"],["Wallis and Futuna (Wallis-et-Futuna)","wf","681"],["Western Sahara (‫الصحراء الغربية‬‎)","eh","212",1,["5288","5289"]],["Yemen (‫اليمن‬‎)","ye","967"],["Zambia","zm","260"],["Zimbabwe","zw","263"],["Åland Islands","ax","358",1,["18"]]],f=0;f<e.length;f++){var g=e[f];e[f]={name:g[0],iso2:g[1],dialCode:g[2],priority:g[3]||0,areaCodes:g[4]||null}}var h={getInstance:function(a){var b=a.getAttribute("data-intl-tel-input-id");return window.intlTelInputGlobals.instances[b]},instances:{}};"object"==typeof window&&(window.intlTelInputGlobals=h);var i=0,j={allowDropdown:!0,autoHideDialCode:!0,autoPlaceholder:"polite",customContainer:"",customPlaceholder:null,dropdownContainer:null,excludeCountries:[],formatOnDisplay:!0,geoIpLookup:null,hiddenInput:"",initialCountry:"",localizedCountries:null,nationalMode:!0,onlyCountries:[],placeholderNumberType:"MOBILE",preferredCountries:["us","gb"],separateDialCode:!1,utilsScript:""},k=["800","822","833","844","855","866","877","880","881","882","883","884","885","886","887","888","889"];"object"==typeof window&&window.addEventListener("load",function(){window.intlTelInputGlobals.windowLoaded=!0});var l=function(a,b){for(var c=Object.keys(a),d=0;d<c.length;d++)b(c[d],a[c[d]])},m=function(a){l(window.intlTelInputGlobals.instances,function(b){window.intlTelInputGlobals.instances[b][a]()})},n=function(){function c(a,d){var e=this;b(this,c),this.id=i++,this.a=a,this.b=null,this.c=null;var f=d||{};this.d={},l(j,function(a,b){e.d[a]=f.hasOwnProperty(a)?f[a]:b}),this.e=Boolean(a.getAttribute("placeholder"))}return d(c,[{key:"_init",value:function(){var a=this;if(this.d.nationalMode&&(this.d.autoHideDialCode=!1),this.d.separateDialCode&&(this.d.autoHideDialCode=this.d.nationalMode=!1),this.g=/Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),this.g&&(document.body.classList.add("iti-mobile"),this.d.dropdownContainer||(this.d.dropdownContainer=document.body)),"undefined"!=typeof Promise){var b=new Promise(function(b,c){a.h=b,a.i=c}),c=new Promise(function(b,c){a.i0=b,a.i1=c});this.promise=Promise.all([b,c])}else this.h=this.i=function(){},this.i0=this.i1=function(){};this.s={},this._b(),this._f(),this._h(),this._i(),this._i3()}},{key:"_b",value:function(){this._d(),this._d2(),this._e(),this.d.localizedCountries&&this._d0(),(this.d.onlyCountries.length||this.d.localizedCountries)&&this.p.sort(this._d1)}},{key:"_c",value:function(b,c,d){c.length>this.countryCodeMaxLen&&(this.countryCodeMaxLen=c.length),this.q.hasOwnProperty(c)||(this.q[c]=[]);for(var e=0;e<this.q[c].length;e++)if(this.q[c][e]===b)return;var f=d!==a?d:this.q[c].length;this.q[c][f]=b}},{key:"_d",value:function(){if(this.d.onlyCountries.length){var a=this.d.onlyCountries.map(function(a){return a.toLowerCase()});this.p=e.filter(function(b){return a.indexOf(b.iso2)>-1})}else if(this.d.excludeCountries.length){var b=this.d.excludeCountries.map(function(a){return a.toLowerCase()});this.p=e.filter(function(a){return-1===b.indexOf(a.iso2)})}else this.p=e}},{key:"_d0",value:function(){for(var a=0;a<this.p.length;a++){var b=this.p[a].iso2.toLowerCase();this.d.localizedCountries.hasOwnProperty(b)&&(this.p[a].name=this.d.localizedCountries[b])}}},{key:"_d1",value:function(a,b){return a.name.localeCompare(b.name)}},{key:"_d2",value:function(){this.countryCodeMaxLen=0,this.dialCodes={},this.q={};for(var a=0;a<this.p.length;a++){var b=this.p[a];this.dialCodes[b.dialCode]||(this.dialCodes[b.dialCode]=!0),this._c(b.iso2,b.dialCode,b.priority)}for(var c=0;c<this.p.length;c++){var d=this.p[c];if(d.areaCodes)for(var e=this.q[d.dialCode][0],f=0;f<d.areaCodes.length;f++){for(var g=d.areaCodes[f],h=1;h<g.length;h++){var i=d.dialCode+g.substr(0,h);this._c(e,i),this._c(d.iso2,i)}this._c(d.iso2,d.dialCode+g)}}}},{key:"_e",value:function(){this.preferredCountries=[];for(var a=0;a<this.d.preferredCountries.length;a++){var b=this.d.preferredCountries[a].toLowerCase(),c=this._y(b,!1,!0);c&&this.preferredCountries.push(c)}}},{key:"_e2",value:function(a,b,c){var d=document.createElement(a);return b&&l(b,function(a,b){return d.setAttribute(a,b)}),c&&c.appendChild(d),d}},{key:"_f",value:function(){this.a.hasAttribute("autocomplete")||this.a.form&&this.a.form.hasAttribute("autocomplete")||this.a.setAttribute("autocomplete","off");var a="iti";this.d.allowDropdown&&(a+=" iti--allow-dropdown"),this.d.separateDialCode&&(a+=" iti--separate-dial-code"),this.d.customContainer&&(a+=" ",a+=this.d.customContainer);var b=this._e2("div",{"class":a});if(this.a.parentNode.insertBefore(b,this.a),this.k=this._e2("div",{"class":"iti__flag-container"},b),b.appendChild(this.a),this.selectedFlag=this._e2("div",{"class":"iti__selected-flag",role:"combobox","aria-owns":"iti-".concat(this.id,"__country-listbox"),"aria-expanded":"false"},this.k),this.l=this._e2("div",{"class":"iti__flag"},this.selectedFlag),this.d.separateDialCode&&(this.t=this._e2("div",{"class":"iti__selected-dial-code"},this.selectedFlag)),this.d.allowDropdown&&(this.selectedFlag.setAttribute("tabindex","0"),this.u=this._e2("div",{"class":"iti__arrow"},this.selectedFlag),this.m=this._e2("ul",{"class":"iti__country-list iti__hide",id:"iti-".concat(this.id,"__country-listbox"),role:"listbox"}),this.preferredCountries.length&&(this._g(this.preferredCountries,"iti__preferred",!0),this._e2("li",{"class":"iti__divider",role:"separator","aria-disabled":"true"},this.m)),this._g(this.p,"iti__standard"),this.d.dropdownContainer?(this.dropdown=this._e2("div",{"class":"iti iti--container"}),this.dropdown.appendChild(this.m)):this.k.appendChild(this.m)),this.d.hiddenInput){var c=this.d.hiddenInput,d=this.a.getAttribute("name");if(d){var e=d.lastIndexOf("[");-1!==e&&(c="".concat(d.substr(0,e),"[").concat(c,"]"))}this.hiddenInput=this._e2("input",{type:"hidden",name:c}),b.appendChild(this.hiddenInput)}}},{key:"_g",value:function(a,b,c){for(var d="",e=0;e<a.length;e++){var f=a[e],g=c?"-preferred":"";d+="<li class='iti__country ".concat(b,"' tabIndex='-1' id='iti-").concat(this.id,"__item-").concat(f.iso2).concat(g,"' role='option' data-dial-code='").concat(f.dialCode,"' data-country-code='").concat(f.iso2,"'>"),d+="<div class='iti__flag-box'><div class='iti__flag iti__".concat(f.iso2,"'></div></div>"),d+="<span class='iti__country-name'>".concat(f.name,"</span>"),d+="<span class='iti__dial-code'>+".concat(f.dialCode,"</span>"),d+="</li>"}this.m.insertAdjacentHTML("beforeend",d)}},{key:"_h",value:function(){var a=this.a.value,b=this._5(a),c=this._w(a),d=this.d,e=d.initialCountry,f=d.nationalMode,g=d.autoHideDialCode,h=d.separateDialCode;b&&!c?this._v(a):"auto"!==e&&(e?this._z(e.toLowerCase()):b&&c?this._z("us"):(this.j=this.preferredCountries.length?this.preferredCountries[0].iso2:this.p[0].iso2,a||this._z(this.j)),a||f||g||h||(this.a.value="+".concat(this.s.dialCode))),a&&this._u(a)}},{key:"_i",value:function(){this._j(),this.d.autoHideDialCode&&this._l(),this.d.allowDropdown&&this._i2(),this.hiddenInput&&this._i0()}},{key:"_i0",value:function(){var a=this;this._a14=function(){a.hiddenInput.value=a.getNumber()},this.a.form&&this.a.form.addEventListener("submit",this._a14)}},{key:"_i1",value:function(){for(var a=this.a;a&&"LABEL"!==a.tagName;)a=a.parentNode;return a}},{key:"_i2",value:function(){var a=this;this._a9=function(b){a.m.classList.contains("iti__hide")?a.a.focus():b.preventDefault()};var b=this._i1();b&&b.addEventListener("click",this._a9),this._a10=function(){!a.m.classList.contains("iti__hide")||a.a.disabled||a.a.readOnly||a._n()},this.selectedFlag.addEventListener("click",this._a10),this._a11=function(b){a.m.classList.contains("iti__hide")&&-1!==["ArrowUp","Up","ArrowDown","Down"," ","Enter"].indexOf(b.key)&&(b.preventDefault(),b.stopPropagation(),a._n()),"Tab"===b.key&&a._2()},this.k.addEventListener("keydown",this._a11)}},{key:"_i3",value:function(){var a=this;this.d.utilsScript&&!window.intlTelInputUtils?window.intlTelInputGlobals.windowLoaded?window.intlTelInputGlobals.loadUtils(this.d.utilsScript):window.addEventListener("load",function(){window.intlTelInputGlobals.loadUtils(a.d.utilsScript)}):this.i0(),"auto"===this.d.initialCountry?this._i4():this.h()}},{key:"_i4",value:function(){window.intlTelInputGlobals.autoCountry?this.handleAutoCountry():window.intlTelInputGlobals.startedLoadingAutoCountry||(window.intlTelInputGlobals.startedLoadingAutoCountry=!0,"function"==typeof this.d.geoIpLookup&&this.d.geoIpLookup(function(a){window.intlTelInputGlobals.autoCountry=a.toLowerCase(),setTimeout(function(){return m("handleAutoCountry")})},function(){return m("rejectAutoCountryPromise")}))}},{key:"_j",value:function(){var a=this;this._a12=function(){a._v(a.a.value)&&a._8()},this.a.addEventListener("keyup",this._a12),this._a13=function(){setTimeout(a._a12)},this.a.addEventListener("cut",this._a13),this.a.addEventListener("paste",this._a13)}},{key:"_j2",value:function(a){var b=this.a.getAttribute("maxlength");return b&&a.length>b?a.substr(0,b):a}},{key:"_l",value:function(){var a=this;this._a8=function(){a._l2()},this.a.form&&this.a.form.addEventListener("submit",this._a8),this.a.addEventListener("blur",this._a8)}},{key:"_l2",value:function(){if("+"===this.a.value.charAt(0)){var a=this._m(this.a.value);a&&this.s.dialCode!==a||(this.a.value="")}}},{key:"_m",value:function(a){return a.replace(/\D/g,"")}},{key:"_m2",value:function(a){var b=document.createEvent("Event");b.initEvent(a,!0,!0),this.a.dispatchEvent(b)}},{key:"_n",value:function(){this.m.classList.remove("iti__hide"),this.selectedFlag.setAttribute("aria-expanded","true"),this._o(),this.b&&(this._x(this.b,!1),this._3(this.b,!0)),this._p(),this.u.classList.add("iti__arrow--up"),this._m2("open:countrydropdown")}},{key:"_n2",value:function(a,b,c){c&&!a.classList.contains(b)?a.classList.add(b):!c&&a.classList.contains(b)&&a.classList.remove(b)}},{key:"_o",value:function(){var a=this;if(this.d.dropdownContainer&&this.d.dropdownContainer.appendChild(this.dropdown),!this.g){var b=this.a.getBoundingClientRect(),c=window.pageYOffset||document.documentElement.scrollTop,d=b.top+c,e=this.m.offsetHeight,f=d+this.a.offsetHeight+e<c+window.innerHeight,g=d-e>c;if(this._n2(this.m,"iti__country-list--dropup",!f&&g),this.d.dropdownContainer){var h=!f&&g?0:this.a.offsetHeight;this.dropdown.style.top="".concat(d+h,"px"),this.dropdown.style.left="".concat(b.left+document.body.scrollLeft,"px"),this._a4=function(){return a._2()},window.addEventListener("scroll",this._a4)}}}},{key:"_o2",value:function(a){for(var b=a;b&&b!==this.m&&!b.classList.contains("iti__country");)b=b.parentNode;return b===this.m?null:b}},{key:"_p",value:function(){var a=this;this._a0=function(b){var c=a._o2(b.target);c&&a._x(c,!1)},this.m.addEventListener("mouseover",this._a0),this._a1=function(b){var c=a._o2(b.target);c&&a._1(c)},this.m.addEventListener("click",this._a1);var b=!0;this._a2=function(){b||a._2(),b=!1},document.documentElement.addEventListener("click",this._a2);var c="",d=null;this._a3=function(b){b.preventDefault(),"ArrowUp"===b.key||"Up"===b.key||"ArrowDown"===b.key||"Down"===b.key?a._q(b.key):"Enter"===b.key?a._r():"Escape"===b.key?a._2():/^[a-zA-ZÀ-ÿа-яА-Я ]$/.test(b.key)&&(d&&clearTimeout(d),c+=b.key.toLowerCase(),a._s(c),d=setTimeout(function(){c=""},1e3))},document.addEventListener("keydown",this._a3)}},{key:"_q",value:function(a){var b="ArrowUp"===a||"Up"===a?this.c.previousElementSibling:this.c.nextElementSibling;b&&(b.classList.contains("iti__divider")&&(b="ArrowUp"===a||"Up"===a?b.previousElementSibling:b.nextElementSibling),this._x(b,!0))}},{key:"_r",value:function(){this.c&&this._1(this.c)}},{key:"_s",value:function(a){for(var b=0;b<this.p.length;b++)if(this._t(this.p[b].name,a)){var c=this.m.querySelector("#iti-".concat(this.id,"__item-").concat(this.p[b].iso2));this._x(c,!1),this._3(c,!0);break}}},{key:"_t",value:function(a,b){return a.substr(0,b.length).toLowerCase()===b}},{key:"_u",value:function(a){var b=a;if(this.d.formatOnDisplay&&window.intlTelInputUtils&&this.s){var c=!this.d.separateDialCode&&(this.d.nationalMode||"+"!==b.charAt(0)),d=intlTelInputUtils.numberFormat,e=d.NATIONAL,f=d.INTERNATIONAL,g=c?e:f;b=intlTelInputUtils.formatNumber(b,this.s.iso2,g)}b=this._7(b),this.a.value=b}},{key:"_v",value:function(a){var b=a,c=this.s.dialCode,d="1"===c;b&&this.d.nationalMode&&d&&"+"!==b.charAt(0)&&("1"!==b.charAt(0)&&(b="1".concat(b)),b="+".concat(b)),this.d.separateDialCode&&c&&"+"!==b.charAt(0)&&(b="+".concat(c).concat(b));var e=this._5(b,!0),f=this._m(b),g=null;if(e){var h=this.q[this._m(e)],i=-1!==h.indexOf(this.s.iso2)&&f.length<=e.length-1;if(!("1"===c&&this._w(f))&&!i)for(var j=0;j<h.length;j++)if(h[j]){g=h[j];break}}else"+"===b.charAt(0)&&f.length?g="":b&&"+"!==b||(g=this.j);return null!==g&&this._z(g)}},{key:"_w",value:function(a){var b=this._m(a);if("1"===b.charAt(0)){var c=b.substr(1,3);return-1!==k.indexOf(c)}return!1}},{key:"_x",value:function(a,b){var c=this.c;c&&c.classList.remove("iti__highlight"),this.c=a,this.c.classList.add("iti__highlight"),b&&this.c.focus()}},{key:"_y",value:function(a,b,c){for(var d=b?e:this.p,f=0;f<d.length;f++)if(d[f].iso2===a)return d[f];if(c)return null;throw new Error("No country data for '".concat(a,"'"))}},{key:"_z",value:function(a){var b=this.s.iso2?this.s:{};this.s=a?this._y(a,!1,!1):{},this.s.iso2&&(this.j=this.s.iso2),this.l.setAttribute("class","iti__flag iti__".concat(a));var c=a?"".concat(this.s.name,": +").concat(this.s.dialCode):"Unknown";if(this.selectedFlag.setAttribute("title",c),this.d.separateDialCode){var d=this.s.dialCode?"+".concat(this.s.dialCode):"";this.t.innerHTML=d;var e=this.selectedFlag.offsetWidth||this._getHiddenSelectedFlagWidth();this.a.style.paddingLeft="".concat(e+6,"px")}if(this._0(),this.d.allowDropdown){var f=this.b;if(f&&(f.classList.remove("iti__active"),f.setAttribute("aria-selected","false")),a){var g=this.m.querySelector("#iti-".concat(this.id,"__item-").concat(a,"-preferred"))||this.m.querySelector("#iti-".concat(this.id,"__item-").concat(a));g.setAttribute("aria-selected","true"),g.classList.add("iti__active"),this.b=g,this.selectedFlag.setAttribute("aria-activedescendant",g.getAttribute("id"))}}return b.iso2!==a}},{key:"_getHiddenSelectedFlagWidth",value:function(){var a=this.a.parentNode.cloneNode();a.style.visibility="hidden",document.body.appendChild(a);var b=this.k.cloneNode();a.appendChild(b);var c=this.selectedFlag.cloneNode(!0);b.appendChild(c);var d=c.offsetWidth;return a.parentNode.removeChild(a),d}},{key:"_0",value:function(){var a="aggressive"===this.d.autoPlaceholder||!this.e&&"polite"===this.d.autoPlaceholder;if(window.intlTelInputUtils&&a){var b=intlTelInputUtils.numberType[this.d.placeholderNumberType],c=this.s.iso2?intlTelInputUtils.getExampleNumber(this.s.iso2,this.d.nationalMode,b):"";c=this._7(c),"function"==typeof this.d.customPlaceholder&&(c=this.d.customPlaceholder(c,this.s)),this.a.setAttribute("placeholder",c)}}},{key:"_1",value:function(a){var b=this._z(a.getAttribute("data-country-code"));this._2(),this._4(a.getAttribute("data-dial-code"),!0),this.a.focus();var c=this.a.value.length;this.a.setSelectionRange(c,c),b&&this._8()}},{key:"_2",value:function(){this.m.classList.add("iti__hide"),this.selectedFlag.setAttribute("aria-expanded","false"),this.u.classList.remove("iti__arrow--up"),document.removeEventListener("keydown",this._a3),document.documentElement.removeEventListener("click",this._a2),this.m.removeEventListener("mouseover",this._a0),this.m.removeEventListener("click",this._a1),this.d.dropdownContainer&&(this.g||window.removeEventListener("scroll",this._a4),this.dropdown.parentNode&&this.dropdown.parentNode.removeChild(this.dropdown)),this._m2("close:countrydropdown")}},{key:"_3",value:function(a,b){var c=this.m,d=window.pageYOffset||document.documentElement.scrollTop,e=c.offsetHeight,f=c.getBoundingClientRect().top+d,g=f+e,h=a.offsetHeight,i=a.getBoundingClientRect().top+d,j=i+h,k=i-f+c.scrollTop,l=e/2-h/2;if(i<f)b&&(k-=l),c.scrollTop=k;else if(j>g){b&&(k+=l);var m=e-h;c.scrollTop=k-m}}},{key:"_4",value:function(a,b){var c,d=this.a.value,e="+".concat(a);if("+"===d.charAt(0)){var f=this._5(d);c=f?d.replace(f,e):e}else{if(this.d.nationalMode||this.d.separateDialCode)return;if(d)c=e+d;else{if(!b&&this.d.autoHideDialCode)return;c=e}}this.a.value=c}},{key:"_5",value:function(a,b){var c="";if("+"===a.charAt(0))for(var d="",e=0;e<a.length;e++){var f=a.charAt(e);if(!isNaN(parseInt(f,10))){if(d+=f,b)this.q[d]&&(c=a.substr(0,e+1));else if(this.dialCodes[d]){c=a.substr(0,e+1);break}if(d.length===this.countryCodeMaxLen)break}}return c}},{key:"_6",value:function(){var a=this.a.value.trim(),b=this.s.dialCode,c=this._m(a);return(this.d.separateDialCode&&"+"!==a.charAt(0)&&b&&c?"+".concat(b):"")+a}},{key:"_7",value:function(a){var b=a;if(this.d.separateDialCode){var c=this._5(b);if(c){c="+".concat(this.s.dialCode);var d=" "===b[c.length]||"-"===b[c.length]?c.length+1:c.length;b=b.substr(d)}}return this._j2(b)}},{key:"_8",value:function(){this._m2("countrychange")}},{key:"handleAutoCountry",value:function(){"auto"===this.d.initialCountry&&(this.j=window.intlTelInputGlobals.autoCountry,this.a.value||this.setCountry(this.j),this.h())}},{key:"handleUtils",value:function(){window.intlTelInputUtils&&(this.a.value&&this._u(this.a.value),this._0()),this.i0()}},{key:"destroy",value:function(){var a=this.a.form;if(this.d.allowDropdown){this._2(),this.selectedFlag.removeEventListener("click",this._a10),this.k.removeEventListener("keydown",this._a11);var b=this._i1();b&&b.removeEventListener("click",this._a9)}this.hiddenInput&&a&&a.removeEventListener("submit",this._a14),this.d.autoHideDialCode&&(a&&a.removeEventListener("submit",this._a8),this.a.removeEventListener("blur",this._a8)),this.a.removeEventListener("keyup",this._a12),this.a.removeEventListener("cut",this._a13),this.a.removeEventListener("paste",this._a13),this.a.removeAttribute("data-intl-tel-input-id");var c=this.a.parentNode;c.parentNode.insertBefore(this.a,c),c.parentNode.removeChild(c),delete window.intlTelInputGlobals.instances[this.id]}},{key:"getExtension",value:function(){return window.intlTelInputUtils?intlTelInputUtils.getExtension(this._6(),this.s.iso2):""}},{key:"getNumber",value:function(a){if(window.intlTelInputUtils){var b=this.s.iso2;return intlTelInputUtils.formatNumber(this._6(),b,a)}return""}},{key:"getNumberType",value:function(){
return window.intlTelInputUtils?intlTelInputUtils.getNumberType(this._6(),this.s.iso2):-99}},{key:"getSelectedCountryData",value:function(){return this.s}},{key:"getValidationError",value:function(){if(window.intlTelInputUtils){var a=this.s.iso2;return intlTelInputUtils.getValidationError(this._6(),a)}return-99}},{key:"isValidNumber",value:function(){var a=this._6().trim(),b=this.d.nationalMode?this.s.iso2:"";return window.intlTelInputUtils?intlTelInputUtils.isValidNumber(a,b):null}},{key:"setCountry",value:function(a){var b=a.toLowerCase();this.l.classList.contains("iti__".concat(b))||(this._z(b),this._4(this.s.dialCode,!1),this._8())}},{key:"setNumber",value:function(a){var b=this._v(a);this._u(a),b&&this._8()}},{key:"setPlaceholderNumberType",value:function(a){this.d.placeholderNumberType=a,this._0()}}]),c}();h.getCountryData=function(){return e};var o=function(a,b,c){var d=document.createElement("script");d.onload=function(){m("handleUtils"),b&&b()},d.onerror=function(){m("rejectUtilsScriptPromise"),c&&c()},d.className="iti-load-utils",d.async=!0,d.src=a,document.body.appendChild(d)};return h.loadUtils=function(a){if(!window.intlTelInputUtils&&!window.intlTelInputGlobals.startedLoadingUtilsScript){if(window.intlTelInputGlobals.startedLoadingUtilsScript=!0,"undefined"!=typeof Promise)return new Promise(function(b,c){return o(a,b,c)});o(a)}return null},h.defaults=j,h.version="17.0.3",function(a,b){var c=new n(a,b);return c._init(),a.setAttribute("data-intl-tel-input-id",c.id),window.intlTelInputGlobals.instances[c.id]=c,c}}()});;
