Your IP : 216.73.216.52


Current Path : /proc/thread-self/cwd/static/frontend/Magento/blank/it_IT/js/bundle/
Upload File :
Current File : //proc/thread-self/cwd/static/frontend/Magento/blank/it_IT/js/bundle/bundle5.js

require.config({"config": {
        "jsbuild":{"Mageplaza_Blog/js/get-editor.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_Blog\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\ndefine([\r\n    'jquery',\r\n    \"mage/adminhtml/events\",\r\n    \"mage/adminhtml/wysiwyg/tiny_mce/setup\"\r\n], function ($) {\r\n    'use strict';\r\n\r\n    return {\r\n        config: function (nameEL, versionEditor, versionMagento, width) {\r\n            var wysiwygcompany_description,\r\n                config = {},\r\n                editor;\r\n\r\n            if (typeof width === 'undefined') {\r\n                width = '99%';\r\n            }\r\n\r\n            if (versionMagento === \"2\") {\r\n                $.extend(config, {\r\n                    settings: {\r\n                        theme_advanced_buttons1: 'bold,italic,|,justifyleft,justifycenter,justifyright,|,' +\r\n                            'fontselect,fontsizeselect,|,forecolor,backcolor,|,link,unlink,image,|,' +\r\n                            'bullist,numlist,|,code',\r\n                        theme_advanced_buttons2: null,\r\n                        theme_advanced_buttons3: null,\r\n                        theme_advanced_buttons4: null\r\n                    }\r\n                });\r\n                editor = new tinyMceWysiwygSetup(\r\n                    nameEL,\r\n                    config\r\n                );\r\n                editor.turnOn();\r\n                $('#' + nameEL).addClass('wysiwyg-editor').data('wysiwygEditor', editor);\r\n            } else if (versionEditor === \"4\") {\r\n                wysiwygcompany_description = new wysiwygSetup(nameEL, {\r\n                    \"width\": width,\r\n                    \"height\": \"200px\",\r\n                    \"plugins\": [{\"name\": \"image\"}],\r\n                    \"tinymce4\": {\r\n                        \"toolbar\": \"formatselect | bold italic underline | alignleft aligncenter alignright |\" +\r\n                            \" bullist numlist | link table charmap\",\r\n                        \"plugins\": \"advlist autolink lists link charmap media noneditable\" +\r\n                            \" table contextmenu paste code help table\"\r\n                    }\r\n                });\r\n                wysiwygcompany_description.setup(\"exact\");\r\n            } else {\r\n                $.extend(config, {\r\n                    settings: {\r\n                        theme_advanced_buttons1: 'bold,italic,|,justifyleft,justifycenter,justifyright,|,' +\r\n                            'fontselect,fontsizeselect,|,forecolor,backcolor,|,link,unlink,image,|,' +\r\n                            'bullist,numlist,|,code',\r\n                        theme_advanced_buttons2: null,\r\n                        theme_advanced_buttons3: null,\r\n                        theme_advanced_buttons4: null\r\n                    },\r\n                    tinymce : {\r\n                        content_css : null\r\n                    }\r\n                });\r\n                editor = new wysiwygSetup(\r\n                    nameEL,\r\n                    config\r\n                );\r\n                editor.setup(\"exact\");\r\n                $('#' + nameEL).addClass('wysiwyg-editor').data('wysiwygEditor', editor);\r\n            }\r\n        }\r\n    };\r\n});","Mageplaza_Blog/js/splide.min.js":"function r(n,t){for(var i=0;i<t.length;i++){var r=t[i];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(n,r.key,r)}}function Jt(n,t,i){t&&r(n.prototype,t),i&&r(n,i),Object.defineProperty(n,\"prototype\",{writable:!1})}\n/*!\n * Splide.js\n * Version  : 4.1.4\n * License  : MIT\n * Copyright: 2022 Naotoshi Fujita\n */\nvar n,t;n=this,t=function(){\"use strict\";var v=\"(prefers-reduced-motion: reduce)\",G=4,rn=5,r={CREATED:1,MOUNTED:2,IDLE:3,MOVING:G,SCROLLING:rn,DRAGGING:6,DESTROYED:7};function D(n){n.length=0}function o(n,t,i){return Array.prototype.slice.call(n,t,i)}function R(n){return n.bind.apply(n,[null].concat(o(arguments,1)))}function on(){}var p=setTimeout;function h(n){return requestAnimationFrame(n)}function u(n,t){return typeof t===n}function un(n){return!c(n)&&u(\"object\",n)}var e=Array.isArray,x=R(u,\"function\"),C=R(u,\"string\"),en=R(u,\"undefined\");function c(n){return null===n}function m(n){try{return n instanceof(n.ownerDocument.defaultView||window).HTMLElement}catch(n){return!1}}function y(n){return e(n)?n:[n]}function g(n,t){y(n).forEach(t)}function b(n,t){return-1<n.indexOf(t)}function k(n,t){return n.push.apply(n,y(t)),n}function A(t,n,i){t&&g(n,function(n){n&&t.classList[i?\"add\":\"remove\"](n)})}function M(n,t){A(n,C(t)?t.split(\" \"):t,!0)}function L(n,t){g(t,n.appendChild.bind(n))}function O(n,i){g(n,function(n){var t=(i||n).parentNode;t&&t.insertBefore(n,i)})}function cn(n,t){return m(n)&&(n.msMatchesSelector||n.matches).call(n,t)}function S(n,t){n=n?o(n.children):[];return t?n.filter(function(n){return cn(n,t)}):n}function fn(n,t){return t?S(n,t)[0]:n.firstElementChild}var E=Object.keys;function w(t,i,n){t&&(n?E(t).reverse():E(t)).forEach(function(n){\"__proto__\"!==n&&i(t[n],n)})}function an(r){return o(arguments,1).forEach(function(i){w(i,function(n,t){r[t]=i[t]})}),r}function d(i){return o(arguments,1).forEach(function(n){w(n,function(n,t){e(n)?i[t]=n.slice():un(n)?i[t]=d({},un(i[t])?i[t]:{},n):i[t]=n})}),i}function sn(t,n){g(n||E(t),function(n){delete t[n]})}function P(n,i){g(n,function(t){g(i,function(n){t&&t.removeAttribute(n)})})}function I(i,t,r){un(t)?w(t,function(n,t){I(i,t,n)}):g(i,function(n){c(r)||\"\"===r?P(n,t):n.setAttribute(t,String(r))})}function j(n,t,i){n=document.createElement(n);return t&&(C(t)?M:I)(n,t),i&&L(i,n),n}function _(n,t,i){if(en(i))return getComputedStyle(n)[t];c(i)||(n.style[t]=\"\"+i)}function ln(n,t){_(n,\"display\",t)}function dn(n){n.setActive&&n.setActive()||n.focus({preventScroll:!0})}function z(n,t){return n.getAttribute(t)}function vn(n,t){return n&&n.classList.contains(t)}function N(n){return n.getBoundingClientRect()}function T(n){g(n,function(n){n&&n.parentNode&&n.parentNode.removeChild(n)})}function hn(n){return fn((new DOMParser).parseFromString(n,\"text/html\").body)}function F(n,t){n.preventDefault(),t&&(n.stopPropagation(),n.stopImmediatePropagation())}function pn(n,t){return n&&n.querySelector(t)}function gn(n,t){return t?o(n.querySelectorAll(t)):[]}function X(n,t){A(n,t,!1)}function mn(n){return n.timeStamp}function W(n){return C(n)?n:n?n+\"px\":\"\"}var yn=\"splide\",f=\"data-\"+yn;function bn(n,t){if(!n)throw new Error(\"[\"+yn+\"] \"+(t||\"\"))}var Y=Math.min,wn=Math.max,xn=Math.floor,kn=Math.ceil,U=Math.abs;function Sn(n,t,i){return U(n-t)<i}function En(n,t,i,r){var o=Y(t,i),t=wn(t,i);return r?o<n&&n<t:o<=n&&n<=t}function q(n,t,i){var r=Y(t,i),t=wn(t,i);return Y(wn(r,n),t)}function Ln(n){return(0<n)-(n<0)}function On(t,n){return g(n,function(n){t=t.replace(\"%s\",\"\"+n)}),t}function An(n){return n<10?\"0\"+n:\"\"+n}var _n={};function zn(){var c=[];function i(n,i,r){g(n,function(t){t&&g(i,function(n){n.split(\" \").forEach(function(n){n=n.split(\".\");r(t,n[0],n[1])})})})}return{bind:function(n,t,u,e){i(n,t,function(n,t,i){var r=\"addEventListener\"in n,o=r?n.removeEventListener.bind(n,t,u,e):n.removeListener.bind(n,u);r?n.addEventListener(t,u,e):n.addListener(u),c.push([n,t,i,u,o])})},unbind:function(n,t,o){i(n,t,function(t,i,r){c=c.filter(function(n){return!!(n[0]!==t||n[1]!==i||n[2]!==r||o&&n[3]!==o)||(n[4](),!1)})})},dispatch:function(n,t,i){var r;return\"function\"==typeof CustomEvent?r=new CustomEvent(t,{bubbles:!0,detail:i}):(r=document.createEvent(\"CustomEvent\")).initCustomEvent(t,!0,!1,i),n.dispatchEvent(r),r},destroy:function(){c.forEach(function(n){n[4]()}),D(c)}}}var B=\"mounted\",H=\"move\",Dn=\"moved\",Mn=\"click\",Pn=\"active\",In=\"inactive\",Rn=\"visible\",Cn=\"hidden\",J=\"refresh\",K=\"updated\",jn=\"resize\",Nn=\"resized\",Tn=\"scroll\",V=\"scrolled\",a=\"destroy\",Gn=\"navigation:mounted\",Fn=\"autoplay:play\",Xn=\"autoplay:pause\",Wn=\"lazyload:loaded\",Yn=\"sk\",Un=\"sh\";function Q(n){var i=n?n.event.bus:document.createDocumentFragment(),r=zn();return n&&n.event.on(a,r.destroy),an(r,{bus:i,on:function(n,t){r.bind(i,y(n).join(\" \"),function(n){t.apply(t,e(n.detail)?n.detail:[])})},off:R(r.unbind,i),emit:function(n){r.dispatch(i,n,o(arguments,1))}})}function qn(t,n,i,r){var o,u,e=Date.now,c=0,f=!0,a=0;function s(){if(!f){if(c=t?Y((e()-o)/t,1):1,i&&i(c),1<=c&&(n(),o=e(),r&&++a>=r))return l();u=h(s)}}function l(){f=!0}function d(){u&&cancelAnimationFrame(u),f=!(u=c=0)}return{start:function(n){n||d(),o=e()-(n?c*t:0),f=!1,u=h(s)},rewind:function(){o=e(),c=0,i&&i(c)},pause:l,cancel:d,set:function(n){t=n},isPaused:function(){return f}}}function s(n){var t=n;return{set:function(n){t=n},is:function(n){return b(y(n),t)}}}var n=\"Arrow\",Bn=n+\"Left\",Hn=n+\"Right\",t=n+\"Up\",n=n+\"Down\",Jn=\"ttb\",l={width:[\"height\"],left:[\"top\",\"right\"],right:[\"bottom\",\"left\"],x:[\"y\"],X:[\"Y\"],Y:[\"X\"],ArrowLeft:[t,Hn],ArrowRight:[n,Bn]};var Z=\"role\",$=\"tabindex\",i=\"aria-\",Kn=i+\"controls\",Vn=i+\"current\",Qn=i+\"selected\",nn=i+\"label\",Zn=i+\"labelledby\",$n=i+\"hidden\",nt=i+\"orientation\",tt=i+\"roledescription\",it=i+\"live\",rt=i+\"busy\",ot=i+\"atomic\",ut=[Z,$,\"disabled\",Kn,Vn,nn,Zn,$n,nt,tt],i=yn+\"__\",et=yn,ct=i+\"track\",ft=i+\"list\",at=i+\"slide\",st=at+\"--clone\",lt=at+\"__container\",dt=i+\"arrows\",vt=i+\"arrow\",ht=vt+\"--prev\",pt=vt+\"--next\",gt=i+\"pagination\",mt=gt+\"__page\",yt=i+\"progress\"+\"__bar\",bt=i+\"toggle\",wt=i+\"sr\",tn=\"is-active\",xt=\"is-prev\",kt=\"is-next\",St=\"is-visible\",Et=\"is-loading\",Lt=\"is-focus-in\",Ot=\"is-overflow\",At=[tn,St,xt,kt,Et,Lt,Ot];var _t=\"touchstart mousedown\",zt=\"touchmove mousemove\",Dt=\"touchend touchcancel mouseup click\";var Mt=\"slide\",Pt=\"loop\",It=\"fade\";function Rt(o,r,t,u){var e,n=Q(o),i=n.on,c=n.emit,f=n.bind,a=o.Components,s=o.root,l=o.options,d=l.isNavigation,v=l.updateOnMove,h=l.i18n,p=l.pagination,g=l.slideFocus,m=a.Direction.resolve,y=z(u,\"style\"),b=z(u,nn),w=-1<t,x=fn(u,\".\"+lt);function k(){var n=o.splides.map(function(n){n=n.splide.Components.Slides.getAt(r);return n?n.slide.id:\"\"}).join(\" \");I(u,nn,On(h.slideX,(w?t:r)+1)),I(u,Kn,n),I(u,Z,g?\"button\":\"\"),g&&P(u,tt)}function S(){e||E()}function E(){var n,t,i;e||(n=o.index,(i=L())!==vn(u,tn)&&(A(u,tn,i),I(u,Vn,d&&i||\"\"),c(i?Pn:In,O)),i=function(){if(o.is(It))return L();var n=N(a.Elements.track),t=N(u),i=m(\"left\",!0),r=m(\"right\",!0);return xn(n[i])<=kn(t[i])&&xn(t[r])<=kn(n[r])}(),t=!i&&(!L()||w),o.state.is([G,rn])||I(u,$n,t||\"\"),I(gn(u,l.focusableNodes||\"\"),$,t?-1:\"\"),g&&I(u,$,t?-1:0),i!==vn(u,St)&&(A(u,St,i),c(i?Rn:Cn,O)),i||document.activeElement!==u||(t=a.Slides.getAt(o.index))&&dn(t.slide),A(u,xt,r===n-1),A(u,kt,r===n+1))}function L(){var n=o.index;return n===r||l.cloneStatus&&n===t}var O={index:r,slideIndex:t,slide:u,container:x,isClone:w,mount:function(){w||(u.id=s.id+\"-slide\"+An(r+1),I(u,Z,p?\"tabpanel\":\"group\"),I(u,tt,h.slide),I(u,nn,b||On(h.slideLabel,[r+1,o.length]))),f(u,\"click\",R(c,Mn,O)),f(u,\"keydown\",R(c,Yn,O)),i([Dn,Un,V],E),i(Gn,k),v&&i(H,S)},destroy:function(){e=!0,n.destroy(),X(u,At),P(u,ut),I(u,\"style\",y),I(u,nn,b||\"\")},update:E,style:function(n,t,i){_(i&&x||u,n,t)},isWithin:function(n,t){return n=U(n-r),(n=w||!l.rewind&&!o.is(Pt)?n:Y(n,o.length-n))<=t}};return O}var Ct=f+\"-interval\";var jt={passive:!1,capture:!0};var Nt={Spacebar:\" \",Right:Hn,Left:Bn,Up:t,Down:n};function Tt(n){return n=C(n)?n:n.key,Nt[n]||n}var Gt=\"keydown\";var Ft=f+\"-lazy\",Xt=Ft+\"-srcset\",Wt=\"[\"+Ft+\"], [\"+Xt+\"]\";var Yt=[\" \",\"Enter\"];var Ut=Object.freeze({__proto__:null,Media:function(r,n,o){var u=r.state,t=o.breakpoints||{},e=o.reducedMotion||{},i=zn(),c=[];function f(n){n&&i.destroy()}function a(n,t){t=matchMedia(t);i.bind(t,\"change\",s),c.push([n,t])}function s(){var n=u.is(7),t=o.direction,i=c.reduce(function(n,t){return d(n,t[1].matches?t[0]:{})},{});sn(o),l(i),o.destroy?r.destroy(\"completely\"===o.destroy):n?(f(!0),r.mount()):t!==o.direction&&r.refresh()}function l(n,t,i){d(o,n),t&&d(Object.getPrototypeOf(o),n),!i&&u.is(1)||r.emit(K,o)}return{setup:function(){var i=\"min\"===o.mediaQuery;E(t).sort(function(n,t){return i?+n-+t:+t-+n}).forEach(function(n){a(t[n],\"(\"+(i?\"min\":\"max\")+\"-width:\"+n+\"px)\")}),a(e,v),s()},destroy:f,reduce:function(n){matchMedia(v).matches&&(n?d(o,e):sn(o,E(e)))},set:l}},Direction:function(n,t,o){return{resolve:function(n,t,i){var r=\"rtl\"!==(i=i||o.direction)||t?i===Jn?0:-1:1;return l[n]&&l[n][r]||n.replace(/width|left|right/i,function(n,t){n=l[n.toLowerCase()][r]||n;return 0<t?n.charAt(0).toUpperCase()+n.slice(1):n})},orient:function(n){return n*(\"rtl\"===o.direction?1:-1)}}},Elements:function(n,t,i){var r,o,u,e=Q(n),c=e.on,f=e.bind,a=n.root,s=i.i18n,l={},d=[],v=[],h=[];function p(){r=y(\".\"+ct),o=fn(r,\".\"+ft),bn(r&&o,\"A track/list element is missing.\"),k(d,S(o,\".\"+at+\":not(.\"+st+\")\")),w({arrows:dt,pagination:gt,prev:ht,next:pt,bar:yt,toggle:bt},function(n,t){l[t]=y(\".\"+n)}),an(l,{root:a,track:r,list:o,slides:d});var n=a.id||function(n){return\"\"+n+An(_n[n]=(_n[n]||0)+1)}(yn),t=i.role;a.id=n,r.id=r.id||n+\"-track\",o.id=o.id||n+\"-list\",!z(a,Z)&&\"SECTION\"!==a.tagName&&t&&I(a,Z,t),I(a,tt,s.carousel),I(o,Z,\"presentation\"),m()}function g(n){var t=ut.concat(\"style\");D(d),X(a,v),X(r,h),P([r,o],t),P(a,n?t:[\"style\",tt])}function m(){X(a,v),X(r,h),v=b(et),h=b(ct),M(a,v),M(r,h),I(a,nn,i.label),I(a,Zn,i.labelledby)}function y(n){n=pn(a,n);return n&&function(n,t){if(x(n.closest))return n.closest(t);for(var i=n;i&&1===i.nodeType&&!cn(i,t);)i=i.parentElement;return i}(n,\".\"+et)===a?n:void 0}function b(n){return[n+\"--\"+i.type,n+\"--\"+i.direction,i.drag&&n+\"--draggable\",i.isNavigation&&n+\"--nav\",n===et&&tn]}return an(l,{setup:p,mount:function(){c(J,g),c(J,p),c(K,m),f(document,_t+\" keydown\",function(n){u=\"keydown\"===n.type},{capture:!0}),f(a,\"focusin\",function(){A(a,Lt,!!u)})},destroy:g})},Slides:function(r,o,u){var n=Q(r),t=n.on,e=n.emit,c=n.bind,f=(n=o.Elements).slides,a=n.list,s=[];function i(){f.forEach(function(n,t){d(n,t,-1)})}function l(){h(function(n){n.destroy()}),D(s)}function d(n,t,i){t=Rt(r,t,i,n);t.mount(),s.push(t),s.sort(function(n,t){return n.index-t.index})}function v(n){return n?p(function(n){return!n.isClone}):s}function h(n,t){v(t).forEach(n)}function p(t){return s.filter(x(t)?t:function(n){return C(t)?cn(n.slide,t):b(y(t),n.index)})}return{mount:function(){i(),t(J,l),t(J,i)},destroy:l,update:function(){h(function(n){n.update()})},register:d,get:v,getIn:function(n){var t=o.Controller,i=t.toIndex(n),r=t.hasFocus()?1:u.perPage;return p(function(n){return En(n.index,i,i+r-1)})},getAt:function(n){return p(n)[0]},add:function(n,o){g(n,function(n){var t,i,r;m(n=C(n)?hn(n):n)&&((t=f[o])?O(n,t):L(a,n),M(n,u.classes.slide),t=n,i=R(e,jn),t=gn(t,\"img\"),(r=t.length)?t.forEach(function(n){c(n,\"load error\",function(){--r||i()})}):i())}),e(J)},remove:function(n){T(p(n).map(function(n){return n.slide})),e(J)},forEach:h,filter:p,style:function(t,i,r){h(function(n){n.style(t,i,r)})},getLength:function(n){return(n?f:s).length},isEnough:function(){return s.length>u.perPage}}},Layout:function(t,n,i){var r,o,u,e=(a=Q(t)).on,c=a.bind,f=a.emit,a=n.Slides,s=n.Direction.resolve,l=(n=n.Elements).root,d=n.track,v=n.list,h=a.getAt,p=a.style;function g(){r=i.direction===Jn,_(l,\"maxWidth\",W(i.width)),_(d,s(\"paddingLeft\"),y(!1)),_(d,s(\"paddingRight\"),y(!0)),m(!0)}function m(n){var t=N(l);!n&&o.width===t.width&&o.height===t.height||(_(d,\"height\",function(){var n=\"\";r&&(bn(n=b(),\"height or heightRatio is missing.\"),n=\"calc(\"+n+\" - \"+y(!1)+\" - \"+y(!0)+\")\");return n}()),p(s(\"marginRight\"),W(i.gap)),p(\"width\",i.autoWidth?null:W(i.fixedWidth)||(r?\"\":w())),p(\"height\",W(i.fixedHeight)||(r?i.autoHeight?null:w():b()),!0),o=t,f(Nn),u!==(u=O())&&(A(l,Ot,u),f(\"overflow\",u)))}function y(n){var t=i.padding,n=s(n?\"right\":\"left\");return t&&W(t[n]||(un(t)?0:t))||\"0px\"}function b(){return W(i.height||N(v).width*i.heightRatio)}function w(){var n=W(i.gap);return\"calc((100%\"+(n&&\" + \"+n)+\")/\"+(i.perPage||1)+(n&&\" - \"+n)+\")\"}function x(){return N(v)[s(\"width\")]}function k(n,t){n=h(n||0);return n?N(n.slide)[s(\"width\")]+(t?0:L()):0}function S(n,t){var i,n=h(n);return n?(n=N(n.slide)[s(\"right\")],i=N(v)[s(\"left\")],U(n-i)+(t?0:L())):0}function E(n){return S(t.length-1)-S(0)+k(0,n)}function L(){var n=h(0);return n&&parseFloat(_(n.slide,s(\"marginRight\")))||0}function O(){return t.is(It)||E(!0)>x()}return{mount:function(){var n,t,i;g(),c(window,\"resize load\",(n=R(f,jn),i=qn(t||0,n,null,1),function(){i.isPaused()&&i.start()})),e([K,J],g),e(jn,m)},resize:m,listSize:x,slideSize:k,sliderSize:E,totalSize:S,getPadding:function(n){return parseFloat(_(d,s(\"padding\"+(n?\"Right\":\"Left\"))))||0},isOverflow:O}},Clones:function(c,i,f){var t,r=Q(c),n=r.on,a=i.Elements,s=i.Slides,o=i.Direction.resolve,l=[];function u(){if(n(J,d),n([K,jn],v),t=h()){var o=t,u=s.get().slice(),e=u.length;if(e){for(;u.length<o;)k(u,u);k(u.slice(-o),u.slice(0,o)).forEach(function(n,t){var i=t<o,r=function(n,t){n=n.cloneNode(!0);return M(n,f.classes.clone),n.id=c.root.id+\"-clone\"+An(t+1),n}(n.slide,t);i?O(r,u[0].slide):L(a.list,r),k(l,r),s.register(r,t-o+(i?0:e),n.index)})}i.Layout.resize(!0)}}function d(){e(),u()}function e(){T(l),D(l),r.destroy()}function v(){var n=h();t!==n&&(t<n||!n)&&r.emit(J)}function h(){var n,t=f.clones;return c.is(Pt)?en(t)&&(t=(n=f[o(\"fixedWidth\")]&&i.Layout.slideSize(0))&&kn(N(a.track)[o(\"width\")]/n)||f[o(\"autoWidth\")]&&c.length||2*f.perPage):t=0,t}return{mount:u,destroy:e}},Move:function(r,c,o){var e,n=Q(r),t=n.on,f=n.emit,a=r.state.set,u=(n=c.Layout).slideSize,i=n.getPadding,s=n.totalSize,l=n.listSize,d=n.sliderSize,v=(n=c.Direction).resolve,h=n.orient,p=(n=c.Elements).list,g=n.track;function m(){c.Controller.isBusy()||(c.Scroll.cancel(),y(r.index),c.Slides.update())}function y(n){b(S(n,!0))}function b(n,t){r.is(It)||(t=t?n:function(n){{var t,i;r.is(Pt)&&(t=k(n),i=t>c.Controller.getEnd(),(t<0||i)&&(n=w(n,i)))}return n}(n),_(p,\"transform\",\"translate\"+v(\"X\")+\"(\"+t+\"px)\"),n!==t&&f(Un))}function w(n,t){var i=n-L(t),r=d();return n-=h(r*(kn(U(i)/r)||1))*(t?1:-1)}function x(){b(E(),!0),e.cancel()}function k(n){for(var t=c.Slides.get(),i=0,r=1/0,o=0;o<t.length;o++){var u=t[o].index,e=U(S(u,!0)-n);if(!(e<=r))break;r=e,i=u}return i}function S(n,t){var i=h(s(n-1)-(n=n,\"center\"===(i=o.focus)?(l()-u(n,!0))/2:+i*u(n)||0));return t?(n=i,n=o.trimSpace&&r.is(Mt)?q(n,0,h(d(!0)-l())):n):i}function E(){var n=v(\"left\");return N(p)[n]-N(g)[n]+h(i(!1))}function L(n){return S(n?c.Controller.getEnd():0,!!o.trimSpace)}return{mount:function(){e=c.Transition,t([B,Nn,K,J],m)},move:function(n,t,i,r){var o,u;n!==t&&(o=i<n,u=h(w(E(),o)),o?0<=u:u<=p[v(\"scrollWidth\")]-N(g)[v(\"width\")])&&(x(),b(w(E(),i<n),!0)),a(G),f(H,t,i,n),e.start(t,function(){a(3),f(Dn,t,i,n),r&&r()})},jump:y,translate:b,shift:w,cancel:x,toIndex:k,toPosition:S,getPosition:E,getLimit:L,exceededLimit:function(n,t){t=en(t)?E():t;var i=!0!==n&&h(t)<h(L(!1)),n=!1!==n&&h(t)>h(L(!0));return i||n},reposition:m}},Controller:function(o,u,e){var c,f,a,s,n=Q(o),t=n.on,i=n.emit,l=u.Move,d=l.getPosition,r=l.getLimit,v=l.toPosition,h=(n=u.Slides).isEnough,p=n.getLength,g=e.omitEnd,m=o.is(Pt),y=o.is(Mt),b=R(L,!1),w=R(L,!0),x=e.start||0,k=x;function S(){f=p(!0),a=e.perMove,s=e.perPage,c=_();var n=q(x,0,g?c:f-1);n!==x&&(x=n,l.reposition())}function E(){c!==_()&&i(\"ei\")}function L(n,t){var i=a||(P()?1:s),i=O(x+i*(n?-1:1),x,!(a||P()));return-1===i&&y&&!Sn(d(),r(!n),1)?n?0:c:t?i:A(i)}function O(n,t,i){var r;return h()||P()?((r=function(n){if(y&&\"move\"===e.trimSpace&&n!==x)for(var t=d();t===v(n,!0)&&En(n,0,o.length-1,!e.rewind);)n<x?--n:++n;return n}(n))!==n&&(t=n,n=r,i=!1),n<0||c<n?n=a||!En(0,n,t,!0)&&!En(c,t,n,!0)?m?i?n<0?-(f%s||s):f:n:e.rewind?n<0?c:0:-1:z(D(n)):i&&n!==t&&(n=z(D(t)+(n<t?-1:1)))):n=-1,n}function A(n){return m?(n+f)%f||0:n}function _(){for(var n=f-(P()||m&&a?1:s);g&&0<n--;)if(v(f-1,!0)!==v(n,!0)){n++;break}return q(n,0,f-1)}function z(n){return q(P()?n:s*n,0,c)}function D(n){return P()?Y(n,c):xn((c<=n?f-1:n)/s)}function M(n){n!==x&&(k=x,x=n)}function P(){return!en(e.focus)||e.isNavigation}function I(){return o.state.is([G,rn])&&!!e.waitForTransition}return{mount:function(){S(),t([K,J,\"ei\"],S),t(Nn,E)},go:function(n,t,i){var r;I()||-1<(r=A(n=function(n){var t=x;{var i,r;C(n)?(r=n.match(/([+\\-<>])(\\d+)?/)||[],i=r[1],r=r[2],\"+\"===i||\"-\"===i?t=O(x+ +(\"\"+i+(+r||1)),x):\">\"===i?t=r?z(+r):b(!0):\"<\"===i&&(t=w(!0))):t=m?n:q(n,0,c)}return t}(n)))&&(t||r!==x)&&(M(r),l.move(n,r,k,i))},scroll:function(n,t,i,r){u.Scroll.scroll(n,t,i,function(){var n=A(l.toIndex(d()));M(g?Y(n,c):n),r&&r()})},getNext:b,getPrev:w,getAdjacent:L,getEnd:_,setIndex:M,getIndex:function(n){return n?k:x},toIndex:z,toPage:D,toDest:function(n){return n=l.toIndex(n),y?q(n,0,c):n},hasFocus:P,isBusy:I}},Arrows:function(o,n,t){var i,r,u=Q(o),e=u.on,c=u.bind,f=u.emit,a=t.classes,s=t.i18n,l=n.Elements,d=n.Controller,v=l.arrows,h=l.track,p=v,g=l.prev,m=l.next,y={};function b(){var n=t.arrows;!n||g&&m||(p=v||j(\"div\",a.arrows),g=S(!0),m=S(!1),i=!0,L(p,[g,m]),v||O(p,h)),g&&m&&(an(y,{prev:g,next:m}),ln(p,n?\"\":\"none\"),M(p,r=dt+\"--\"+t.direction),n&&(e([B,Dn,J,V,\"ei\"],E),c(m,\"click\",R(k,\">\")),c(g,\"click\",R(k,\"<\")),E(),I([g,m],Kn,h.id),f(\"arrows:mounted\",g,m))),e(K,w)}function w(){x(),b()}function x(){u.destroy(),X(p,r),i?(T(v?[g,m]:p),g=m=null):P([g,m],ut)}function k(n){d.go(n,!0)}function S(n){return hn('<button class=\"'+a.arrow+\" \"+(n?a.prev:a.next)+'\" type=\"button\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 40 40\" width=\"40\" height=\"40\" focusable=\"false\"><path d=\"'+(t.arrowPath||\"m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z\")+'\" />')}function E(){var n,t,i,r;g&&m&&(r=o.index,n=d.getPrev(),t=d.getNext(),i=-1<n&&r<n?s.last:s.prev,r=-1<t&&t<r?s.first:s.next,g.disabled=n<0,m.disabled=t<0,I(g,nn,i),I(m,nn,r),f(\"arrows:updated\",g,m,n,t))}return{arrows:y,mount:b,destroy:x,update:E}},Autoplay:function(n,t,i){var r,o,u=Q(n),e=u.on,c=u.bind,f=u.emit,a=qn(i.interval,n.go.bind(n,\">\"),function(n){var t=l.bar;t&&_(t,\"width\",100*n+\"%\"),f(\"autoplay:playing\",n)}),s=a.isPaused,l=t.Elements,d=(u=t.Elements).root,v=u.toggle,h=i.autoplay,p=\"pause\"===h;function g(){s()&&t.Slides.isEnough()&&(a.start(!i.resetProgress),o=r=p=!1,b(),f(Fn))}function m(n){p=!!(n=void 0===n?!0:n),b(),s()||(a.pause(),f(Xn))}function y(){p||(r||o?m(!1):g())}function b(){v&&(A(v,tn,!p),I(v,nn,i.i18n[p?\"play\":\"pause\"]))}function w(n){n=t.Slides.getAt(n);a.set(n&&+z(n.slide,Ct)||i.interval)}return{mount:function(){h&&(i.pauseOnHover&&c(d,\"mouseenter mouseleave\",function(n){r=\"mouseenter\"===n.type,y()}),i.pauseOnFocus&&c(d,\"focusin focusout\",function(n){o=\"focusin\"===n.type,y()}),v&&c(v,\"click\",function(){p?g():m(!0)}),e([H,Tn,J],a.rewind),e(H,w),v&&I(v,Kn,l.track.id),p||g(),b())},destroy:a.cancel,play:g,pause:m,isPaused:s}},Cover:function(n,t,i){var r=Q(n).on;function o(i){t.Slides.forEach(function(n){var t=fn(n.container||n.slide,\"img\");t&&t.src&&u(i,t,n)})}function u(n,t,i){i.style(\"background\",n?'center/cover no-repeat url(\"'+t.src+'\")':\"\",!0),ln(t,n?\"none\":\"\")}return{mount:function(){i.cover&&(r(Wn,R(u,!0)),r([B,K,J],R(o,!0)))},destroy:R(o,!1)}},Scroll:function(n,c,u){var f,a,t=Q(n),i=t.on,s=t.emit,l=n.state.set,d=c.Move,v=d.getPosition,e=d.getLimit,h=d.exceededLimit,p=d.translate,g=n.is(Mt),m=1;function y(n,t,i,r,o){var u,e=v(),i=(x(),!i||g&&h()||(i=c.Layout.sliderSize(),u=Ln(n)*i*xn(U(n)/i)||0,n=d.toPosition(c.Controller.toDest(n%i))+u),Sn(e,n,1));m=1,t=i?0:t||wn(U(n-e)/1.5,800),a=r,f=qn(t,b,R(w,e,n,o),1),l(rn),s(Tn),f.start()}function b(){l(3),a&&a(),s(V)}function w(n,t,i,r){var o=v(),r=(n+(t-n)*(t=r,(n=u.easingFunc)?n(t):1-Math.pow(1-t,4))-o)*m;p(o+r),g&&!i&&h()&&(m*=.6,U(r)<10&&y(e(h(!0)),600,!1,a,!0))}function x(){f&&f.cancel()}function r(){f&&!f.isPaused()&&(x(),b())}return{mount:function(){i(H,x),i([K,J],r)},destroy:x,scroll:y,cancel:r}},Drag:function(e,o,c){var f,t,u,a,s,l,d,v,n=Q(e),i=n.on,h=n.emit,p=n.bind,g=n.unbind,m=e.state,y=o.Move,b=o.Scroll,w=o.Controller,x=o.Elements.track,k=o.Media.reduce,r=(n=o.Direction).resolve,S=n.orient,E=y.getPosition,L=y.exceededLimit,O=!1;function j(){var n=c.drag;C(!n),a=\"free\"===n}function N(n){var t,i,r;l=!1,d||(t=R(n),i=n.target,r=c.noDrag,cn(i,\".\"+mt+\", .\"+vt)||r&&cn(i,r)||!t&&n.button||(w.isBusy()?F(n,!0):(v=t?x:window,s=m.is([G,rn]),u=null,p(v,zt,A,jt),p(v,Dt,_,jt),y.cancel(),b.cancel(),z(n))))}function A(n){var t,i,r,o,u;m.is(6)||(m.set(6),h(\"drag\")),n.cancelable&&(s?(y.translate(f+D(n)/(O&&e.is(Mt)?5:1)),u=200<M(n),t=O!==(O=L()),(u||t)&&z(n),l=!0,h(\"dragging\"),F(n)):U(D(u=n))>U(D(u,!0))&&(t=n,i=c.dragMinThreshold,r=un(i),o=r&&i.mouse||0,r=(r?i.touch:+i)||10,s=U(D(t))>(R(t)?r:o),F(n)))}function _(n){var t,i,r;m.is(6)&&(m.set(3),h(\"dragged\")),s&&(i=function(n){return E()+Ln(n)*Y(U(n)*(c.flickPower||600),a?1/0:o.Layout.listSize()*(c.flickMaxPages||1))}(t=function(n){if(e.is(Pt)||!O){var t=M(n);if(t&&t<200)return D(n)/t}return 0}(t=n)),r=c.rewind&&c.rewindByDrag,k(!1),a?w.scroll(i,0,c.snap):e.is(It)?w.go(S(Ln(t))<0?r?\"<\":\"-\":r?\">\":\"+\"):e.is(Mt)&&O&&r?w.go(L(!0)?\">\":\"<\"):w.go(w.toDest(i),!0),k(!0),F(n)),g(v,zt,A),g(v,Dt,_),s=!1}function T(n){!d&&l&&F(n,!0)}function z(n){u=t,t=n,f=E()}function D(n,t){return I(n,t)-I(P(n),t)}function M(n){return mn(n)-mn(P(n))}function P(n){return t===n&&u||t}function I(n,t){return(R(n)?n.changedTouches[0]:n)[\"page\"+r(t?\"Y\":\"X\")]}function R(n){return\"undefined\"!=typeof TouchEvent&&n instanceof TouchEvent}function C(n){d=n}return{mount:function(){p(x,zt,on,jt),p(x,Dt,on,jt),p(x,_t,N,jt),p(x,\"click\",T,{capture:!0}),p(x,\"dragstart\",F),i([B,K],j)},disable:C,isDragging:function(){return s}}},Keyboard:function(t,n,i){var r,o,u=Q(t),e=u.on,c=u.bind,f=u.unbind,a=t.root,s=n.Direction.resolve;function l(){var n=i.keyboard;n&&(r=\"global\"===n?window:a,c(r,Gt,h))}function d(){f(r,Gt)}function v(){var n=o;o=!0,p(function(){o=n})}function h(n){o||((n=Tt(n))===s(Bn)?t.go(\"<\"):n===s(Hn)&&t.go(\">\"))}return{mount:function(){l(),e(K,d),e(K,l),e(H,v)},destroy:d,disable:function(n){o=n}}},LazyLoad:function(i,n,o){var t=Q(i),r=t.on,u=t.off,e=t.bind,c=t.emit,f=\"sequential\"===o.lazyLoad,a=[Dn,V],s=[];function l(){D(s),n.Slides.forEach(function(r){gn(r.slide,Wt).forEach(function(n){var t=z(n,Ft),i=z(n,Xt);t===n.src&&i===n.srcset||(t=o.classes.spinner,t=fn(i=n.parentElement,\".\"+t)||j(\"span\",t,i),s.push([n,r,t]),n.src||ln(n,\"none\"))})}),(f?p:(u(a),r(a,d),d))()}function d(){(s=s.filter(function(n){var t=o.perPage*((o.preloadPages||1)+1)-1;return!n[1].isWithin(i.index,t)||v(n)})).length||u(a)}function v(n){var t=n[0];M(n[1].slide,Et),e(t,\"load error\",R(h,n)),I(t,\"src\",z(t,Ft)),I(t,\"srcset\",z(t,Xt)),P(t,Ft),P(t,Xt)}function h(n,t){var i=n[0],r=n[1];X(r.slide,Et),\"error\"!==t.type&&(T(n[2]),ln(i,\"\"),c(Wn,i,r),c(jn)),f&&p()}function p(){s.length&&v(s.shift())}return{mount:function(){o.lazyLoad&&(l(),r(J,l))},destroy:R(D,s),check:d}},Pagination:function(l,n,d){var v,h,t=Q(l),p=t.on,g=t.emit,m=t.bind,y=n.Slides,b=n.Elements,w=n.Controller,x=w.hasFocus,r=w.getIndex,e=w.go,c=n.Direction.resolve,k=b.pagination,S=[];function E(){v&&(T(k?o(v.children):v),X(v,h),D(S),v=null),t.destroy()}function L(n){e(\">\"+n,!0)}function O(n,t){var i=S.length,r=Tt(t),o=A(),u=-1,o=(r===c(Hn,!1,o)?u=++n%i:r===c(Bn,!1,o)?u=(--n+i)%i:\"Home\"===r?u=0:\"End\"===r&&(u=i-1),S[u]);o&&(dn(o.button),e(\">\"+u),F(t,!0))}function A(){return d.paginationDirection||d.direction}function _(n){return S[w.toPage(n)]}function z(){var n,t=_(r(!0)),i=_(r());t&&(X(n=t.button,tn),P(n,Qn),I(n,$,-1)),i&&(M(n=i.button,tn),I(n,Qn,!0),I(n,$,\"\")),g(\"pagination:updated\",{list:v,items:S},t,i)}return{items:S,mount:function n(){E(),p([K,J,\"ei\"],n);var t=d.pagination;if(k&&ln(k,t?\"\":\"none\"),t){p([H,Tn,V],z);var t=l.length,i=d.classes,r=d.i18n,o=d.perPage,u=x()?w.getEnd()+1:kn(t/o);M(v=k||j(\"ul\",i.pagination,b.track.parentElement),h=gt+\"--\"+A()),I(v,Z,\"tablist\"),I(v,nn,r.select),I(v,nt,A()===Jn?\"vertical\":\"\");for(var e=0;e<u;e++){var c=j(\"li\",null,v),f=j(\"button\",{class:i.page,type:\"button\"},c),a=y.getIn(e).map(function(n){return n.slide.id}),s=!x()&&1<o?r.pageX:r.slideX;m(f,\"click\",R(L,e)),d.paginationKeyboard&&m(f,\"keydown\",R(O,e)),I(c,Z,\"presentation\"),I(f,Z,\"tab\"),I(f,Kn,a.join(\" \")),I(f,nn,On(s,e+1)),I(f,$,-1),S.push({li:c,button:f,page:e})}z(),g(\"pagination:mounted\",{list:v,items:S},_(l.index))}},destroy:E,getAt:_,update:z}},Sync:function(i,n,t){var r=t.isNavigation,o=t.slideFocus,u=[];function e(){var n,t;i.splides.forEach(function(n){n.isParent||(f(i,n.splide),f(n.splide,i))}),r&&(n=Q(i),(t=n.on)(Mn,s),t(Yn,l),t([B,K],a),u.push(n),n.emit(Gn,i.splides))}function c(){u.forEach(function(n){n.destroy()}),D(u)}function f(n,r){n=Q(n);n.on(H,function(n,t,i){r.go(r.is(Pt)?i:n)}),u.push(n)}function a(){I(n.Elements.list,nt,t.direction===Jn?\"vertical\":\"\")}function s(n){i.go(n.index)}function l(n,t){b(Yt,Tt(t))&&(s(n),F(t))}return{setup:R(n.Media.set,{slideFocus:en(o)?r:o},!0),mount:e,destroy:c,remount:function(){c(),e()}}},Wheel:function(e,c,f){var n=Q(e).bind,a=0;function t(n){var t,i,r,o,u;n.cancelable&&(t=(u=n.deltaY)<0,i=mn(n),r=f.wheelMinThreshold||0,o=f.wheelSleep||0,U(u)>r&&o<i-a&&(e.go(t?\"<\":\">\"),a=i),u=t,f.releaseWheel&&!e.state.is(G)&&-1===c.Controller.getAdjacent(u)||F(n))}return{mount:function(){f.wheel&&n(c.Elements.track,\"wheel\",t,jt)}}},Live:function(n,t,i){var r=Q(n).on,o=t.Elements.track,u=i.live&&!i.isNavigation,e=j(\"span\",wt),c=qn(90,R(f,!1));function f(n){I(o,rt,n),n?(L(o,e),c.start()):(T(e),c.cancel())}function a(n){u&&I(o,it,n?\"off\":\"polite\")}return{mount:function(){u&&(a(!t.Autoplay.isPaused()),I(o,ot,!0),e.textContent=\"\u2026\",r(Fn,R(a,!0)),r(Xn,R(a,!1)),r([Dn,V],R(f,!0)))},disable:a,destroy:function(){P(o,[it,ot,rt]),T(e)}}}}),qt={type:\"slide\",role:\"region\",speed:400,perPage:1,cloneStatus:!0,arrows:!0,pagination:!0,paginationKeyboard:!0,interval:5e3,pauseOnHover:!0,pauseOnFocus:!0,resetProgress:!0,easing:\"cubic-bezier(0.25, 1, 0.5, 1)\",drag:!0,direction:\"ltr\",trimSpace:!0,focusableNodes:\"a, button, textarea, input, select, iframe\",live:!0,classes:{slide:at,clone:st,arrows:dt,arrow:vt,prev:ht,next:pt,pagination:gt,page:mt,spinner:i+\"spinner\"},i18n:{prev:\"Previous slide\",next:\"Next slide\",first:\"Go to first slide\",last:\"Go to last slide\",slideX:\"Go to slide %s\",pageX:\"Go to page %s\",play:\"Start autoplay\",pause:\"Pause autoplay\",carousel:\"carousel\",slide:\"slide\",select:\"Select a slide to show\",slideLabel:\"%s of %s\"},reducedMotion:{speed:0,rewindSpeed:0,autoplay:\"pause\"}};function Bt(n,t,i){var r=t.Slides;function o(){r.forEach(function(n){n.style(\"transform\",\"translateX(-\"+100*n.index+\"%)\")})}return{mount:function(){Q(n).on([B,J],o)},start:function(n,t){r.style(\"transition\",\"opacity \"+i.speed+\"ms \"+i.easing),p(t)},cancel:on}}function Ht(u,n,e){var c,f=n.Move,a=n.Controller,s=n.Scroll,t=n.Elements.list,l=R(_,t,\"transition\");function i(){l(\"\"),s.cancel()}return{mount:function(){Q(u).bind(t,\"transitionend\",function(n){n.target===t&&c&&(i(),c())})},start:function(n,t){var i=f.toPosition(n,!0),r=f.getPosition(),o=function(n){var t=e.rewindSpeed;if(u.is(Mt)&&t){var i=a.getIndex(!0),r=a.getEnd();if(0===i&&r<=n||r<=i&&0===n)return t}return e.speed}(n);1<=U(i-r)&&1<=o?e.useScroll?s.scroll(i,o,!1,t):(l(\"transform \"+o+\"ms \"+e.easing),f.translate(i,!0),c=t):(f.jump(n),t())},cancel:i}}t=function(){function i(n,t){this.event=Q(),this.Components={},this.state=s(1),this.splides=[],this.n={},this.t={};n=C(n)?pn(document,n):n;bn(n,n+\" is invalid.\"),t=d({label:z(this.root=n,nn)||\"\",labelledby:z(n,Zn)||\"\"},qt,i.defaults,t||{});try{d(t,JSON.parse(z(n,f)))}catch(n){bn(!1,\"Invalid JSON\")}this.n=Object.create(d({},t))}var n=i.prototype;return n.mount=function(n,t){var i=this,r=this.state,o=this.Components;return bn(r.is([1,7]),\"Already mounted!\"),r.set(1),this.i=o,this.r=t||this.r||(this.is(It)?Bt:Ht),this.t=n||this.t,w(an({},Ut,this.t,{Transition:this.r}),function(n,t){n=n(i,o,i.n);(o[t]=n).setup&&n.setup()}),w(o,function(n){n.mount&&n.mount()}),this.emit(B),M(this.root,\"is-initialized\"),r.set(3),this.emit(\"ready\"),this},n.sync=function(n){return this.splides.push({splide:n}),n.splides.push({splide:this,isParent:!0}),this.state.is(3)&&(this.i.Sync.remount(),n.Components.Sync.remount()),this},n.go=function(n){return this.i.Controller.go(n),this},n.on=function(n,t){return this.event.on(n,t),this},n.off=function(n){return this.event.off(n),this},n.emit=function(n){var t;return(t=this.event).emit.apply(t,[n].concat(o(arguments,1))),this},n.add=function(n,t){return this.i.Slides.add(n,t),this},n.remove=function(n){return this.i.Slides.remove(n),this},n.is=function(n){return this.n.type===n},n.refresh=function(){return this.emit(J),this},n.destroy=function(t){void 0===t&&(t=!0);var n=this.event,i=this.state;return i.is(1)?Q(this).on(\"ready\",this.destroy.bind(this,t)):(w(this.i,function(n){n.destroy&&n.destroy(t)},!0),n.emit(a),n.destroy(),t&&D(this.splides),i.set(7)),this},Jt(i,[{key:\"options\",get:function(){return this.n},set:function(n){this.i.Media.set(n,!0,!0)}},{key:\"length\",get:function(){return this.i.Slides.getLength(!0)}},{key:\"index\",get:function(){return this.i.Controller.getIndex()}}]),i}();return t.defaults={},t.STATES=r,t},\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(n=\"undefined\"!=typeof globalThis?globalThis:n||self).Splide=t();\n//# sourceMappingURL=splide.min.js.map\n","Mageplaza_Blog/js/categorytree.js":"/**\r\n * Mageplaza\r\n *\r\n * NOTICE OF LICENSE\r\n *\r\n * This source file is subject to the Mageplaza.com license that is\r\n * available through the world-wide-web at this URL:\r\n * https://www.mageplaza.com/LICENSE.txt\r\n *\r\n * DISCLAIMER\r\n *\r\n * Do not edit or add to this file if you wish to upgrade this extension to newer\r\n * version in the future.\r\n *\r\n * @category    Mageplaza\r\n * @package     Mageplaza_Blog\r\n * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)\r\n * @license     https://www.mageplaza.com/LICENSE.txt\r\n */\r\n\r\ndefine([\r\n        'jquery'\r\n    ], function ($) {\r\n    \"use strict\";\r\n\r\n        var parentCategory = $(\".mp-blog-expand-tree-2\");\r\n        var childCategory  = $(\".mp-blog-expand-tree-3\");\r\n\r\n        parentCategory.click(function () {\r\n            if ($(this).hasClass(\"mp-blog-expand-tree-2\")) {\r\n                $(this).parent().find(\".category-level3\").slideDown(\"fast\");\r\n                $(this).removeClass(\"mp-blog-expand-tree-2 fa fa-plus-square-o\")\r\n                .addClass(\"mp-blog-narrow-tree-2 fa fa-minus-square-o\");\r\n            } else {\r\n                $(this).parent().find(\".category-level4\").slideUp(\"fast\");\r\n                $(this).parent().find(\".category-level3\").slideUp(\"fast\");\r\n                $(this).removeClass(\"mp-blog-narrow-tree-2 fa fa-minus-square-o\")\r\n                .addClass(\"mp-blog-expand-tree-2 fa fa-plus-square-o\");\r\n                $(this).parent().find(\".mp-blog-narrow-tree-3\")\r\n                .removeClass(\"mp-blog-narrow-tree-3 fa fa-minus-square-o\")\r\n                .addClass(\"mp-blog-expand-tree-3 fa fa-plus-square-o\");\r\n            }\r\n\r\n        });\r\n\r\n        childCategory.click(function () {\r\n            if ($(this).hasClass(\"mp-blog-expand-tree-3\")) {\r\n                $(this).parent().find(\".category-level4\").slideDown(\"fast\");\r\n                $(this).removeClass(\"mp-blog-expand-tree-3 fa fa-plus-square-o\")\r\n                .addClass(\"mp-blog-narrow-tree-3 fa fa-minus-square-o\");\r\n            } else {\r\n                $(this).parent().find(\".category-level4\").slideUp(\"fast\");\r\n                $(this).removeClass(\"mp-blog-narrow-tree-3 fa fa-minus-square-o\")\r\n                .addClass(\"mp-blog-expand-tree-3 fa fa-plus-square-o\");\r\n            }\r\n        });\r\n    }\r\n);","fotorama/fotorama.js":"/*!\n * Fotorama 4.6.4 | http://fotorama.io/license/\n */\nfotoramaVersion = '4.6.4';\n(function (window, document, location, $, undefined) {\n    \"use strict\";\n    var _fotoramaClass = 'fotorama',\n        _fullscreenClass = 'fotorama__fullscreen',\n\n        wrapClass = _fotoramaClass + '__wrap',\n        wrapCss2Class = wrapClass + '--css2',\n        wrapCss3Class = wrapClass + '--css3',\n        wrapVideoClass = wrapClass + '--video',\n        wrapFadeClass = wrapClass + '--fade',\n        wrapSlideClass = wrapClass + '--slide',\n        wrapNoControlsClass = wrapClass + '--no-controls',\n        wrapNoShadowsClass = wrapClass + '--no-shadows',\n        wrapPanYClass = wrapClass + '--pan-y',\n        wrapRtlClass = wrapClass + '--rtl',\n        wrapOnlyActiveClass = wrapClass + '--only-active',\n        wrapNoCaptionsClass = wrapClass + '--no-captions',\n        wrapToggleArrowsClass = wrapClass + '--toggle-arrows',\n\n        stageClass = _fotoramaClass + '__stage',\n        stageFrameClass = stageClass + '__frame',\n        stageFrameVideoClass = stageFrameClass + '--video',\n        stageShaftClass = stageClass + '__shaft',\n\n        grabClass = _fotoramaClass + '__grab',\n        pointerClass = _fotoramaClass + '__pointer',\n\n        arrClass = _fotoramaClass + '__arr',\n        arrDisabledClass = arrClass + '--disabled',\n        arrPrevClass = arrClass + '--prev',\n        arrNextClass = arrClass + '--next',\n\n        navClass = _fotoramaClass + '__nav',\n        navWrapClass = navClass + '-wrap',\n        navShaftClass = navClass + '__shaft',\n        navShaftVerticalClass = navWrapClass + '--vertical',\n        navShaftListClass = navWrapClass + '--list',\n        navShafthorizontalClass = navWrapClass + '--horizontal',\n        navDotsClass = navClass + '--dots',\n        navThumbsClass = navClass + '--thumbs',\n        navFrameClass = navClass + '__frame',\n\n        fadeClass = _fotoramaClass + '__fade',\n        fadeFrontClass = fadeClass + '-front',\n        fadeRearClass = fadeClass + '-rear',\n\n        shadowClass = _fotoramaClass + '__shadow',\n        shadowsClass = shadowClass + 's',\n        shadowsLeftClass = shadowsClass + '--left',\n        shadowsRightClass = shadowsClass + '--right',\n        shadowsTopClass = shadowsClass + '--top',\n        shadowsBottomClass = shadowsClass + '--bottom',\n\n        activeClass = _fotoramaClass + '__active',\n        selectClass = _fotoramaClass + '__select',\n\n        hiddenClass = _fotoramaClass + '--hidden',\n\n        fullscreenClass = _fotoramaClass + '--fullscreen',\n        fullscreenIconClass = _fotoramaClass + '__fullscreen-icon',\n\n        errorClass = _fotoramaClass + '__error',\n        loadingClass = _fotoramaClass + '__loading',\n        loadedClass = _fotoramaClass + '__loaded',\n        loadedFullClass = loadedClass + '--full',\n        loadedImgClass = loadedClass + '--img',\n\n        grabbingClass = _fotoramaClass + '__grabbing',\n\n        imgClass = _fotoramaClass + '__img',\n        imgFullClass = imgClass + '--full',\n\n        thumbClass = _fotoramaClass + '__thumb',\n        thumbArrLeft = thumbClass + '__arr--left',\n        thumbArrRight = thumbClass + '__arr--right',\n        thumbBorderClass = thumbClass + '-border',\n\n        htmlClass = _fotoramaClass + '__html',\n\n        videoContainerClass = _fotoramaClass + '-video-container',\n        videoClass = _fotoramaClass + '__video',\n        videoPlayClass = videoClass + '-play',\n        videoCloseClass = videoClass + '-close',\n\n\n        horizontalImageClass = _fotoramaClass + '_horizontal_ratio',\n        verticalImageClass = _fotoramaClass + '_vertical_ratio',\n        fotoramaSpinnerClass = _fotoramaClass + '__spinner',\n        spinnerShowClass = fotoramaSpinnerClass + '--show';\n    var JQUERY_VERSION = $ && $.fn.jquery.split('.');\n\n    if (!JQUERY_VERSION\n        || JQUERY_VERSION[0] < 1\n        || (JQUERY_VERSION[0] == 1 && JQUERY_VERSION[1] < 8)) {\n        throw 'Fotorama requires jQuery 1.8 or later and will not run without it.';\n    }\n\n    var _ = {};\n    /* Modernizr 2.8.3 (Custom Build) | MIT & BSD\n     * Build: http://modernizr.com/download/#-csstransforms3d-csstransitions-touch-prefixed\n     */\n\n    var Modernizr = (function (window, document, undefined) {\n        var version = '2.8.3',\n            Modernizr = {},\n\n\n            docElement = document.documentElement,\n\n            mod = 'modernizr',\n            modElem = document.createElement(mod),\n            mStyle = modElem.style,\n            inputElem,\n\n\n            toString = {}.toString,\n\n            prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),\n\n\n            omPrefixes = 'Webkit Moz O ms',\n\n            cssomPrefixes = omPrefixes.split(' '),\n\n            domPrefixes = omPrefixes.toLowerCase().split(' '),\n\n\n            tests = {},\n            inputs = {},\n            attrs = {},\n\n            classes = [],\n\n            slice = classes.slice,\n\n            featureName,\n\n\n            injectElementWithStyles = function (rule, callback, nodes, testnames) {\n\n                var style, ret, node, docOverflow,\n                    div = document.createElement('div'),\n                    body = document.body,\n                    fakeBody = body || document.createElement('body');\n\n                if (parseInt(nodes, 10)) {\n                    while (nodes--) {\n                        node = document.createElement('div');\n                        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);\n                        div.appendChild(node);\n                    }\n                }\n\n                style = ['&#173;', '<style id=\"s', mod, '\">', rule, '</style>'].join('');\n                div.id = mod;\n                (body ? div : fakeBody).innerHTML += style;\n                fakeBody.appendChild(div);\n                if (!body) {\n                    fakeBody.style.background = '';\n                    fakeBody.style.overflow = 'hidden';\n                    docOverflow = docElement.style.overflow;\n                    docElement.style.overflow = 'hidden';\n                    docElement.appendChild(fakeBody);\n                }\n\n                ret = callback(div, rule);\n                if (!body) {\n                    fakeBody.parentNode.removeChild(fakeBody);\n                    docElement.style.overflow = docOverflow;\n                } else {\n                    div.parentNode.removeChild(div);\n                }\n\n                return !!ret;\n\n            },\n            _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;\n\n        if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {\n            hasOwnProp = function (object, property) {\n                return _hasOwnProperty.call(object, property);\n            };\n        }\n        else {\n            hasOwnProp = function (object, property) {\n                return ((property in object) && is(object.constructor.prototype[property], 'undefined'));\n            };\n        }\n\n\n        if (!Function.prototype.bind) {\n            Function.prototype.bind = function bind(that) {\n\n                var target = this;\n\n                if (typeof target != \"function\") {\n                    throw new TypeError();\n                }\n\n                var args = slice.call(arguments, 1),\n                    bound = function () {\n\n                        if (this instanceof bound) {\n\n                            var F = function () {\n                            };\n                            F.prototype = target.prototype;\n                            var self = new F();\n\n                            var result = target.apply(\n                                self,\n                                args.concat(slice.call(arguments))\n                            );\n                            if (Object(result) === result) {\n                                return result;\n                            }\n                            return self;\n\n                        } else {\n\n                            return target.apply(\n                                that,\n                                args.concat(slice.call(arguments))\n                            );\n\n                        }\n\n                    };\n\n                return bound;\n            };\n        }\n\n        function setCss(str) {\n            mStyle.cssText = str;\n        }\n\n        function setCssAll(str1, str2) {\n            return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));\n        }\n\n        function is(obj, type) {\n            return typeof obj === type;\n        }\n\n        function contains(str, substr) {\n            return !!~('' + str).indexOf(substr);\n        }\n\n        function testProps(props, prefixed) {\n            for (var i in props) {\n                var prop = props[i];\n                if (!contains(prop, \"-\") && mStyle[prop] !== undefined) {\n                    return prefixed == 'pfx' ? prop : true;\n                }\n            }\n            return false;\n        }\n\n        function testDOMProps(props, obj, elem) {\n            for (var i in props) {\n                var item = obj[props[i]];\n                if (item !== undefined) {\n\n                    if (elem === false) return props[i];\n\n                    if (is(item, 'function')) {\n                        return item.bind(elem || obj);\n                    }\n\n                    return item;\n                }\n            }\n            return false;\n        }\n\n        function testPropsAll(prop, prefixed, elem) {\n\n            var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),\n                props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');\n\n            if (is(prefixed, \"string\") || is(prefixed, \"undefined\")) {\n                return testProps(props, prefixed);\n\n            } else {\n                props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');\n                return testDOMProps(props, prefixed, elem);\n            }\n        }\n\n        tests['touch'] = function () {\n            var bool;\n\n            if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {\n                bool = true;\n            } else {\n                injectElementWithStyles(['@media (', prefixes.join('touch-enabled),('), mod, ')', '{#modernizr{top:9px;position:absolute}}'].join(''), function (node) {\n                    bool = node.offsetTop === 9;\n                });\n            }\n\n            return bool;\n        };\n        tests['csstransforms3d'] = function () {\n\n            var ret = !!testPropsAll('perspective');\n\n            if (ret && 'webkitPerspective' in docElement.style) {\n\n                injectElementWithStyles('@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}', function (node, rule) {\n                    ret = node.offsetLeft === 9 && node.offsetHeight === 3;\n                });\n            }\n            return ret;\n        };\n\n\n        tests['csstransitions'] = function () {\n            return testPropsAll('transition');\n        };\n\n\n        for (var feature in tests) {\n            if (hasOwnProp(tests, feature)) {\n                featureName = feature.toLowerCase();\n                Modernizr[featureName] = tests[feature]();\n\n                classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);\n            }\n        }\n\n\n        Modernizr.addTest = function (feature, test) {\n            if (typeof feature == 'object') {\n                for (var key in feature) {\n                    if (hasOwnProp(feature, key)) {\n                        Modernizr.addTest(key, feature[key]);\n                    }\n                }\n            } else {\n\n                feature = feature.toLowerCase();\n\n                if (Modernizr[feature] !== undefined) {\n                    return Modernizr;\n                }\n\n                test = typeof test == 'function' ? test() : test;\n\n                if (typeof enableClasses !== \"undefined\" && enableClasses) {\n                    docElement.className += ' ' + (test ? '' : 'no-') + feature;\n                }\n                Modernizr[feature] = test;\n\n            }\n\n            return Modernizr;\n        };\n\n\n        setCss('');\n        modElem = inputElem = null;\n\n\n        Modernizr._version = version;\n\n        Modernizr._prefixes = prefixes;\n        Modernizr._domPrefixes = domPrefixes;\n        Modernizr._cssomPrefixes = cssomPrefixes;\n\n\n        Modernizr.testProp = function (prop) {\n            return testProps([prop]);\n        };\n\n        Modernizr.testAllProps = testPropsAll;\n        Modernizr.testStyles = injectElementWithStyles;\n        Modernizr.prefixed = function (prop, obj, elem) {\n            if (!obj) {\n                return testPropsAll(prop, 'pfx');\n            } else {\n                return testPropsAll(prop, obj, elem);\n            }\n        };\n        return Modernizr;\n    })(window, document);\n\n    var fullScreenApi = {\n            ok: false,\n            is: function () {\n                return false;\n            },\n            request: function () {\n            },\n            cancel: function () {\n            },\n            event: '',\n            prefix: ''\n        },\n        browserPrefixes = 'webkit moz o ms khtml'.split(' ');\n\n// check for native support\n    if (typeof document.cancelFullScreen != 'undefined') {\n        fullScreenApi.ok = true;\n    } else {\n        // check for fullscreen support by vendor prefix\n        for (var i = 0, il = browserPrefixes.length; i < il; i++) {\n            fullScreenApi.prefix = browserPrefixes[i];\n            if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') {\n                fullScreenApi.ok = true;\n                break;\n            }\n        }\n    }\n\n// update methods to do something useful\n    if (fullScreenApi.ok) {\n        fullScreenApi.event = fullScreenApi.prefix + 'fullscreenchange';\n        fullScreenApi.is = function () {\n            switch (this.prefix) {\n                case '':\n                    return document.fullScreen;\n                case 'webkit':\n                    return document.webkitIsFullScreen;\n                default:\n                    return document[this.prefix + 'FullScreen'];\n            }\n        };\n        fullScreenApi.request = function (el) {\n            return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();\n        };\n        fullScreenApi.cancel = function (el) {\n            if (!this.is()) {\n                return false;\n            }\n            return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();\n        };\n    }\n    /* Bez v1.0.10-g5ae0136\n     * http://github.com/rdallasgray/bez\n     *\n     * A plugin to convert CSS3 cubic-bezier co-ordinates to jQuery-compatible easing functions\n     *\n     * With thanks to Nikolay Nemshilov for clarification on the cubic-bezier maths\n     * See http://st-on-it.blogspot.com/2011/05/calculating-cubic-bezier-function.html\n     *\n     * Copyright 2011 Robert Dallas Gray. All rights reserved.\n     * Provided under the FreeBSD license: https://github.com/rdallasgray/bez/blob/master/LICENSE.txt\n     */\n    function bez(coOrdArray) {\n        var encodedFuncName = \"bez_\" + $.makeArray(arguments).join(\"_\").replace(\".\", \"p\");\n        if (typeof $['easing'][encodedFuncName] !== \"function\") {\n            var polyBez = function (p1, p2) {\n                var A = [null, null],\n                    B = [null, null],\n                    C = [null, null],\n                    bezCoOrd = function (t, ax) {\n                        C[ax] = 3 * p1[ax];\n                        B[ax] = 3 * (p2[ax] - p1[ax]) - C[ax];\n                        A[ax] = 1 - C[ax] - B[ax];\n                        return t * (C[ax] + t * (B[ax] + t * A[ax]));\n                    },\n                    xDeriv = function (t) {\n                        return C[0] + t * (2 * B[0] + 3 * A[0] * t);\n                    },\n                    xForT = function (t) {\n                        var x = t, i = 0, z;\n                        while (++i < 14) {\n                            z = bezCoOrd(x, 0) - t;\n                            if (Math.abs(z) < 1e-3) break;\n                            x -= z / xDeriv(x);\n                        }\n                        return x;\n                    };\n                return function (t) {\n                    return bezCoOrd(xForT(t), 1);\n                }\n            };\n            $['easing'][encodedFuncName] = function (x, t, b, c, d) {\n                return c * polyBez([coOrdArray[0], coOrdArray[1]], [coOrdArray[2], coOrdArray[3]])(t / d) + b;\n            }\n        }\n        return encodedFuncName;\n    }\n\n    var $WINDOW = $(window),\n        $DOCUMENT = $(document),\n        $HTML,\n        $BODY,\n\n        QUIRKS_FORCE = location.hash.replace('#', '') === 'quirks',\n        TRANSFORMS3D = Modernizr.csstransforms3d,\n        CSS3 = TRANSFORMS3D && !QUIRKS_FORCE,\n        COMPAT = TRANSFORMS3D || document.compatMode === 'CSS1Compat',\n        FULLSCREEN = fullScreenApi.ok,\n\n        MOBILE = navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),\n        SLOW = !CSS3 || MOBILE,\n\n        MS_POINTER = navigator.msPointerEnabled,\n\n        WHEEL = \"onwheel\" in document.createElement(\"div\") ? \"wheel\" : document.onmousewheel !== undefined ? \"mousewheel\" : \"DOMMouseScroll\",\n\n        TOUCH_TIMEOUT = 250,\n        TRANSITION_DURATION = 300,\n\n        SCROLL_LOCK_TIMEOUT = 1400,\n\n        AUTOPLAY_INTERVAL = 5000,\n        MARGIN = 2,\n        THUMB_SIZE = 64,\n\n        WIDTH = 500,\n        HEIGHT = 333,\n\n        STAGE_FRAME_KEY = '$stageFrame',\n        NAV_DOT_FRAME_KEY = '$navDotFrame',\n        NAV_THUMB_FRAME_KEY = '$navThumbFrame',\n\n        AUTO = 'auto',\n\n        BEZIER = bez([.1, 0, .25, 1]),\n\n        MAX_WIDTH = 1200,\n\n        /**\n         * Number of thumbnails in slide. Calculated only on setOptions and resize.\n         * @type {number}\n         */\n        thumbsPerSlide = 1,\n\n        OPTIONS = {\n\n            /**\n             * Set width for gallery.\n             * Default value - width of first image\n             * Number - set value in px\n             * String - set value in quotes\n             *\n             */\n            width: null,\n\n            /**\n             * Set min-width for gallery\n             *\n             */\n            minwidth: null,\n\n            /**\n             * Set max-width for gallery\n             *\n             */\n            maxwidth: '100%',\n\n            /**\n             * Set height for gallery\n             * Default value - height of first image\n             * Number - set value in px\n             * String - set value in quotes\n             *\n             */\n            height: null,\n\n            /**\n             * Set min-height for gallery\n             *\n             */\n            minheight: null,\n\n            /**\n             * Set max-height for gallery\n             *\n             */\n            maxheight: null,\n\n            /**\n             * Set proportion ratio for gallery depends of image\n             *\n             */\n            ratio: null, // '16/9' || 500/333 || 1.5\n\n            margin: MARGIN,\n\n            nav: 'dots', // 'thumbs' || false\n            navposition: 'bottom', // 'top'\n            navwidth: null,\n            thumbwidth: THUMB_SIZE,\n            thumbheight: THUMB_SIZE,\n            thumbmargin: MARGIN,\n            thumbborderwidth: MARGIN,\n\n            allowfullscreen: false, // true || 'native'\n\n            transition: 'slide', // 'crossfade' || 'dissolve'\n            clicktransition: null,\n            transitionduration: TRANSITION_DURATION,\n\n            captions: true,\n\n            startindex: 0,\n\n            loop: false,\n\n            autoplay: false,\n            stopautoplayontouch: true,\n\n            keyboard: false,\n\n            arrows: true,\n            click: true,\n            swipe: false,\n            trackpad: false,\n\n            shuffle: false,\n\n            direction: 'ltr', // 'rtl'\n\n            shadows: true,\n\n            showcaption: true,\n\n            /**\n             * Set type of thumbnail navigation\n             */\n            navdir: 'horizontal',\n\n            /**\n             * Set configuration to show or hide arrows in thumb navigation\n             */\n            navarrows: true,\n\n            /**\n             * Set type of navigation. Can be thumbs or slides\n             */\n            navtype: 'thumbs'\n\n        },\n\n        KEYBOARD_OPTIONS = {\n            left: true,\n            right: true,\n            down: true,\n            up: true,\n            space: false,\n            home: false,\n            end: false\n        };\n\n    function noop() {\n    }\n\n    function minMaxLimit(value, min, max) {\n        return Math.max(isNaN(min) ? -Infinity : min, Math.min(isNaN(max) ? Infinity : max, value));\n    }\n\n    function readTransform(css, dir) {\n        return css.match(/ma/) && css.match(/-?\\d+(?!d)/g)[css.match(/3d/) ?\n                (dir === 'vertical' ? 13 : 12) : (dir === 'vertical' ? 5 : 4)\n                ]\n    }\n\n    function readPosition($el, dir) {\n        if (CSS3) {\n            return +readTransform($el.css('transform'), dir);\n        } else {\n            return +$el.css(dir === 'vertical' ? 'top' : 'left').replace('px', '');\n        }\n    }\n\n    function getTranslate(pos, direction) {\n        var obj = {};\n\n        if (CSS3) {\n\n            switch (direction) {\n                case 'vertical':\n                    obj.transform = 'translate3d(0, ' + (pos) + 'px,0)';\n                    break;\n                case 'list':\n                    break;\n                default :\n                    obj.transform = 'translate3d(' + (pos) + 'px,0,0)';\n                    break;\n            }\n        } else {\n            direction === 'vertical' ?\n                obj.top = pos :\n                obj.left = pos;\n        }\n        return obj;\n    }\n\n    function getDuration(time) {\n        return {'transition-duration': time + 'ms'};\n    }\n\n    function unlessNaN(value, alternative) {\n        return isNaN(value) ? alternative : value;\n    }\n\n    function numberFromMeasure(value, measure) {\n        return unlessNaN(+String(value).replace(measure || 'px', ''));\n    }\n\n    function numberFromPercent(value) {\n        return /%$/.test(value) ? numberFromMeasure(value, '%') : undefined;\n    }\n\n    function numberFromWhatever(value, whole) {\n        return unlessNaN(numberFromPercent(value) / 100 * whole, numberFromMeasure(value));\n    }\n\n    function measureIsValid(value) {\n        return (!isNaN(numberFromMeasure(value)) || !isNaN(numberFromMeasure(value, '%'))) && value;\n    }\n\n    function getPosByIndex(index, side, margin, baseIndex) {\n\n        return (index - (baseIndex || 0)) * (side + (margin || 0));\n    }\n\n    function getIndexByPos(pos, side, margin, baseIndex) {\n        return -Math.round(pos / (side + (margin || 0)) - (baseIndex || 0));\n    }\n\n    function bindTransitionEnd($el) {\n        var elData = $el.data();\n\n        if (elData.tEnd) return;\n\n        var el = $el[0],\n            transitionEndEvent = {\n                WebkitTransition: 'webkitTransitionEnd',\n                MozTransition: 'transitionend',\n                OTransition: 'oTransitionEnd otransitionend',\n                msTransition: 'MSTransitionEnd',\n                transition: 'transitionend'\n            };\n        addEvent(el, transitionEndEvent[Modernizr.prefixed('transition')], function (e) {\n            elData.tProp && e.propertyName.match(elData.tProp) && elData.onEndFn();\n        });\n        elData.tEnd = true;\n    }\n\n    function afterTransition($el, property, fn, time) {\n        var ok,\n            elData = $el.data();\n\n        if (elData) {\n            elData.onEndFn = function () {\n                if (ok) return;\n                ok = true;\n                clearTimeout(elData.tT);\n                fn();\n            };\n            elData.tProp = property;\n\n            // Passive call, just in case of fail of native transition-end event\n            clearTimeout(elData.tT);\n            elData.tT = setTimeout(function () {\n                elData.onEndFn();\n            }, time * 1.5);\n\n            bindTransitionEnd($el);\n        }\n    }\n\n\n    function stop($el, pos/*, _001*/) {\n        var dir = $el.navdir || 'horizontal';\n        if ($el.length) {\n            var elData = $el.data();\n            if (CSS3) {\n                $el.css(getDuration(0));\n                elData.onEndFn = noop;\n                clearTimeout(elData.tT);\n            } else {\n                $el.stop();\n            }\n            var lockedPos = getNumber(pos, function () {\n                return readPosition($el, dir);\n            });\n\n            $el.css(getTranslate(lockedPos, dir/*, _001*/));//.width(); // `.width()` for reflow\n            return lockedPos;\n        }\n    }\n\n    function getNumber() {\n        var number;\n        for (var _i = 0, _l = arguments.length; _i < _l; _i++) {\n            number = _i ? arguments[_i]() : arguments[_i];\n            if (typeof number === 'number') {\n                break;\n            }\n        }\n\n        return number;\n    }\n\n    function edgeResistance(pos, edge) {\n        return Math.round(pos + ((edge - pos) / 1.5));\n    }\n\n    function getProtocol() {\n        getProtocol.p = getProtocol.p || (location.protocol === 'https:' ? 'https://' : 'http://');\n        return getProtocol.p;\n    }\n\n    function parseHref(href) {\n        var a = document.createElement('a');\n        a.href = href;\n        return a;\n    }\n\n    function findVideoId(href, forceVideo) {\n        if (typeof href !== 'string') return href;\n        href = parseHref(href);\n\n        var id,\n            type;\n\n        if (href.host.match(/youtube\\.com/) && href.search) {\n            //.log();\n            id = href.search.split('v=')[1];\n            if (id) {\n                var ampersandPosition = id.indexOf('&');\n                if (ampersandPosition !== -1) {\n                    id = id.substring(0, ampersandPosition);\n                }\n                type = 'youtube';\n            }\n        } else if (href.host.match(/youtube\\.com|youtu\\.be|youtube-nocookie.com/)) {\n            id = href.pathname.replace(/^\\/(embed\\/|v\\/)?/, '').replace(/\\/.*/, '');\n            type = 'youtube';\n        } else if (href.host.match(/vimeo\\.com/)) {\n            type = 'vimeo';\n            id = href.pathname.replace(/^\\/(video\\/)?/, '').replace(/\\/.*/, '');\n        }\n\n        if ((!id || !type) && forceVideo) {\n            id = href.href;\n            type = 'custom';\n        }\n\n        return id ? {id: id, type: type, s: href.search.replace(/^\\?/, ''), p: getProtocol()} : false;\n    }\n\n    function getVideoThumbs(dataFrame, data, fotorama) {\n        var img, thumb, video = dataFrame.video;\n        if (video.type === 'youtube') {\n            thumb = getProtocol() + 'img.youtube.com/vi/' + video.id + '/default.jpg';\n            img = thumb.replace(/\\/default.jpg$/, '/hqdefault.jpg');\n            dataFrame.thumbsReady = true;\n        } else if (video.type === 'vimeo') {\n            $.ajax({\n                url: getProtocol() + 'vimeo.com/api/oembed.json',\n                data: {\n                    url: 'https://vimeo.com/' + video.id\n                },\n                dataType: 'jsonp',\n                success: function (json) {\n                    dataFrame.thumbsReady = true;\n                    updateData(data, {\n                        img: json[0].thumbnail_url,\n                        thumb: json[0].thumbnail_url\n                    }, dataFrame.i, fotorama);\n                }\n            });\n        } else {\n            dataFrame.thumbsReady = true;\n        }\n\n        return {\n            img: img,\n            thumb: thumb\n        }\n    }\n\n    function updateData(data, _dataFrame, i, fotorama) {\n        for (var _i = 0, _l = data.length; _i < _l; _i++) {\n            var dataFrame = data[_i];\n\n            if (dataFrame.i === i && dataFrame.thumbsReady) {\n                var clear = {videoReady: true};\n                clear[STAGE_FRAME_KEY] = clear[NAV_THUMB_FRAME_KEY] = clear[NAV_DOT_FRAME_KEY] = false;\n\n                fotorama.splice(_i, 1, $.extend(\n                    {},\n                    dataFrame,\n                    clear,\n                    _dataFrame\n                ));\n\n                break;\n            }\n        }\n    }\n\n    function getDataFromHtml($el) {\n        var data = [];\n\n        function getDataFromImg($img, imgData, checkVideo) {\n            var $child = $img.children('img').eq(0),\n                _imgHref = $img.attr('href'),\n                _imgSrc = $img.attr('src'),\n                _thumbSrc = $child.attr('src'),\n                _video = imgData.video,\n                video = checkVideo ? findVideoId(_imgHref, _video === true) : false;\n\n            if (video) {\n                _imgHref = false;\n            } else {\n                video = _video;\n            }\n\n            getDimensions($img, $child, $.extend(imgData, {\n                video: video,\n                img: imgData.img || _imgHref || _imgSrc || _thumbSrc,\n                thumb: imgData.thumb || _thumbSrc || _imgSrc || _imgHref\n            }));\n        }\n\n        function getDimensions($img, $child, imgData) {\n            var separateThumbFLAG = imgData.thumb && imgData.img !== imgData.thumb,\n                width = numberFromMeasure(imgData.width || $img.attr('width')),\n                height = numberFromMeasure(imgData.height || $img.attr('height'));\n\n            $.extend(imgData, {\n                width: width,\n                height: height,\n                thumbratio: getRatio(imgData.thumbratio || (numberFromMeasure(imgData.thumbwidth || ($child && $child.attr('width')) || separateThumbFLAG || width) / numberFromMeasure(imgData.thumbheight || ($child && $child.attr('height')) || separateThumbFLAG || height)))\n            });\n        }\n\n        $el.children().each(function () {\n            var $this = $(this),\n                dataFrame = optionsToLowerCase($.extend($this.data(), {id: $this.attr('id')}));\n            if ($this.is('a, img')) {\n                getDataFromImg($this, dataFrame, true);\n            } else if (!$this.is(':empty')) {\n                getDimensions($this, null, $.extend(dataFrame, {\n                    html: this,\n                    _html: $this.html() // Because of IE\n                }));\n            } else return;\n\n            data.push(dataFrame);\n        });\n\n        return data;\n    }\n\n    function isHidden(el) {\n        return el.offsetWidth === 0 && el.offsetHeight === 0;\n    }\n\n    function isDetached(el) {\n        return !$.contains(document.documentElement, el);\n    }\n\n    function waitFor(test, fn, timeout, i) {\n        if (!waitFor.i) {\n            waitFor.i = 1;\n            waitFor.ii = [true];\n        }\n\n        i = i || waitFor.i;\n\n        if (typeof waitFor.ii[i] === 'undefined') {\n            waitFor.ii[i] = true;\n        }\n\n        if (test()) {\n            fn();\n        } else {\n            waitFor.ii[i] && setTimeout(function () {\n                waitFor.ii[i] && waitFor(test, fn, timeout, i);\n            }, timeout || 100);\n        }\n\n        return waitFor.i++;\n    }\n\n    waitFor.stop = function (i) {\n        waitFor.ii[i] = false;\n    };\n\n    function fit($el, measuresToFit) {\n        var elData = $el.data(),\n            measures = elData.measures;\n\n        if (measures && (!elData.l ||\n            elData.l.W !== measures.width ||\n            elData.l.H !== measures.height ||\n            elData.l.r !== measures.ratio ||\n            elData.l.w !== measuresToFit.w ||\n            elData.l.h !== measuresToFit.h)) {\n\n            var height = minMaxLimit(measuresToFit.h, 0, measures.height),\n                width = height * measures.ratio;\n\n            UTIL.setRatio($el, width, height);\n\n            elData.l = {\n                W: measures.width,\n                H: measures.height,\n                r: measures.ratio,\n                w: measuresToFit.w,\n                h: measuresToFit.h\n            };\n        }\n\n        return true;\n    }\n\n    function setStyle($el, style) {\n        var el = $el[0];\n        if (el.styleSheet) {\n            el.styleSheet.cssText = style;\n        } else {\n            $el.html(style);\n        }\n    }\n\n    function findShadowEdge(pos, min, max, dir) {\n        return min === max ? false :\n            dir === 'vertical' ?\n                (pos <= min ? 'top' : pos >= max ? 'bottom' : 'top bottom') :\n                (pos <= min ? 'left' : pos >= max ? 'right' : 'left right');\n    }\n\n    function smartClick($el, fn, _options) {\n        _options = _options || {};\n\n        $el.each(function () {\n            var $this = $(this),\n                thisData = $this.data(),\n                startEvent;\n\n            if (thisData.clickOn) return;\n\n            thisData.clickOn = true;\n\n            $.extend(touch($this, {\n                onStart: function (e) {\n                    startEvent = e;\n                    (_options.onStart || noop).call(this, e);\n                },\n                onMove: _options.onMove || noop,\n                onTouchEnd: _options.onTouchEnd || noop,\n                onEnd: function (result) {\n                    if (result.moved) return;\n                    fn.call(this, startEvent);\n                }\n            }), {noMove: true});\n        });\n    }\n\n    function div(classes, child) {\n        return '<div class=\"' + classes + '\">' + (child || '') + '</div>';\n    }\n\n\n    /**\n     * Function transforming into valid classname\n     * @param className - name of the class\n     * @returns {string} - dom format of class name\n     */\n    function cls(className) {\n        return \".\" + className;\n    }\n\n    /**\n     *\n     * @param {json-object} videoItem Parsed object from data.video item or href from link a in input dates\n     * @returns {string} DOM view of video iframe\n     */\n    function createVideoFrame(videoItem) {\n        var frame = '<iframe src=\"' + videoItem.p + videoItem.type + '.com/embed/' + videoItem.id + '\" frameborder=\"0\" allowfullscreen></iframe>';\n        return frame;\n    }\n\n// Fisher\u2013Yates Shuffle\n// http://bost.ocks.org/mike/shuffle/\n    function shuffle(array) {\n        // While there remain elements to shuffle\n        var l = array.length;\n        while (l) {\n            // Pick a remaining element\n            var i = Math.floor(Math.random() * l--);\n\n            // And swap it with the current element\n            var t = array[l];\n            array[l] = array[i];\n            array[i] = t;\n        }\n\n        return array;\n    }\n\n    function clone(array) {\n        return Object.prototype.toString.call(array) == '[object Array]'\n            && $.map(array, function (frame) {\n                return $.extend({}, frame);\n            });\n    }\n\n    function lockScroll($el, left, top) {\n        $el\n            .scrollLeft(left || 0)\n            .scrollTop(top || 0);\n    }\n\n    function optionsToLowerCase(options) {\n        if (options) {\n            var opts = {};\n            $.each(options, function (key, value) {\n                opts[key.toLowerCase()] = value;\n            });\n\n            return opts;\n        }\n    }\n\n    function getRatio(_ratio) {\n        if (!_ratio) return;\n        var ratio = +_ratio;\n        if (!isNaN(ratio)) {\n            return ratio;\n        } else {\n            ratio = _ratio.split('/');\n            return +ratio[0] / +ratio[1] || undefined;\n        }\n    }\n\n    function addEvent(el, e, fn, bool) {\n        if (!e) return;\n        el.addEventListener ? el.addEventListener(e, fn, {passive: !!bool}) : el.attachEvent('on' + e, fn);\n    }\n\n    /**\n     *\n     * @param position guess position for navShaft\n     * @param restriction object contains min and max values for position\n     * @returns {*} filtered value of position\n     */\n    function validateRestrictions(position, restriction) {\n        if (position > restriction.max) {\n            position = restriction.max;\n        } else {\n            if (position < restriction.min) {\n                position = restriction.min;\n            }\n        }\n        return position;\n    }\n\n    function validateSlidePos(opt, navShaftTouchTail, guessIndex, offsetNav, $guessNavFrame, $navWrap, dir) {\n        var position,\n            size,\n            wrapSize;\n        if (dir === 'horizontal') {\n            size = opt.thumbwidth;\n            wrapSize = $navWrap.width();\n        } else {\n            size = opt.thumbheight;\n            wrapSize = $navWrap.height();\n        }\n        if ( (size + opt.margin) * (guessIndex + 1) >= (wrapSize - offsetNav) ) {\n            if (dir === 'horizontal') {\n                position = -$guessNavFrame.position().left;\n            } else {\n                position = -$guessNavFrame.position().top;\n            }\n        } else {\n            if ((size + opt.margin) * (guessIndex) <= Math.abs(offsetNav)) {\n                if (dir === 'horizontal') {\n                    position = -$guessNavFrame.position().left + wrapSize - (size + opt.margin);\n                } else {\n                    position = -$guessNavFrame.position().top + wrapSize - (size + opt.margin);\n                }\n            } else {\n                position = offsetNav;\n            }\n        }\n        position = validateRestrictions(position, navShaftTouchTail);\n\n        return position || 0;\n    }\n\n    function elIsDisabled(el) {\n        return !!el.getAttribute('disabled');\n    }\n\n    function disableAttr(FLAG, disable) {\n        if (disable) {\n            return {disabled: FLAG};\n        } else {\n            return {tabindex: FLAG * -1 + '', disabled: FLAG};\n\n        }\n    }\n\n    function addEnterUp(el, fn) {\n        addEvent(el, 'keyup', function (e) {\n            elIsDisabled(el) || e.keyCode == 13 && fn.call(el, e);\n        });\n    }\n\n    function addFocus(el, fn) {\n        addEvent(el, 'focus', el.onfocusin = function (e) {\n            fn.call(el, e);\n        }, true);\n    }\n\n    function stopEvent(e, stopPropagation) {\n        if (!Modernizr.touch) {\n            e.preventDefault ? e.preventDefault() : (e.returnValue = false);\n        }\n        stopPropagation && e.stopPropagation && e.stopPropagation();\n    }\n\n    function getDirectionSign(forward) {\n        return forward ? '>' : '<';\n    }\n\n    var UTIL = (function () {\n\n        function setRatioClass($el, wh, ht) {\n            var rateImg = wh / ht;\n\n            if (rateImg <= 1) {\n                $el.parent().removeClass(horizontalImageClass);\n                $el.parent().addClass(verticalImageClass);\n            } else {\n                $el.parent().removeClass(verticalImageClass);\n                $el.parent().addClass(horizontalImageClass);\n            }\n        }\n\n        /**\n         * Set specific attribute in thumbnail template\n         * @param $frame DOM item of specific thumbnail\n         * @param value Value which must be setted into specific attribute\n         * @param searchAttr Name of attribute where value must be included\n         */\n        function setThumbAttr($frame, value, searchAttr) {\n            var attr = searchAttr;\n\n            if (!$frame.attr(attr) && $frame.attr(attr) !== undefined) {\n                $frame.attr(attr, value);\n            }\n\n            if ($frame.find(\"[\" + attr + \"]\").length) {\n                $frame.find(\"[\" + attr + \"]\")\n                    .each(function () {\n                        $(this).attr(attr, value);\n                    });\n            }\n        }\n\n        /**\n         * Method describe behavior need to render caption on preview or not\n         * @param frameItem specific item from data\n         * @param isExpected {bool} if items with caption need render them or not\n         * @returns {boolean} if true then caption should be rendered\n         */\n        function isExpectedCaption(frameItem, isExpected, undefined) {\n            var expected = false,\n                frameExpected;\n\n            frameItem.showCaption === undefined || frameItem.showCaption === true ? frameExpected = true : frameExpected = false;\n\n            if (!isExpected) {\n                return false;\n            }\n\n            if (frameItem.caption && frameExpected) {\n                expected = true;\n            }\n\n            return expected;\n        }\n\n        return {\n            setRatio: setRatioClass,\n            setThumbAttr: setThumbAttr,\n            isExpectedCaption: isExpectedCaption\n        };\n\n    }(UTIL || {}, jQuery));\n\n    function slide($el, options) {\n        var elData = $el.data(),\n            elPos = Math.round(options.pos),\n            onEndFn = function () {\n                if (elData && elData.sliding) {\n                    elData.sliding = false;\n                }\n                (options.onEnd || noop)();\n            };\n\n        if (typeof options.overPos !== 'undefined' && options.overPos !== options.pos) {\n            elPos = options.overPos;\n        }\n\n        var translate = $.extend(getTranslate(elPos, options.direction), options.width && {width: options.width}, options.height && {height: options.height});\n        if (elData && elData.sliding) {\n            elData.sliding = true;\n        }\n\n        if (CSS3) {\n            $el.css($.extend(getDuration(options.time), translate));\n\n            if (options.time > 10) {\n                afterTransition($el, 'transform', onEndFn, options.time);\n            } else {\n                onEndFn();\n            }\n        } else {\n            $el.stop().animate(translate, options.time, BEZIER, onEndFn);\n        }\n    }\n\n    function fade($el1, $el2, $frames, options, fadeStack, chain) {\n        var chainedFLAG = typeof chain !== 'undefined';\n        if (!chainedFLAG) {\n            fadeStack.push(arguments);\n            Array.prototype.push.call(arguments, fadeStack.length);\n            if (fadeStack.length > 1) return;\n        }\n\n        $el1 = $el1 || $($el1);\n        $el2 = $el2 || $($el2);\n\n        var _$el1 = $el1[0],\n            _$el2 = $el2[0],\n            crossfadeFLAG = options.method === 'crossfade',\n            onEndFn = function () {\n                if (!onEndFn.done) {\n                    onEndFn.done = true;\n                    var args = (chainedFLAG || fadeStack.shift()) && fadeStack.shift();\n                    args && fade.apply(this, args);\n                    (options.onEnd || noop)(!!args);\n                }\n            },\n            time = options.time / (chain || 1);\n\n        $frames.removeClass(fadeRearClass + ' ' + fadeFrontClass);\n\n        $el1\n            .stop()\n            .addClass(fadeRearClass);\n        $el2\n            .stop()\n            .addClass(fadeFrontClass);\n\n        crossfadeFLAG && _$el2 && $el1.fadeTo(0, 0);\n\n        $el1.fadeTo(crossfadeFLAG ? time : 0, 1, crossfadeFLAG && onEndFn);\n        $el2.fadeTo(time, 0, onEndFn);\n\n        (_$el1 && crossfadeFLAG) || _$el2 || onEndFn();\n    }\n\n    var lastEvent,\n        moveEventType,\n        preventEvent,\n        preventEventTimeout,\n        dragDomEl;\n\n    function extendEvent(e) {\n        var touch = (e.touches || [])[0] || e;\n        e._x = touch.pageX || touch.originalEvent.pageX;\n        e._y = touch.clientY || touch.originalEvent.clientY;\n        e._now = $.now();\n    }\n\n    function touch($el, options) {\n        var el = $el[0],\n            tail = {},\n            touchEnabledFLAG,\n            startEvent,\n            $target,\n            controlTouch,\n            touchFLAG,\n            targetIsSelectFLAG,\n            targetIsLinkFlag,\n            isDisabledSwipe,\n            tolerance,\n            moved;\n\n        function onStart(e) {\n            $target = $(e.target);\n            tail.checked = targetIsSelectFLAG = targetIsLinkFlag = isDisabledSwipe = moved = false;\n\n            if (touchEnabledFLAG\n                || tail.flow\n                || (e.touches && e.touches.length > 1)\n                || e.which > 1\n                || (lastEvent && lastEvent.type !== e.type && preventEvent)\n                || (targetIsSelectFLAG = options.select && $target.is(options.select, el))) return targetIsSelectFLAG;\n\n            touchFLAG = e.type === 'touchstart';\n            targetIsLinkFlag = $target.is('a, a *', el);\n            isDisabledSwipe = $target.hasClass('disableSwipe');\n            controlTouch = tail.control;\n\n            tolerance = (tail.noMove || tail.noSwipe || controlTouch) ? 16 : !tail.snap ? 4 : 0;\n\n            extendEvent(e);\n\n            startEvent = lastEvent = e;\n            moveEventType = e.type.replace(/down|start/, 'move').replace(/Down/, 'Move');\n\n            (options.onStart || noop).call(el, e, {control: controlTouch, $target: $target});\n\n            touchEnabledFLAG = tail.flow = true;\n\n            if (!isDisabledSwipe && (!touchFLAG || tail.go)) stopEvent(e);\n        }\n\n        function onMove(e) {\n            if ((e.touches && e.touches.length > 1)\n                || (MS_POINTER && !e.isPrimary)\n                || moveEventType !== e.type\n                || !touchEnabledFLAG) {\n                touchEnabledFLAG && onEnd();\n                (options.onTouchEnd || noop)();\n                return;\n            }\n\n            isDisabledSwipe = $(e.target).hasClass('disableSwipe');\n\n            if (isDisabledSwipe) {\n                return;\n            }\n\n            extendEvent(e);\n\n            var xDiff = Math.abs(e._x - startEvent._x), // opt _x \u2192 _pageX\n                yDiff = Math.abs(e._y - startEvent._y),\n                xyDiff = xDiff - yDiff,\n                xWin = (tail.go || tail.x || xyDiff >= 0) && !tail.noSwipe,\n                yWin = xyDiff < 0;\n\n            if (touchFLAG && !tail.checked) {\n                if (touchEnabledFLAG = xWin) {\n                    stopEvent(e);\n                }\n            } else {\n                stopEvent(e);\n                if (movedEnough(xDiff,yDiff)) {\n                    (options.onMove || noop).call(el, e, {touch: touchFLAG});\n                }\n            }\n\n            if (!moved && movedEnough(xDiff, yDiff) && Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)) > tolerance) {\n                moved = true;\n            }\n\n            tail.checked = tail.checked || xWin || yWin;\n        }\n\n        function movedEnough(xDiff, yDiff) {\n            return xDiff > yDiff && xDiff > 1.5;\n        }\n\n        function onEnd(e) {\n            (options.onTouchEnd || noop)();\n\n            var _touchEnabledFLAG = touchEnabledFLAG;\n            tail.control = touchEnabledFLAG = false;\n\n            if (_touchEnabledFLAG) {\n                tail.flow = false;\n            }\n\n            if (!_touchEnabledFLAG || (targetIsLinkFlag && !tail.checked)) return;\n\n            e && stopEvent(e);\n\n            preventEvent = true;\n            clearTimeout(preventEventTimeout);\n            preventEventTimeout = setTimeout(function () {\n                preventEvent = false;\n            }, 1000);\n\n            (options.onEnd || noop).call(el, {\n                moved: moved,\n                $target: $target,\n                control: controlTouch,\n                touch: touchFLAG,\n                startEvent: startEvent,\n                aborted: !e || e.type === 'MSPointerCancel'\n            });\n        }\n\n        function onOtherStart() {\n            if (tail.flow) return;\n            tail.flow = true;\n        }\n\n        function onOtherEnd() {\n            if (!tail.flow) return;\n            tail.flow = false;\n        }\n\n        if (MS_POINTER) {\n            addEvent(el, 'MSPointerDown', onStart);\n            addEvent(document, 'MSPointerMove', onMove);\n            addEvent(document, 'MSPointerCancel', onEnd);\n            addEvent(document, 'MSPointerUp', onEnd);\n        } else {\n            addEvent(el, 'touchstart', onStart);\n            addEvent(el, 'touchmove', onMove);\n            addEvent(el, 'touchend', onEnd);\n\n            addEvent(document, 'touchstart', onOtherStart, true);\n            addEvent(document, 'touchend', onOtherEnd);\n            addEvent(document, 'touchcancel', onOtherEnd);\n\n            $WINDOW.on('scroll', onOtherEnd);\n\n            $el.on('mousedown', onStart);\n            $DOCUMENT\n                .on('mousemove', onMove)\n                .on('mouseup', onEnd);\n        }\n        if (Modernizr.touch) {\n            dragDomEl = 'a';\n        } else {\n            dragDomEl = 'div';\n        }\n        $el.on('click', dragDomEl, function (e) {\n            tail.checked && stopEvent(e);\n        });\n\n        return tail;\n    }\n\n    function moveOnTouch($el, options) {\n        var el = $el[0],\n            elData = $el.data(),\n            tail = {},\n            startCoo,\n            coo,\n            startElPos,\n            moveElPos,\n            edge,\n            moveTrack,\n            startTime,\n            endTime,\n            min,\n            max,\n            snap,\n            dir,\n            slowFLAG,\n            controlFLAG,\n            moved,\n            tracked;\n\n        function startTracking(e, noStop) {\n            tracked = true;\n            startCoo = coo = (dir === 'vertical') ? e._y : e._x;\n            startTime = e._now;\n\n            moveTrack = [\n                [startTime, startCoo]\n            ];\n\n            startElPos = moveElPos = tail.noMove || noStop ? 0 : stop($el, (options.getPos || noop)()/*, options._001*/);\n\n            (options.onStart || noop).call(el, e);\n        }\n\n        function onStart(e, result) {\n            min = tail.min;\n            max = tail.max;\n            snap = tail.snap,\n                dir = tail.direction || 'horizontal',\n                $el.navdir = dir;\n\n            slowFLAG = e.altKey;\n            tracked = moved = false;\n\n            controlFLAG = result.control;\n\n            if (!controlFLAG && !elData.sliding) {\n                startTracking(e);\n            }\n        }\n\n        function onMove(e, result) {\n            if (!tail.noSwipe) {\n                if (!tracked) {\n                    startTracking(e);\n                }\n                coo = (dir === 'vertical') ? e._y : e._x;\n\n                moveTrack.push([e._now, coo]);\n\n                moveElPos = startElPos - (startCoo - coo);\n\n                edge = findShadowEdge(moveElPos, min, max, dir);\n\n                if (moveElPos <= min) {\n                    moveElPos = edgeResistance(moveElPos, min);\n                } else if (moveElPos >= max) {\n                    moveElPos = edgeResistance(moveElPos, max);\n                }\n\n                if (!tail.noMove) {\n                    $el.css(getTranslate(moveElPos, dir));\n                    if (!moved) {\n                        moved = true;\n                        // only for mouse\n                        result.touch || MS_POINTER || $el.addClass(grabbingClass);\n                    }\n\n                    (options.onMove || noop).call(el, e, {pos: moveElPos, edge: edge});\n                }\n            }\n        }\n\n        function onEnd(result) {\n            if (tail.noSwipe && result.moved) return;\n\n            if (!tracked) {\n                startTracking(result.startEvent, true);\n            }\n\n            result.touch || MS_POINTER || $el.removeClass(grabbingClass);\n\n            endTime = $.now();\n\n            var _backTimeIdeal = endTime - TOUCH_TIMEOUT,\n                _backTime,\n                _timeDiff,\n                _timeDiffLast,\n                backTime = null,\n                backCoo,\n                virtualPos,\n                limitPos,\n                newPos,\n                overPos,\n                time = TRANSITION_DURATION,\n                speed,\n                friction = options.friction;\n\n            for (var _i = moveTrack.length - 1; _i >= 0; _i--) {\n                _backTime = moveTrack[_i][0];\n                _timeDiff = Math.abs(_backTime - _backTimeIdeal);\n                if (backTime === null || _timeDiff < _timeDiffLast) {\n                    backTime = _backTime;\n                    backCoo = moveTrack[_i][1];\n                } else if (backTime === _backTimeIdeal || _timeDiff > _timeDiffLast) {\n                    break;\n                }\n                _timeDiffLast = _timeDiff;\n            }\n\n            newPos = minMaxLimit(moveElPos, min, max);\n\n            var cooDiff = backCoo - coo,\n                forwardFLAG = cooDiff >= 0,\n                timeDiff = endTime - backTime,\n                longTouchFLAG = timeDiff > TOUCH_TIMEOUT,\n                swipeFLAG = !longTouchFLAG && moveElPos !== startElPos && newPos === moveElPos;\n\n            if (snap) {\n                newPos = minMaxLimit(Math[swipeFLAG ? (forwardFLAG ? 'floor' : 'ceil') : 'round'](moveElPos / snap) * snap, min, max);\n                min = max = newPos;\n            }\n\n            if (swipeFLAG && (snap || newPos === moveElPos)) {\n                speed = -(cooDiff / timeDiff);\n                time *= minMaxLimit(Math.abs(speed), options.timeLow, options.timeHigh);\n                virtualPos = Math.round(moveElPos + speed * time / friction);\n\n                if (!snap) {\n                    newPos = virtualPos;\n                }\n\n                if (!forwardFLAG && virtualPos > max || forwardFLAG && virtualPos < min) {\n                    limitPos = forwardFLAG ? min : max;\n                    overPos = virtualPos - limitPos;\n                    if (!snap) {\n                        newPos = limitPos;\n                    }\n                    overPos = minMaxLimit(newPos + overPos * .03, limitPos - 50, limitPos + 50);\n                    time = Math.abs((moveElPos - overPos) / (speed / friction));\n                }\n            }\n\n            time *= slowFLAG ? 10 : 1;\n\n            (options.onEnd || noop).call(el, $.extend(result, {\n                moved: result.moved || longTouchFLAG && snap,\n                pos: moveElPos,\n                newPos: newPos,\n                overPos: overPos,\n                time: time,\n                dir: dir\n            }));\n        }\n\n        tail = $.extend(touch(options.$wrap, $.extend({}, options, {\n            onStart: onStart,\n            onMove: onMove,\n            onEnd: onEnd\n        })), tail);\n\n        return tail;\n    }\n\n    function wheel($el, options) {\n        var el = $el[0],\n            lockFLAG,\n            lastDirection,\n            lastNow,\n            tail = {\n                prevent: {}\n            };\n\n        addEvent(el, WHEEL, function (e) {\n            var yDelta = e.wheelDeltaY || -1 * e.deltaY || 0,\n                xDelta = e.wheelDeltaX || -1 * e.deltaX || 0,\n                xWin = Math.abs(xDelta) && !Math.abs(yDelta),\n                direction = getDirectionSign(xDelta < 0),\n                sameDirection = lastDirection === direction,\n                now = $.now(),\n                tooFast = now - lastNow < TOUCH_TIMEOUT;\n\n            lastDirection = direction;\n            lastNow = now;\n\n            if (!xWin || !tail.ok || tail.prevent[direction] && !lockFLAG) {\n                return;\n            } else {\n                stopEvent(e, true);\n                if (lockFLAG && sameDirection && tooFast) {\n                    return;\n                }\n            }\n\n            if (options.shift) {\n                lockFLAG = true;\n                clearTimeout(tail.t);\n                tail.t = setTimeout(function () {\n                    lockFLAG = false;\n                }, SCROLL_LOCK_TIMEOUT);\n            }\n\n            (options.onEnd || noop)(e, options.shift ? direction : xDelta);\n\n        });\n\n        return tail;\n    }\n\n    jQuery.Fotorama = function ($fotorama, opts) {\n        $HTML = $('html');\n        $BODY = $('body');\n\n        var that = this,\n            stamp = $.now(),\n            stampClass = _fotoramaClass + stamp,\n            fotorama = $fotorama[0],\n            data,\n            dataFrameCount = 1,\n            fotoramaData = $fotorama.data(),\n            size,\n\n            $style = $('<style></style>'),\n\n            $anchor = $(div(hiddenClass)),\n            $wrap = $fotorama.find(cls(wrapClass)),\n            $stage = $wrap.find(cls(stageClass)),\n            stage = $stage[0],\n\n            $stageShaft = $fotorama.find(cls(stageShaftClass)),\n            $stageFrame = $(),\n            $arrPrev = $fotorama.find(cls(arrPrevClass)),\n            $arrNext = $fotorama.find(cls(arrNextClass)),\n            $arrs = $fotorama.find(cls(arrClass)),\n            $navWrap = $fotorama.find(cls(navWrapClass)),\n            $nav = $navWrap.find(cls(navClass)),\n            $navShaft = $nav.find(cls(navShaftClass)),\n            $navFrame,\n            $navDotFrame = $(),\n            $navThumbFrame = $(),\n\n            stageShaftData = $stageShaft.data(),\n            navShaftData = $navShaft.data(),\n\n            $thumbBorder = $fotorama.find(cls(thumbBorderClass)),\n            $thumbArrLeft = $fotorama.find(cls(thumbArrLeft)),\n            $thumbArrRight = $fotorama.find(cls(thumbArrRight)),\n\n            $fullscreenIcon = $fotorama.find(cls(fullscreenIconClass)),\n            fullscreenIcon = $fullscreenIcon[0],\n            $videoPlay = $(div(videoPlayClass)),\n            $videoClose = $fotorama.find(cls(videoCloseClass)),\n            videoClose = $videoClose[0],\n\n            $spinner = $fotorama.find(cls(fotoramaSpinnerClass)),\n\n            $videoPlaying,\n\n            activeIndex = false,\n            activeFrame,\n            activeIndexes,\n            repositionIndex,\n            dirtyIndex,\n            lastActiveIndex,\n            prevIndex,\n            nextIndex,\n            nextAutoplayIndex,\n            startIndex,\n\n            o_loop,\n            o_nav,\n            o_navThumbs,\n            o_navTop,\n            o_allowFullScreen,\n            o_nativeFullScreen,\n            o_fade,\n            o_thumbSide,\n            o_thumbSide2,\n            o_transitionDuration,\n            o_transition,\n            o_shadows,\n            o_rtl,\n            o_keyboard,\n            lastOptions = {},\n\n            measures = {},\n            measuresSetFLAG,\n\n            stageShaftTouchTail = {},\n            stageWheelTail = {},\n            navShaftTouchTail = {},\n            navWheelTail = {},\n\n            scrollTop,\n            scrollLeft,\n\n            showedFLAG,\n            pausedAutoplayFLAG,\n            stoppedAutoplayFLAG,\n\n            toDeactivate = {},\n            toDetach = {},\n\n            measuresStash,\n\n            touchedFLAG,\n\n            hoverFLAG,\n\n            navFrameKey,\n            stageLeft = 0,\n\n            fadeStack = [];\n\n        $wrap[STAGE_FRAME_KEY] = $('<div class=\"' + stageFrameClass + '\"></div>');\n        $wrap[NAV_THUMB_FRAME_KEY] = $($.Fotorama.jst.thumb());\n        $wrap[NAV_DOT_FRAME_KEY] = $($.Fotorama.jst.dots());\n\n        toDeactivate[STAGE_FRAME_KEY] = [];\n        toDeactivate[NAV_THUMB_FRAME_KEY] = [];\n        toDeactivate[NAV_DOT_FRAME_KEY] = [];\n        toDetach[STAGE_FRAME_KEY] = {};\n\n        $wrap.addClass(CSS3 ? wrapCss3Class : wrapCss2Class);\n\n        fotoramaData.fotorama = this;\n\n        /**\n         * Search video items in incoming data and transform object for video layout.\n         *\n         */\n        function checkForVideo() {\n            $.each(data, function (i, dataFrame) {\n                if (!dataFrame.i) {\n                    dataFrame.i = dataFrameCount++;\n                    var video = findVideoId(dataFrame.video, true);\n                    if (video) {\n                        var thumbs = {};\n                        dataFrame.video = video;\n                        if (!dataFrame.img && !dataFrame.thumb) {\n                            thumbs = getVideoThumbs(dataFrame, data, that);\n                        } else {\n                            dataFrame.thumbsReady = true;\n                        }\n                        updateData(data, {img: thumbs.img, thumb: thumbs.thumb}, dataFrame.i, that);\n                    }\n                }\n            });\n        }\n\n        /**\n         * Checks if current media object is YouTube or Vimeo video stream\n         * @returns {boolean}\n         */\n        function isVideo() {\n            return $((that.activeFrame || {}).$stageFrame || {}).hasClass('fotorama-video-container');\n        }\n\n        function allowKey(key) {\n            return o_keyboard[key];\n        }\n\n        function setStagePosition() {\n            if ($stage !== undefined) {\n\n                if (opts.navdir == 'vertical') {\n                    var padding = opts.thumbwidth + opts.thumbmargin;\n\n                    $stage.css('left', padding);\n                    $arrNext.css('right', padding);\n                    $fullscreenIcon.css('right', padding);\n                    $wrap.css('width', $wrap.css('width') + padding);\n                    $stageShaft.css('max-width', $wrap.width() - padding);\n                } else {\n                    $stage.css('left', '');\n                    $arrNext.css('right', '');\n                    $fullscreenIcon.css('right', '');\n                    $wrap.css('width', $wrap.css('width') + padding);\n                    $stageShaft.css('max-width', '');\n                }\n            }\n        }\n\n        function bindGlobalEvents(FLAG) {\n            var keydownCommon = 'keydown.' + _fotoramaClass,\n                localStamp = _fotoramaClass + stamp,\n                keydownLocal = 'keydown.' + localStamp,\n                keyupLocal = 'keyup.' + localStamp,\n                resizeLocal = 'resize.' + localStamp + ' ' + 'orientationchange.' + localStamp,\n                showParams;\n\n            if (FLAG) {\n                $DOCUMENT\n                    .on(keydownLocal, function (e) {\n                        var catched,\n                            index;\n\n                        if ($videoPlaying && e.keyCode === 27) {\n                            catched = true;\n                            unloadVideo($videoPlaying, true, true);\n                        } else if (that.fullScreen || (opts.keyboard && !that.index)) {\n                            if (e.keyCode === 27) {\n                                catched = true;\n                                that.cancelFullScreen();\n                            } else if ((e.shiftKey && e.keyCode === 32 && allowKey('space')) || (!e.altKey && !e.metaKey && e.keyCode === 37 && allowKey('left')) || (e.keyCode === 38 && allowKey('up') && $(':focus').attr('data-gallery-role'))) {\n                                that.longPress.progress();\n                                index = '<';\n                            } else if ((e.keyCode === 32 && allowKey('space')) || (!e.altKey && !e.metaKey && e.keyCode === 39 && allowKey('right')) || (e.keyCode === 40 && allowKey('down') && $(':focus').attr('data-gallery-role'))) {\n                                that.longPress.progress();\n                                index = '>';\n                            } else if (e.keyCode === 36 && allowKey('home')) {\n                                that.longPress.progress();\n                                index = '<<';\n                            } else if (e.keyCode === 35 && allowKey('end')) {\n                                that.longPress.progress();\n                                index = '>>';\n                            }\n                        }\n\n                        (catched || index) && stopEvent(e);\n                        showParams = {index: index, slow: e.altKey, user: true};\n                        index && (that.longPress.inProgress ?\n                            that.showWhileLongPress(showParams) :\n                            that.show(showParams));\n                    });\n\n                if (FLAG) {\n                    $DOCUMENT\n                        .on(keyupLocal, function (e) {\n                            if (that.longPress.inProgress) {\n                                that.showEndLongPress({user: true});\n                            }\n                            that.longPress.reset();\n                        });\n                }\n\n                if (!that.index) {\n                    $DOCUMENT\n                        .off(keydownCommon)\n                        .on(keydownCommon, 'textarea, input, select', function (e) {\n                            !$BODY.hasClass(_fullscreenClass) && e.stopPropagation();\n                        });\n                }\n\n                $WINDOW.on(resizeLocal, that.resize);\n            } else {\n                $DOCUMENT.off(keydownLocal);\n                $WINDOW.off(resizeLocal);\n            }\n        }\n\n        function appendElements(FLAG) {\n            if (FLAG === appendElements.f) return;\n\n            if (FLAG) {\n                $fotorama\n                    .addClass(_fotoramaClass + ' ' + stampClass)\n                    .before($anchor)\n                    .before($style);\n                addInstance(that);\n            } else {\n                $anchor.detach();\n                $style.detach();\n                $fotorama\n                    .html(fotoramaData.urtext)\n                    .removeClass(stampClass);\n\n                hideInstance(that);\n            }\n\n            bindGlobalEvents(FLAG);\n            appendElements.f = FLAG;\n        }\n\n        /**\n         * Set and install data from incoming @param {JSON} options or takes data attr from data-\"name\"=... values.\n         */\n        function setData() {\n            data = that.data = data || clone(opts.data) || getDataFromHtml($fotorama);\n            size = that.size = data.length;\n\n            ready.ok && opts.shuffle && shuffle(data);\n\n            checkForVideo();\n\n            activeIndex = limitIndex(activeIndex);\n\n            size && appendElements(true);\n        }\n\n        function stageNoMove() {\n            var _noMove = size < 2 || $videoPlaying;\n            stageShaftTouchTail.noMove = _noMove || o_fade;\n            stageShaftTouchTail.noSwipe = _noMove || !opts.swipe;\n\n            !o_transition && $stageShaft.toggleClass(grabClass, !opts.click && !stageShaftTouchTail.noMove && !stageShaftTouchTail.noSwipe);\n            MS_POINTER && $wrap.toggleClass(wrapPanYClass, !stageShaftTouchTail.noSwipe);\n        }\n\n        function setAutoplayInterval(interval) {\n            if (interval === true) interval = '';\n            opts.autoplay = Math.max(+interval || AUTOPLAY_INTERVAL, o_transitionDuration * 1.5);\n        }\n\n        function updateThumbArrow(opt) {\n            if (opt.navarrows && opt.nav === 'thumbs') {\n                $thumbArrLeft.show();\n                $thumbArrRight.show();\n            } else {\n                $thumbArrLeft.hide();\n                $thumbArrRight.hide();\n            }\n\n        }\n\n        function getThumbsInSlide($el, opts) {\n            return Math.floor($wrap.width() / (opts.thumbwidth + opts.thumbmargin));\n        }\n\n        /**\n         * Options on the fly\n         * */\n        function setOptions() {\n            if (!opts.nav || opts.nav === 'dots') {\n                opts.navdir = 'horizontal'\n            }\n\n            that.options = opts = optionsToLowerCase(opts);\n            thumbsPerSlide = getThumbsInSlide($wrap, opts);\n\n            o_fade = (opts.transition === 'crossfade' || opts.transition === 'dissolve');\n\n            o_loop = opts.loop && (size > 2 || (o_fade && (!o_transition || o_transition !== 'slide')));\n\n            o_transitionDuration = +opts.transitionduration || TRANSITION_DURATION;\n\n            o_rtl = opts.direction === 'rtl';\n\n            o_keyboard = $.extend({}, opts.keyboard && KEYBOARD_OPTIONS, opts.keyboard);\n            updateThumbArrow(opts);\n            var classes = {add: [], remove: []};\n\n            function addOrRemoveClass(FLAG, value) {\n                classes[FLAG ? 'add' : 'remove'].push(value);\n            }\n\n            if (size > 1) {\n                o_nav = opts.nav;\n                o_navTop = opts.navposition === 'top';\n                classes.remove.push(selectClass);\n\n                $arrs.toggle(!!opts.arrows);\n            } else {\n                o_nav = false;\n                $arrs.hide();\n            }\n\n            arrsUpdate();\n            stageWheelUpdate();\n            thumbArrUpdate();\n            if (opts.autoplay) setAutoplayInterval(opts.autoplay);\n\n            o_thumbSide = numberFromMeasure(opts.thumbwidth) || THUMB_SIZE;\n            o_thumbSide2 = numberFromMeasure(opts.thumbheight) || THUMB_SIZE;\n\n            stageWheelTail.ok = navWheelTail.ok = opts.trackpad && !SLOW;\n\n            stageNoMove();\n\n            extendMeasures(opts, [measures]);\n\n            o_navThumbs = o_nav === 'thumbs';\n\n            if ($navWrap.filter(':hidden') && !!o_nav) {\n                $navWrap.show();\n            }\n            if (o_navThumbs) {\n                frameDraw(size, 'navThumb');\n\n                $navFrame = $navThumbFrame;\n                navFrameKey = NAV_THUMB_FRAME_KEY;\n\n                setStyle($style, $.Fotorama.jst.style({\n                    w: o_thumbSide,\n                    h: o_thumbSide2,\n                    b: opts.thumbborderwidth,\n                    m: opts.thumbmargin,\n                    s: stamp,\n                    q: !COMPAT\n                }));\n\n                $nav\n                    .addClass(navThumbsClass)\n                    .removeClass(navDotsClass);\n            } else if (o_nav === 'dots') {\n                frameDraw(size, 'navDot');\n\n                $navFrame = $navDotFrame;\n                navFrameKey = NAV_DOT_FRAME_KEY;\n\n                $nav\n                    .addClass(navDotsClass)\n                    .removeClass(navThumbsClass);\n            } else {\n                $navWrap.hide();\n                o_nav = false;\n                $nav.removeClass(navThumbsClass + ' ' + navDotsClass);\n            }\n\n            if (o_nav) {\n                if (o_navTop) {\n                    $navWrap.insertBefore($stage);\n                } else {\n                    $navWrap.insertAfter($stage);\n                }\n                frameAppend.nav = false;\n\n                frameAppend($navFrame, $navShaft, 'nav');\n            }\n\n            o_allowFullScreen = opts.allowfullscreen;\n\n            if (o_allowFullScreen) {\n                $fullscreenIcon.prependTo($stage);\n                o_nativeFullScreen = FULLSCREEN && o_allowFullScreen === 'native';\n            } else {\n                $fullscreenIcon.detach();\n                o_nativeFullScreen = false;\n            }\n\n            addOrRemoveClass(o_fade, wrapFadeClass);\n            addOrRemoveClass(!o_fade, wrapSlideClass);\n            addOrRemoveClass(!opts.captions, wrapNoCaptionsClass);\n            addOrRemoveClass(o_rtl, wrapRtlClass);\n            addOrRemoveClass(opts.arrows, wrapToggleArrowsClass);\n\n            o_shadows = opts.shadows && !SLOW;\n            addOrRemoveClass(!o_shadows, wrapNoShadowsClass);\n\n            $wrap\n                .addClass(classes.add.join(' '))\n                .removeClass(classes.remove.join(' '));\n\n            lastOptions = $.extend({}, opts);\n            setStagePosition();\n        }\n\n        function normalizeIndex(index) {\n            return index < 0 ? (size + (index % size)) % size : index >= size ? index % size : index;\n        }\n\n        function limitIndex(index) {\n            return minMaxLimit(index, 0, size - 1);\n        }\n\n        function edgeIndex(index) {\n            return o_loop ? normalizeIndex(index) : limitIndex(index);\n        }\n\n        function getPrevIndex(index) {\n            return index > 0 || o_loop ? index - 1 : false;\n        }\n\n        function getNextIndex(index) {\n            return index < size - 1 || o_loop ? index + 1 : false;\n        }\n\n        function setStageShaftMinmaxAndSnap() {\n            stageShaftTouchTail.min = o_loop ? -Infinity : -getPosByIndex(size - 1, measures.w, opts.margin, repositionIndex);\n            stageShaftTouchTail.max = o_loop ? Infinity : -getPosByIndex(0, measures.w, opts.margin, repositionIndex);\n            stageShaftTouchTail.snap = measures.w + opts.margin;\n        }\n\n        function setNavShaftMinMax() {\n\n            var isVerticalDir = (opts.navdir === 'vertical');\n            var param = isVerticalDir ? $navShaft.height() : $navShaft.width();\n            var mainParam = isVerticalDir ? measures.h : measures.nw;\n            navShaftTouchTail.min = Math.min(0, mainParam - param);\n            navShaftTouchTail.max = 0;\n            navShaftTouchTail.direction = opts.navdir;\n            $navShaft.toggleClass(grabClass, !(navShaftTouchTail.noMove = navShaftTouchTail.min === navShaftTouchTail.max));\n        }\n\n        function eachIndex(indexes, type, fn) {\n            if (typeof indexes === 'number') {\n                indexes = new Array(indexes);\n                var rangeFLAG = true;\n            }\n            return $.each(indexes, function (i, index) {\n                if (rangeFLAG) index = i;\n                if (typeof index === 'number') {\n                    var dataFrame = data[normalizeIndex(index)];\n\n                    if (dataFrame) {\n                        var key = '$' + type + 'Frame',\n                            $frame = dataFrame[key];\n\n                        fn.call(this, i, index, dataFrame, $frame, key, $frame && $frame.data());\n                    }\n                }\n            });\n        }\n\n        function setMeasures(width, height, ratio, index) {\n            if (!measuresSetFLAG || (measuresSetFLAG === '*' && index === startIndex)) {\n\n                width = measureIsValid(opts.width) || measureIsValid(width) || WIDTH;\n                height = measureIsValid(opts.height) || measureIsValid(height) || HEIGHT;\n                that.resize({\n                    width: width,\n                    ratio: opts.ratio || ratio || width / height\n                }, 0, index !== startIndex && '*');\n            }\n        }\n\n        function loadImg(indexes, type, specialMeasures, again) {\n\n            eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {\n\n                if (!$frame) return;\n\n                var fullFLAG = that.fullScreen && !frameData.$full && type === 'stage';\n\n                if (frameData.$img && !again && !fullFLAG) return;\n\n                var img = new Image(),\n                    $img = $(img),\n                    imgData = $img.data();\n\n                frameData[fullFLAG ? '$full' : '$img'] = $img;\n\n                var srcKey = type === 'stage' ? (fullFLAG ? 'full' : 'img') : 'thumb',\n                    src = dataFrame[srcKey],\n                    dummy = fullFLAG ? dataFrame['img'] : dataFrame[type === 'stage' ? 'thumb' : 'img'];\n\n                if (type === 'navThumb') $frame = frameData.$wrap;\n\n                function triggerTriggerEvent(event) {\n                    var _index = normalizeIndex(index);\n                    triggerEvent(event, {\n                        index: _index,\n                        src: src,\n                        frame: data[_index]\n                    });\n                }\n\n                function error() {\n                    $img.remove();\n\n                    $.Fotorama.cache[src] = 'error';\n\n                    if ((!dataFrame.html || type !== 'stage') && dummy && dummy !== src) {\n                        dataFrame[srcKey] = src = dummy;\n                        frameData.$full = null;\n                        loadImg([index], type, specialMeasures, true);\n                    } else {\n                        if (src && !dataFrame.html && !fullFLAG) {\n                            $frame\n                                .trigger('f:error')\n                                .removeClass(loadingClass)\n                                .addClass(errorClass);\n\n                            triggerTriggerEvent('error');\n                        } else if (type === 'stage') {\n                            $frame\n                                .trigger('f:load')\n                                .removeClass(loadingClass + ' ' + errorClass)\n                                .addClass(loadedClass);\n\n                            triggerTriggerEvent('load');\n                            setMeasures();\n                        }\n\n                        frameData.state = 'error';\n\n                        if (size > 1 && data[index] === dataFrame && !dataFrame.html && !dataFrame.deleted && !dataFrame.video && !fullFLAG) {\n                            dataFrame.deleted = true;\n                            that.splice(index, 1);\n                        }\n                    }\n                }\n\n                function loaded() {\n                    $.Fotorama.measures[src] = imgData.measures = $.Fotorama.measures[src] || {\n                            width: img.width,\n                            height: img.height,\n                            ratio: img.width / img.height\n                        };\n\n                    setMeasures(imgData.measures.width, imgData.measures.height, imgData.measures.ratio, index);\n\n                    $img\n                        .off('load error')\n                        .addClass('' + (fullFLAG ? imgFullClass: imgClass))\n                        .attr('aria-hidden', 'false')\n                        .prependTo($frame);\n\n                    if ($frame.hasClass(stageFrameClass) && !$frame.hasClass(videoContainerClass)) {\n                        $frame.attr(\"href\", $img.attr(\"src\"));\n                    }\n\n                    fit($img, (\n                            $.isFunction(specialMeasures) ? specialMeasures() : specialMeasures) || measures);\n\n                    $.Fotorama.cache[src] = frameData.state = 'loaded';\n\n                    setTimeout(function () {\n                        $frame\n                            .trigger('f:load')\n                            .removeClass(loadingClass + ' ' + errorClass)\n                            .addClass(loadedClass + ' ' + (fullFLAG ? loadedFullClass : loadedImgClass));\n\n                        if (type === 'stage') {\n                            triggerTriggerEvent('load');\n                        } else if (dataFrame.thumbratio === AUTO || !dataFrame.thumbratio && opts.thumbratio === AUTO) {\n                            // danger! reflow for all thumbnails\n                            dataFrame.thumbratio = imgData.measures.ratio;\n                            reset();\n                        }\n                    }, 0);\n                }\n\n                if (!src) {\n                    error();\n                    return;\n                }\n\n                function waitAndLoad() {\n                    var _i = 10;\n                    waitFor(function () {\n                        return !touchedFLAG || !_i-- && !SLOW;\n                    }, function () {\n                        loaded();\n                    });\n                }\n\n                if (!$.Fotorama.cache[src]) {\n                    $.Fotorama.cache[src] = '*';\n\n                    $img\n                        .on('load', waitAndLoad)\n                        .on('error', error);\n                } else {\n                    (function justWait() {\n                        if ($.Fotorama.cache[src] === 'error') {\n                            error();\n                        } else if ($.Fotorama.cache[src] === 'loaded') {\n                            setTimeout(waitAndLoad, 0);\n                        } else {\n                            setTimeout(justWait, 100);\n                        }\n                    })();\n                }\n\n                frameData.state = '';\n                img.src = src;\n\n                if (frameData.data.caption) {\n                    img.alt = frameData.data.caption || \"\";\n                }\n\n                if (frameData.data.full) {\n                    $(img).data('original', frameData.data.full);\n                }\n\n                if (UTIL.isExpectedCaption(dataFrame, opts.showcaption)) {\n                    $(img).attr('aria-labelledby', dataFrame.labelledby);\n                }\n            });\n        }\n\n        function updateFotoramaState() {\n            var $frame = activeFrame[STAGE_FRAME_KEY];\n\n            if ($frame && !$frame.data().state) {\n                $spinner.addClass(spinnerShowClass);\n                $frame.on('f:load f:error', function () {\n                    $frame.off('f:load f:error');\n                    $spinner.removeClass(spinnerShowClass);\n                });\n            }\n        }\n\n        function addNavFrameEvents(frame) {\n            addEnterUp(frame, onNavFrameClick);\n            addFocus(frame, function () {\n\n                setTimeout(function () {\n                    lockScroll($nav);\n                }, 0);\n                slideNavShaft({time: o_transitionDuration, guessIndex: $(this).data().eq, minMax: navShaftTouchTail});\n            });\n        }\n\n        function frameDraw(indexes, type) {\n            eachIndex(indexes, type, function (i, index, dataFrame, $frame, key, frameData) {\n                if ($frame) return;\n\n                $frame = dataFrame[key] = $wrap[key].clone();\n                frameData = $frame.data();\n                frameData.data = dataFrame;\n                var frame = $frame[0],\n                    labelledbyValue = \"labelledby\" + $.now();\n\n                if (type === 'stage') {\n\n                    if (dataFrame.html) {\n                        $('<div class=\"' + htmlClass + '\"></div>')\n                            .append(\n                            dataFrame._html ? $(dataFrame.html)\n                                .removeAttr('id')\n                                .html(dataFrame._html) // Because of IE\n                                : dataFrame.html\n                        )\n                            .appendTo($frame);\n                    }\n\n                    if (dataFrame.id) {\n                        labelledbyValue = dataFrame.id || labelledbyValue;\n                    }\n                    dataFrame.labelledby = labelledbyValue;\n\n                    if (UTIL.isExpectedCaption(dataFrame, opts.showcaption)) {\n                        $($.Fotorama.jst.frameCaption({\n                            caption: dataFrame.caption,\n                            labelledby: labelledbyValue\n                        })).appendTo($frame);\n                    }\n\n                    dataFrame.video && $frame\n                        .addClass(stageFrameVideoClass)\n                        .append($videoPlay.clone());\n\n                    // This solves tabbing problems\n                    addFocus(frame, function (e) {\n                        setTimeout(function () {\n                            lockScroll($stage);\n                        }, 0);\n                        clickToShow({index: frameData.eq, user: true}, e);\n                    });\n\n                    $stageFrame = $stageFrame.add($frame);\n                } else if (type === 'navDot') {\n                    addNavFrameEvents(frame);\n                    $navDotFrame = $navDotFrame.add($frame);\n                } else if (type === 'navThumb') {\n                    addNavFrameEvents(frame);\n                    frameData.$wrap = $frame.children(':first');\n\n                    $navThumbFrame = $navThumbFrame.add($frame);\n                    if (dataFrame.video) {\n                        frameData.$wrap.append($videoPlay.clone());\n                    }\n                }\n            });\n        }\n\n        function callFit($img, measuresToFit) {\n            return $img && $img.length && fit($img, measuresToFit);\n        }\n\n        function stageFramePosition(indexes) {\n            eachIndex(indexes, 'stage', function (i, index, dataFrame, $frame, key, frameData) {\n                if (!$frame) return;\n\n                var normalizedIndex = normalizeIndex(index);\n                frameData.eq = normalizedIndex;\n\n                toDetach[STAGE_FRAME_KEY][normalizedIndex] = $frame.css($.extend({left: o_fade ? 0 : getPosByIndex(index, measures.w, opts.margin, repositionIndex)}, o_fade && getDuration(0)));\n\n                if (isDetached($frame[0])) {\n                    $frame.appendTo($stageShaft);\n                    unloadVideo(dataFrame.$video);\n                }\n\n                callFit(frameData.$img, measures);\n                callFit(frameData.$full, measures);\n\n                if ($frame.hasClass(stageFrameClass) && !($frame.attr('aria-hidden') === \"false\" && $frame.hasClass(activeClass))) {\n                    $frame.attr('aria-hidden', 'true');\n                }\n            });\n        }\n\n        function thumbsDraw(pos, loadFLAG) {\n            var leftLimit,\n                rightLimit,\n                exceedLimit;\n\n\n            if (o_nav !== 'thumbs' || isNaN(pos)) return;\n\n            leftLimit = -pos;\n            rightLimit = -pos + measures.nw;\n\n            if (opts.navdir === 'vertical') {\n                pos = pos - opts.thumbheight;\n                rightLimit = -pos + measures.h;\n            }\n\n            $navThumbFrame.each(function () {\n                var $this = $(this),\n                    thisData = $this.data(),\n                    eq = thisData.eq,\n                    getSpecialMeasures = function () {\n                        return {\n                            h: o_thumbSide2,\n                            w: thisData.w\n                        }\n                    },\n                    specialMeasures = getSpecialMeasures(),\n                    exceedLimit = opts.navdir === 'vertical' ?\n                    thisData.t > rightLimit : thisData.l > rightLimit;\n                specialMeasures.w = thisData.w;\n\n                if ((opts.navdir !== 'vertical' && thisData.l + thisData.w < leftLimit)\n                    || exceedLimit\n                    || callFit(thisData.$img, specialMeasures)) return;\n\n                loadFLAG && loadImg([eq], 'navThumb', getSpecialMeasures);\n            });\n        }\n\n        function frameAppend($frames, $shaft, type) {\n            if (!frameAppend[type]) {\n\n                var thumbsFLAG = type === 'nav' && o_navThumbs,\n                    left = 0,\n                    top = 0;\n\n                $shaft.append(\n                    $frames\n                        .filter(function () {\n                            var actual,\n                                $this = $(this),\n                                frameData = $this.data();\n                            for (var _i = 0, _l = data.length; _i < _l; _i++) {\n                                if (frameData.data === data[_i]) {\n                                    actual = true;\n                                    frameData.eq = _i;\n                                    break;\n                                }\n                            }\n                            return actual || $this.remove() && false;\n                        })\n                        .sort(function (a, b) {\n                            return $(a).data().eq - $(b).data().eq;\n                        })\n                        .each(function () {\n                            var $this = $(this),\n                                frameData = $this.data();\n                            UTIL.setThumbAttr($this, frameData.data.caption, \"aria-label\");\n                        })\n                        .each(function () {\n\n                            if (!thumbsFLAG) return;\n\n                            var $this = $(this),\n                                frameData = $this.data(),\n                                thumbwidth = Math.round(o_thumbSide2 * frameData.data.thumbratio) || o_thumbSide,\n                                thumbheight = Math.round(o_thumbSide / frameData.data.thumbratio) || o_thumbSide2;\n                            frameData.t = top;\n                            frameData.h = thumbheight;\n                            frameData.l = left;\n                            frameData.w = thumbwidth;\n\n                            $this.css({width: thumbwidth});\n\n                            top += thumbheight + opts.thumbmargin;\n                            left += thumbwidth + opts.thumbmargin;\n                        })\n                );\n\n                frameAppend[type] = true;\n            }\n        }\n\n        function getDirection(x) {\n            return x - stageLeft > measures.w / 3;\n        }\n\n        function disableDirrection(i) {\n            return !o_loop && (!(activeIndex + i) || !(activeIndex - size + i)) && !$videoPlaying;\n        }\n\n        function arrsUpdate() {\n            var disablePrev = disableDirrection(0),\n                disableNext = disableDirrection(1);\n            $arrPrev\n                .toggleClass(arrDisabledClass, disablePrev)\n                .attr(disableAttr(disablePrev, false));\n            $arrNext\n                .toggleClass(arrDisabledClass, disableNext)\n                .attr(disableAttr(disableNext, false));\n        }\n\n        function thumbArrUpdate() {\n            var isLeftDisable = false,\n                isRightDisable = false;\n            if (opts.navtype === 'thumbs' && !opts.loop) {\n                (activeIndex == 0) ? isLeftDisable = true : isLeftDisable = false;\n                (activeIndex == opts.data.length - 1) ? isRightDisable = true : isRightDisable = false;\n            }\n            if (opts.navtype === 'slides') {\n                var pos = readPosition($navShaft, opts.navdir);\n                pos >= navShaftTouchTail.max ? isLeftDisable = true : isLeftDisable = false;\n                pos <= Math.round(navShaftTouchTail.min) ? isRightDisable = true : isRightDisable = false;\n            }\n            $thumbArrLeft\n                .toggleClass(arrDisabledClass, isLeftDisable)\n                .attr(disableAttr(isLeftDisable, true));\n            $thumbArrRight\n                .toggleClass(arrDisabledClass, isRightDisable)\n                .attr(disableAttr(isRightDisable, true));\n        }\n\n        function stageWheelUpdate() {\n            if (stageWheelTail.ok) {\n                stageWheelTail.prevent = {'<': disableDirrection(0), '>': disableDirrection(1)};\n            }\n        }\n\n        function getNavFrameBounds($navFrame) {\n            var navFrameData = $navFrame.data(),\n                left,\n                top,\n                width,\n                height;\n\n            if (o_navThumbs) {\n                left = navFrameData.l;\n                top = navFrameData.t;\n                width = navFrameData.w;\n                height = navFrameData.h;\n            } else {\n                left = $navFrame.position().left;\n                width = $navFrame.width();\n            }\n\n            var horizontalBounds = {\n                c: left + width / 2,\n                min: -left + opts.thumbmargin * 10,\n                max: -left + measures.w - width - opts.thumbmargin * 10\n            };\n\n            var verticalBounds = {\n                c: top + height / 2,\n                min: -top + opts.thumbmargin * 10,\n                max: -top + measures.h - height - opts.thumbmargin * 10\n            };\n\n            return opts.navdir === 'vertical' ? verticalBounds : horizontalBounds;\n        }\n\n        function slideThumbBorder(time) {\n            var navFrameData = activeFrame[navFrameKey].data();\n            slide($thumbBorder, {\n                time: time * 1.2,\n                pos: (opts.navdir === 'vertical' ? navFrameData.t : navFrameData.l),\n                width: navFrameData.w,\n                height: navFrameData.h,\n                direction: opts.navdir\n            });\n        }\n\n        function slideNavShaft(options) {\n            var $guessNavFrame = data[options.guessIndex][navFrameKey],\n                typeOfAnimation = opts.navtype;\n\n            var overflowFLAG,\n                time,\n                minMax,\n                boundTop,\n                boundLeft,\n                l,\n                pos,\n                x;\n\n            if ($guessNavFrame) {\n                if (typeOfAnimation === 'thumbs') {\n                    overflowFLAG = navShaftTouchTail.min !== navShaftTouchTail.max;\n                    minMax = options.minMax || overflowFLAG && getNavFrameBounds(activeFrame[navFrameKey]);\n                    boundTop = overflowFLAG && (options.keep && slideNavShaft.t ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max));\n                    boundLeft = overflowFLAG && (options.keep && slideNavShaft.l ? slideNavShaft.l : minMaxLimit((options.coo || measures.nw / 2) - getNavFrameBounds($guessNavFrame).c, minMax.min, minMax.max));\n                    l = (opts.navdir === 'vertical' ? boundTop : boundLeft);\n                    pos = overflowFLAG && minMaxLimit(l, navShaftTouchTail.min, navShaftTouchTail.max) || 0;\n                    time = options.time * 1.1;\n                    slide($navShaft, {\n                        time: time,\n                        pos: pos,\n                        direction: opts.navdir,\n                        onEnd: function () {\n                            thumbsDraw(pos, true);\n                            thumbArrUpdate();\n                        }\n                    });\n\n                    setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));\n                    slideNavShaft.l = l;\n                } else {\n                    x = readPosition($navShaft, opts.navdir);\n                    time = options.time * 1.11;\n\n                    pos = validateSlidePos(opts, navShaftTouchTail, options.guessIndex, x, $guessNavFrame, $navWrap, opts.navdir);\n\n                    slide($navShaft, {\n                        time: time,\n                        pos: pos,\n                        direction: opts.navdir,\n                        onEnd: function () {\n                            thumbsDraw(pos, true);\n                            thumbArrUpdate();\n                        }\n                    });\n                    setShadow($nav, findShadowEdge(pos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));\n                }\n            }\n        }\n\n        function navUpdate() {\n            deactivateFrames(navFrameKey);\n            toDeactivate[navFrameKey].push(activeFrame[navFrameKey].addClass(activeClass).attr('data-active', true));\n        }\n\n        function deactivateFrames(key) {\n            var _toDeactivate = toDeactivate[key];\n\n            while (_toDeactivate.length) {\n                _toDeactivate.shift().removeClass(activeClass).attr('data-active', false);\n            }\n        }\n\n        function detachFrames(key) {\n            var _toDetach = toDetach[key];\n\n            $.each(activeIndexes, function (i, index) {\n                delete _toDetach[normalizeIndex(index)];\n            });\n\n            $.each(_toDetach, function (index, $frame) {\n                delete _toDetach[index];\n                $frame.detach();\n            });\n        }\n\n        function stageShaftReposition(skipOnEnd) {\n\n            repositionIndex = dirtyIndex = activeIndex;\n\n            var $frame = activeFrame[STAGE_FRAME_KEY];\n\n            if ($frame) {\n                deactivateFrames(STAGE_FRAME_KEY);\n                toDeactivate[STAGE_FRAME_KEY].push($frame.addClass(activeClass).attr('data-active', true));\n\n                if ($frame.hasClass(stageFrameClass)) {\n                    $frame.attr('aria-hidden', 'false');\n                }\n\n                skipOnEnd || that.showStage.onEnd(true);\n                stop($stageShaft, 0, true);\n\n                detachFrames(STAGE_FRAME_KEY);\n                stageFramePosition(activeIndexes);\n                setStageShaftMinmaxAndSnap();\n                setNavShaftMinMax();\n                addEnterUp($stageShaft[0], function () {\n                    if (!$fotorama.hasClass(fullscreenClass)) {\n                        that.requestFullScreen();\n                        $fullscreenIcon.focus();\n                    }\n                });\n            }\n        }\n\n        function extendMeasures(options, measuresArray) {\n            if (!options) return;\n\n            $.each(measuresArray, function (i, measures) {\n                if (!measures) return;\n\n                $.extend(measures, {\n                    width: options.width || measures.width,\n                    height: options.height,\n                    minwidth: options.minwidth,\n                    maxwidth: options.maxwidth,\n                    minheight: options.minheight,\n                    maxheight: options.maxheight,\n                    ratio: getRatio(options.ratio)\n                })\n            });\n        }\n\n        function triggerEvent(event, extra) {\n            $fotorama.trigger(_fotoramaClass + ':' + event, [that, extra]);\n        }\n\n        function onTouchStart() {\n            clearTimeout(onTouchEnd.t);\n            touchedFLAG = 1;\n\n            if (opts.stopautoplayontouch) {\n                that.stopAutoplay();\n            } else {\n                pausedAutoplayFLAG = true;\n            }\n        }\n\n        function onTouchEnd() {\n            if (!touchedFLAG) return;\n            if (!opts.stopautoplayontouch) {\n                releaseAutoplay();\n                changeAutoplay();\n            }\n\n            onTouchEnd.t = setTimeout(function () {\n                touchedFLAG = 0;\n            }, TRANSITION_DURATION + TOUCH_TIMEOUT);\n        }\n\n        function releaseAutoplay() {\n            pausedAutoplayFLAG = !!($videoPlaying || stoppedAutoplayFLAG);\n        }\n\n        function changeAutoplay() {\n\n            clearTimeout(changeAutoplay.t);\n            waitFor.stop(changeAutoplay.w);\n\n            if (!opts.autoplay || pausedAutoplayFLAG) {\n                if (that.autoplay) {\n                    that.autoplay = false;\n                    triggerEvent('stopautoplay');\n                }\n\n                return;\n            }\n\n            if (!that.autoplay) {\n                that.autoplay = true;\n                triggerEvent('startautoplay');\n            }\n\n            var _activeIndex = activeIndex;\n\n\n            var frameData = activeFrame[STAGE_FRAME_KEY].data();\n            changeAutoplay.w = waitFor(function () {\n                return frameData.state || _activeIndex !== activeIndex;\n            }, function () {\n                changeAutoplay.t = setTimeout(function () {\n\n                    if (pausedAutoplayFLAG || _activeIndex !== activeIndex) return;\n\n                    var _nextAutoplayIndex = nextAutoplayIndex,\n                        nextFrameData = data[_nextAutoplayIndex][STAGE_FRAME_KEY].data();\n\n                    changeAutoplay.w = waitFor(function () {\n\n                        return nextFrameData.state || _nextAutoplayIndex !== nextAutoplayIndex;\n                    }, function () {\n                        if (pausedAutoplayFLAG || _nextAutoplayIndex !== nextAutoplayIndex) return;\n                        that.show(o_loop ? getDirectionSign(!o_rtl) : nextAutoplayIndex);\n                    });\n                }, opts.autoplay);\n            });\n\n        }\n\n        that.startAutoplay = function (interval) {\n            if (that.autoplay) return this;\n            pausedAutoplayFLAG = stoppedAutoplayFLAG = false;\n            setAutoplayInterval(interval || opts.autoplay);\n            changeAutoplay();\n\n            return this;\n        };\n\n        that.stopAutoplay = function () {\n            if (that.autoplay) {\n                pausedAutoplayFLAG = stoppedAutoplayFLAG = true;\n                changeAutoplay();\n            }\n            return this;\n        };\n\n        that.showSlide = function (slideDir) {\n            var currentPosition = readPosition($navShaft, opts.navdir),\n                pos,\n                time = 500 * 1.1,\n                size = opts.navdir === 'horizontal' ? opts.thumbwidth : opts.thumbheight,\n                onEnd = function () {\n                    thumbArrUpdate();\n                };\n            if (slideDir === 'next') {\n                pos = currentPosition - (size + opts.margin) * thumbsPerSlide;\n            }\n            if (slideDir === 'prev') {\n                pos = currentPosition + (size + opts.margin) * thumbsPerSlide;\n            }\n            pos = validateRestrictions(pos, navShaftTouchTail);\n            thumbsDraw(pos, true);\n            slide($navShaft, {\n                time: time,\n                pos: pos,\n                direction: opts.navdir,\n                onEnd: onEnd\n            });\n        };\n\n        that.showWhileLongPress = function (options) {\n            if (that.longPress.singlePressInProgress) {\n                return;\n            }\n\n            var index = calcActiveIndex(options);\n            calcGlobalIndexes(index);\n            var time = calcTime(options) / 50;\n            var _activeFrame = activeFrame;\n            that.activeFrame = activeFrame = data[activeIndex];\n            var silent = _activeFrame === activeFrame && !options.user;\n\n            that.showNav(silent, options, time);\n\n            return this;\n        };\n\n        that.showEndLongPress = function (options) {\n            if (that.longPress.singlePressInProgress) {\n                return;\n            }\n\n            var index = calcActiveIndex(options);\n            calcGlobalIndexes(index);\n            var time = calcTime(options) / 50;\n            var _activeFrame = activeFrame;\n            that.activeFrame = activeFrame = data[activeIndex];\n\n            var silent = _activeFrame === activeFrame && !options.user;\n\n            that.showStage(silent, options, time);\n\n            showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;\n            lastActiveIndex = activeIndex;\n            return this;\n        };\n\n        function calcActiveIndex (options) {\n            var index;\n\n            if (typeof options !== 'object') {\n                index = options;\n                options = {};\n            } else {\n                index = options.index;\n            }\n\n            index = index === '>' ? dirtyIndex + 1 : index === '<' ? dirtyIndex - 1 : index === '<<' ? 0 : index === '>>' ? size - 1 : index;\n            index = isNaN(index) ? undefined : index;\n            index = typeof index === 'undefined' ? activeIndex || 0 : index;\n\n            return index;\n        }\n\n        function calcGlobalIndexes (index) {\n            that.activeIndex = activeIndex = edgeIndex(index);\n            prevIndex = getPrevIndex(activeIndex);\n            nextIndex = getNextIndex(activeIndex);\n            nextAutoplayIndex = normalizeIndex(activeIndex + (o_rtl ? -1 : 1));\n            activeIndexes = [activeIndex, prevIndex, nextIndex];\n\n            dirtyIndex = o_loop ? index : activeIndex;\n        }\n\n        function calcTime (options) {\n            var diffIndex = Math.abs(lastActiveIndex - dirtyIndex),\n                time = getNumber(options.time, function () {\n                    return Math.min(o_transitionDuration * (1 + (diffIndex - 1) / 12), o_transitionDuration * 2);\n                });\n\n            if (options.slow) {\n                time *= 10;\n            }\n\n            return time;\n        }\n\n        that.showStage = function (silent, options, time, e) {\n            if (e !== undefined && e.target.tagName == 'IFRAME') {\n                return;\n            }\n            unloadVideo($videoPlaying, activeFrame.i !== data[normalizeIndex(repositionIndex)].i);\n            frameDraw(activeIndexes, 'stage');\n            stageFramePosition(SLOW ? [dirtyIndex] : [dirtyIndex, getPrevIndex(dirtyIndex), getNextIndex(dirtyIndex)]);\n            updateTouchTails('go', true);\n\n            silent || triggerEvent('show', {\n                user: options.user,\n                time: time\n            });\n\n            pausedAutoplayFLAG = true;\n\n            var overPos = options.overPos;\n            var onEnd = that.showStage.onEnd = function (skipReposition) {\n                if (onEnd.ok) return;\n                onEnd.ok = true;\n\n                skipReposition || stageShaftReposition(true);\n\n                if (!silent) {\n                    triggerEvent('showend', {\n                        user: options.user\n                    });\n                }\n\n                if (!skipReposition && o_transition && o_transition !== opts.transition) {\n                    that.setOptions({transition: o_transition});\n                    o_transition = false;\n                    return;\n                }\n\n                updateFotoramaState();\n                loadImg(activeIndexes, 'stage');\n\n                updateTouchTails('go', false);\n                stageWheelUpdate();\n\n                stageCursor();\n                releaseAutoplay();\n                changeAutoplay();\n\n                if (that.fullScreen) {\n                    activeFrame[STAGE_FRAME_KEY].find('.' + imgFullClass).attr('aria-hidden', false);\n                    activeFrame[STAGE_FRAME_KEY].find('.' + imgClass).attr('aria-hidden', true)\n                } else {\n                    activeFrame[STAGE_FRAME_KEY].find('.' + imgFullClass).attr('aria-hidden', true);\n                    activeFrame[STAGE_FRAME_KEY].find('.' + imgClass).attr('aria-hidden', false)\n                }\n            };\n\n            if (!o_fade) {\n                slide($stageShaft, {\n                    pos: -getPosByIndex(dirtyIndex, measures.w, opts.margin, repositionIndex),\n                    overPos: overPos,\n                    time: time,\n                    onEnd: onEnd\n                });\n            } else {\n                var $activeFrame = activeFrame[STAGE_FRAME_KEY],\n                    $prevActiveFrame = data[lastActiveIndex] && activeIndex !== lastActiveIndex ? data[lastActiveIndex][STAGE_FRAME_KEY] : null;\n\n                fade($activeFrame, $prevActiveFrame, $stageFrame, {\n                    time: time,\n                    method: opts.transition,\n                    onEnd: onEnd\n                }, fadeStack);\n            }\n\n            arrsUpdate();\n        };\n\n        that.showNav = function(silent, options, time){\n            thumbArrUpdate();\n            if (o_nav) {\n                navUpdate();\n\n                var guessIndex = limitIndex(activeIndex + minMaxLimit(dirtyIndex - lastActiveIndex, -1, 1));\n                slideNavShaft({\n                    time: time,\n                    coo: guessIndex !== activeIndex && options.coo,\n                    guessIndex: typeof options.coo !== 'undefined' ? guessIndex : activeIndex,\n                    keep: silent\n                });\n                if (o_navThumbs) slideThumbBorder(time);\n            }\n        };\n\n        that.show = function (options, e) {\n            that.longPress.singlePressInProgress = true;\n\n            var index = calcActiveIndex(options);\n            calcGlobalIndexes(index);\n            var time = calcTime(options);\n            var _activeFrame = activeFrame;\n            that.activeFrame = activeFrame = data[activeIndex];\n\n            var silent = _activeFrame === activeFrame && !options.user;\n\n            that.showStage(silent, options, time, e);\n            that.showNav(silent, options, time);\n\n            showedFLAG = typeof lastActiveIndex !== 'undefined' && lastActiveIndex !== activeIndex;\n            lastActiveIndex = activeIndex;\n            that.longPress.singlePressInProgress = false;\n\n            return this;\n        };\n\n        that.requestFullScreen = function () {\n            if (o_allowFullScreen && !that.fullScreen) {\n\n                //check that this is not video\n                if(isVideo()) {\n                    return;\n                }\n\n                scrollTop = $WINDOW.scrollTop();\n                scrollLeft = $WINDOW.scrollLeft();\n\n                lockScroll($WINDOW);\n\n                updateTouchTails('x', true);\n\n                measuresStash = $.extend({}, measures);\n\n                $fotorama\n                    .addClass(fullscreenClass)\n                    .appendTo($BODY.addClass(_fullscreenClass));\n\n                $HTML.addClass(_fullscreenClass);\n\n                unloadVideo($videoPlaying, true, true);\n\n                that.fullScreen = true;\n\n                if (o_nativeFullScreen) {\n                    fullScreenApi.request(fotorama);\n                }\n\n                loadImg(activeIndexes, 'stage');\n                updateFotoramaState();\n                triggerEvent('fullscreenenter');\n                that.resize();\n\n                if (!('ontouchstart' in window)) {\n                    $fullscreenIcon.focus();\n                }\n            }\n\n            return this;\n        };\n\n        function cancelFullScreen() {\n            if (that.fullScreen) {\n                that.fullScreen = false;\n\n                if (FULLSCREEN) {\n                    fullScreenApi.cancel(fotorama);\n                }\n\n                $BODY.removeClass(_fullscreenClass);\n                $HTML.removeClass(_fullscreenClass);\n\n                $fotorama\n                    .removeClass(fullscreenClass)\n                    .insertAfter($anchor);\n\n                measures = $.extend({}, measuresStash);\n\n                unloadVideo($videoPlaying, true, true);\n\n                updateTouchTails('x', false);\n\n                that.resize();\n                loadImg(activeIndexes, 'stage');\n\n                lockScroll($WINDOW, scrollLeft, scrollTop);\n\n                triggerEvent('fullscreenexit');\n            }\n        }\n\n        that.cancelFullScreen = function () {\n            if (o_nativeFullScreen && fullScreenApi.is()) {\n                fullScreenApi.cancel(document);\n            } else {\n                cancelFullScreen();\n            }\n\n            return this;\n        };\n\n        that.toggleFullScreen = function () {\n            return that[(that.fullScreen ? 'cancel' : 'request') + 'FullScreen']();\n        };\n\n        that.resize = function (options) {\n            if (!data) return this;\n\n            var time = arguments[1] || 0,\n                setFLAG = arguments[2];\n\n            thumbsPerSlide = getThumbsInSlide($wrap, opts);\n            extendMeasures(!that.fullScreen ? optionsToLowerCase(options) : {\n                width: $(window).width(),\n                maxwidth: null,\n                minwidth: null,\n                height: $(window).height(),\n                maxheight: null,\n                minheight: null\n            }, [measures, setFLAG || that.fullScreen || opts]);\n\n            var width = measures.width,\n                height = measures.height,\n                ratio = measures.ratio,\n                windowHeight = $WINDOW.height() - (o_nav ? $nav.height() : 0);\n\n            if (measureIsValid(width)) {\n                $wrap.css({width: ''});\n                $stage.css({width: ''});\n                $stageShaft.css({width: ''});\n                $nav.css({width: ''});\n                $wrap.css({minWidth: measures.minwidth || 0, maxWidth: measures.maxwidth || MAX_WIDTH});\n\n                if (o_nav === 'dots') {\n                    $navWrap.hide();\n                }\n                width = measures.W = measures.w = $wrap.width();\n                measures.nw = o_nav && numberFromWhatever(opts.navwidth, width) || width;\n\n                $stageShaft.css({width: measures.w, marginLeft: (measures.W - measures.w) / 2});\n\n                height = numberFromWhatever(height, windowHeight);\n\n                height = height || (ratio && width / ratio);\n\n                if (height) {\n                    width = Math.round(width);\n                    height = measures.h = Math.round(minMaxLimit(height, numberFromWhatever(measures.minheight, windowHeight), numberFromWhatever(measures.maxheight, windowHeight)));\n                    $stage.css({'width': width, 'height': height});\n\n                    if (opts.navdir === 'vertical' && !that.fullscreen) {\n                        $nav.width(opts.thumbwidth + opts.thumbmargin * 2);\n                    }\n\n                    if (opts.navdir === 'horizontal' && !that.fullscreen) {\n                        $nav.height(opts.thumbheight + opts.thumbmargin * 2);\n                    }\n\n                    if (o_nav === 'dots') {\n                        $nav.width(width)\n                            .height('auto');\n                        $navWrap.show();\n                    }\n\n                    if (opts.navdir === 'vertical' && that.fullScreen) {\n                        $stage.css('height', $WINDOW.height());\n                    }\n\n                    if (opts.navdir === 'horizontal' && that.fullScreen) {\n                        $stage.css('height', $WINDOW.height() - $nav.height());\n                    }\n\n                    if (o_nav) {\n                        switch (opts.navdir) {\n                            case 'vertical':\n                                $navWrap.removeClass(navShafthorizontalClass);\n                                $navWrap.removeClass(navShaftListClass);\n                                $navWrap.addClass(navShaftVerticalClass);\n                                $nav\n                                    .stop()\n                                    .animate({height: measures.h, width: opts.thumbwidth}, time);\n                                break;\n                            case 'list':\n                                $navWrap.removeClass(navShaftVerticalClass);\n                                $navWrap.removeClass(navShafthorizontalClass);\n                                $navWrap.addClass(navShaftListClass);\n                                break;\n                            default:\n                                $navWrap.removeClass(navShaftVerticalClass);\n                                $navWrap.removeClass(navShaftListClass);\n                                $navWrap.addClass(navShafthorizontalClass);\n                                $nav\n                                    .stop()\n                                    .animate({width: measures.nw}, time);\n                                break;\n                        }\n\n                        stageShaftReposition();\n                        slideNavShaft({guessIndex: activeIndex, time: time, keep: true});\n                        if (o_navThumbs && frameAppend.nav) slideThumbBorder(time);\n                    }\n\n                    measuresSetFLAG = setFLAG || true;\n\n                    ready.ok = true;\n                    ready();\n                }\n            }\n\n            stageLeft = $stage.offset().left;\n            setStagePosition();\n\n            return this;\n        };\n\n        that.setOptions = function (options) {\n            $.extend(opts, options);\n            reset();\n            return this;\n        };\n\n        that.shuffle = function () {\n            data && shuffle(data) && reset();\n            return this;\n        };\n\n        function setShadow($el, edge) {\n            if (o_shadows) {\n                $el.removeClass(shadowsLeftClass + ' ' + shadowsRightClass);\n                $el.removeClass(shadowsTopClass + ' ' + shadowsBottomClass);\n                edge && !$videoPlaying && $el.addClass(edge.replace(/^|\\s/g, ' ' + shadowsClass + '--'));\n            }\n        }\n\n        that.longPress = {\n            threshold: 1,\n            count: 0,\n            thumbSlideTime: 20,\n            progress: function(){\n                if (!this.inProgress) {\n                    this.count++;\n                    this.inProgress = this.count > this.threshold;\n                }\n            },\n            end: function(){\n                if(this.inProgress) {\n                    this.isEnded = true\n                }\n            },\n            reset: function(){\n                this.count = 0;\n                this.inProgress = false;\n                this.isEnded = false;\n            }\n        };\n\n        that.destroy = function () {\n            that.cancelFullScreen();\n            that.stopAutoplay();\n\n            data = that.data = null;\n\n            appendElements();\n\n            activeIndexes = [];\n            detachFrames(STAGE_FRAME_KEY);\n\n            reset.ok = false;\n\n            return this;\n        };\n\n        /**\n         *\n         * @returns {jQuery.Fotorama}\n         */\n        that.playVideo = function () {\n            var dataFrame = activeFrame,\n                video = dataFrame.video,\n                _activeIndex = activeIndex;\n\n            if (typeof video === 'object' && dataFrame.videoReady) {\n                o_nativeFullScreen && that.fullScreen && that.cancelFullScreen();\n\n                waitFor(function () {\n                    return !fullScreenApi.is() || _activeIndex !== activeIndex;\n                }, function () {\n                    if (_activeIndex === activeIndex) {\n                        dataFrame.$video = dataFrame.$video || $(div(videoClass)).append(createVideoFrame(video));\n                        dataFrame.$video.appendTo(dataFrame[STAGE_FRAME_KEY]);\n\n                        $wrap.addClass(wrapVideoClass);\n                        $videoPlaying = dataFrame.$video;\n\n                        stageNoMove();\n\n                        $arrs.blur();\n                        $fullscreenIcon.blur();\n\n                        triggerEvent('loadvideo');\n                    }\n                });\n            }\n\n            return this;\n        };\n\n        that.stopVideo = function () {\n            unloadVideo($videoPlaying, true, true);\n            return this;\n        };\n\n        that.spliceByIndex = function (index, newImgObj) {\n            newImgObj.i = index + 1;\n            newImgObj.img && $.ajax({\n                url: newImgObj.img,\n                type: 'HEAD',\n                success: function () {\n                    data.splice(index, 1, newImgObj);\n                    reset();\n                }\n            });\n        };\n\n        function unloadVideo($video, unloadActiveFLAG, releaseAutoplayFLAG) {\n            if (unloadActiveFLAG) {\n                $wrap.removeClass(wrapVideoClass);\n                $videoPlaying = false;\n\n                stageNoMove();\n            }\n\n            if ($video && $video !== $videoPlaying) {\n                $video.remove();\n                triggerEvent('unloadvideo');\n            }\n\n            if (releaseAutoplayFLAG) {\n                releaseAutoplay();\n                changeAutoplay();\n            }\n        }\n\n        function toggleControlsClass(FLAG) {\n            $wrap.toggleClass(wrapNoControlsClass, FLAG);\n        }\n\n        function stageCursor(e) {\n            if (stageShaftTouchTail.flow) return;\n\n            var x = e ? e.pageX : stageCursor.x,\n                pointerFLAG = x && !disableDirrection(getDirection(x)) && opts.click;\n\n            if (stageCursor.p !== pointerFLAG\n                && $stage.toggleClass(pointerClass, pointerFLAG)) {\n                stageCursor.p = pointerFLAG;\n                stageCursor.x = x;\n            }\n        }\n\n        $stage.on('mousemove', stageCursor);\n\n        function clickToShow(showOptions, e) {\n            clearTimeout(clickToShow.t);\n\n            if (opts.clicktransition && opts.clicktransition !== opts.transition) {\n                setTimeout(function () {\n                    var _o_transition = opts.transition;\n\n                    that.setOptions({transition: opts.clicktransition});\n\n                    // now safe to pass base transition to o_transition, so that.show will restor it\n                    o_transition = _o_transition;\n                    // this timeout is here to prevent jerking in some browsers\n                    clickToShow.t = setTimeout(function () {\n                        that.show(showOptions);\n                    }, 10);\n                }, 0);\n            } else {\n                that.show(showOptions, e);\n            }\n        }\n\n        function onStageTap(e, toggleControlsFLAG) {\n            var target = e.target,\n                $target = $(target);\n            if ($target.hasClass(videoPlayClass)) {\n                that.playVideo();\n            } else if (target === fullscreenIcon) {\n                that.toggleFullScreen();\n            } else if ($videoPlaying) {\n                target === videoClose && unloadVideo($videoPlaying, true, true);\n            } else if (!$fotorama.hasClass(fullscreenClass)) {\n                that.requestFullScreen();\n            }\n        }\n\n        function updateTouchTails(key, value) {\n            stageShaftTouchTail[key] = navShaftTouchTail[key] = value;\n        }\n\n        stageShaftTouchTail = moveOnTouch($stageShaft, {\n            onStart: onTouchStart,\n            onMove: function (e, result) {\n                setShadow($stage, result.edge);\n            },\n            onTouchEnd: onTouchEnd,\n            onEnd: function (result) {\n                var toggleControlsFLAG;\n\n                setShadow($stage);\n                toggleControlsFLAG = (MS_POINTER && !hoverFLAG || result.touch) &&\n                    opts.arrows;\n\n                if ((result.moved || (toggleControlsFLAG && result.pos !== result.newPos && !result.control)) && result.$target[0] !== $fullscreenIcon[0]) {\n                    var index = getIndexByPos(result.newPos, measures.w, opts.margin, repositionIndex);\n\n                    that.show({\n                        index: index,\n                        time: o_fade ? o_transitionDuration : result.time,\n                        overPos: result.overPos,\n                        user: true\n                    });\n                } else if (!result.aborted && !result.control) {\n                    onStageTap(result.startEvent, toggleControlsFLAG);\n                }\n            },\n            timeLow: 1,\n            timeHigh: 1,\n            friction: 2,\n            select: '.' + selectClass + ', .' + selectClass + ' *',\n            $wrap: $stage,\n            direction: 'horizontal'\n\n        });\n\n        navShaftTouchTail = moveOnTouch($navShaft, {\n            onStart: onTouchStart,\n            onMove: function (e, result) {\n                setShadow($nav, result.edge);\n            },\n            onTouchEnd: onTouchEnd,\n            onEnd: function (result) {\n\n                function onEnd() {\n                    slideNavShaft.l = result.newPos;\n                    releaseAutoplay();\n                    changeAutoplay();\n                    thumbsDraw(result.newPos, true);\n                    thumbArrUpdate();\n                }\n\n                if (!result.moved) {\n                    var target = result.$target.closest('.' + navFrameClass, $navShaft)[0];\n                    target && onNavFrameClick.call(target, result.startEvent);\n                } else if (result.pos !== result.newPos) {\n                    pausedAutoplayFLAG = true;\n                    slide($navShaft, {\n                        time: result.time,\n                        pos: result.newPos,\n                        overPos: result.overPos,\n                        direction: opts.navdir,\n                        onEnd: onEnd\n                    });\n                    thumbsDraw(result.newPos);\n                    o_shadows && setShadow($nav, findShadowEdge(result.newPos, navShaftTouchTail.min, navShaftTouchTail.max, result.dir));\n                } else {\n                    onEnd();\n                }\n            },\n            timeLow: .5,\n            timeHigh: 2,\n            friction: 5,\n            $wrap: $nav,\n            direction: opts.navdir\n        });\n\n        stageWheelTail = wheel($stage, {\n            shift: true,\n            onEnd: function (e, direction) {\n                onTouchStart();\n                onTouchEnd();\n                that.show({index: direction, slow: e.altKey})\n            }\n        });\n\n        navWheelTail = wheel($nav, {\n            onEnd: function (e, direction) {\n                onTouchStart();\n                onTouchEnd();\n                var newPos = stop($navShaft) + direction * .25;\n                $navShaft.css(getTranslate(minMaxLimit(newPos, navShaftTouchTail.min, navShaftTouchTail.max), opts.navdir));\n                o_shadows && setShadow($nav, findShadowEdge(newPos, navShaftTouchTail.min, navShaftTouchTail.max, opts.navdir));\n                navWheelTail.prevent = {'<': newPos >= navShaftTouchTail.max, '>': newPos <= navShaftTouchTail.min};\n                clearTimeout(navWheelTail.t);\n                navWheelTail.t = setTimeout(function () {\n                    slideNavShaft.l = newPos;\n                    thumbsDraw(newPos, true)\n                }, TOUCH_TIMEOUT);\n                thumbsDraw(newPos);\n            }\n        });\n\n        $wrap.hover(\n            function () {\n                setTimeout(function () {\n                    if (touchedFLAG) return;\n                    toggleControlsClass(!(hoverFLAG = true));\n                }, 0);\n            },\n            function () {\n                if (!hoverFLAG) return;\n                toggleControlsClass(!(hoverFLAG = false));\n            }\n        );\n\n        function onNavFrameClick(e) {\n            var index = $(this).data().eq;\n\n            if (opts.navtype === 'thumbs') {\n                clickToShow({index: index, slow: e.altKey, user: true, coo: e._x - $nav.offset().left});\n            } else {\n                clickToShow({index: index, slow: e.altKey, user: true});\n            }\n        }\n\n        function onArrClick(e) {\n            clickToShow({index: $arrs.index(this) ? '>' : '<', slow: e.altKey, user: true});\n        }\n\n        smartClick($arrs, function (e) {\n            stopEvent(e);\n            onArrClick.call(this, e);\n        }, {\n            onStart: function () {\n                onTouchStart();\n                stageShaftTouchTail.control = true;\n            },\n            onTouchEnd: onTouchEnd\n        });\n\n        smartClick($thumbArrLeft, function (e) {\n            stopEvent(e);\n            if (opts.navtype === 'thumbs') {\n\n                that.show('<');\n            } else {\n                that.showSlide('prev')\n            }\n        });\n\n        smartClick($thumbArrRight, function (e) {\n            stopEvent(e);\n            if (opts.navtype === 'thumbs') {\n                that.show('>');\n            } else {\n                that.showSlide('next')\n            }\n\n        });\n\n\n        function addFocusOnControls(el) {\n            addFocus(el, function () {\n                setTimeout(function () {\n                    lockScroll($stage);\n                }, 0);\n                toggleControlsClass(false);\n            });\n        }\n\n        $arrs.each(function () {\n            addEnterUp(this, function (e) {\n                onArrClick.call(this, e);\n            });\n            addFocusOnControls(this);\n        });\n\n        addEnterUp(fullscreenIcon, function () {\n            if ($fotorama.hasClass(fullscreenClass)) {\n                that.cancelFullScreen();\n                $stageShaft.focus();\n            } else {\n                that.requestFullScreen();\n                $fullscreenIcon.focus();\n            }\n\n        });\n        addFocusOnControls(fullscreenIcon);\n\n        function reset() {\n            setData();\n            setOptions();\n\n            if (!reset.i) {\n                reset.i = true;\n                // Only once\n                var _startindex = opts.startindex;\n                activeIndex = repositionIndex = dirtyIndex = lastActiveIndex = startIndex = edgeIndex(_startindex) || 0;\n                /*(o_rtl ? size - 1 : 0)*///;\n            }\n\n            if (size) {\n                if (changeToRtl()) return;\n\n                if ($videoPlaying) {\n                    unloadVideo($videoPlaying, true);\n                }\n\n                activeIndexes = [];\n\n                if (!isVideo()) {\n                    detachFrames(STAGE_FRAME_KEY);\n                }\n\n                reset.ok = true;\n\n                that.show({index: activeIndex, time: 0});\n                that.resize();\n            } else {\n                that.destroy();\n            }\n        }\n\n        function changeToRtl() {\n\n            if (!changeToRtl.f === o_rtl) {\n                changeToRtl.f = o_rtl;\n                activeIndex = size - 1 - activeIndex;\n                that.reverse();\n\n                return true;\n            }\n        }\n\n        $.each('load push pop shift unshift reverse sort splice'.split(' '), function (i, method) {\n            that[method] = function () {\n                data = data || [];\n                if (method !== 'load') {\n                    Array.prototype[method].apply(data, arguments);\n                } else if (arguments[0] && typeof arguments[0] === 'object' && arguments[0].length) {\n                    data = clone(arguments[0]);\n                }\n                reset();\n                return that;\n            }\n        });\n\n        function ready() {\n            if (ready.ok) {\n                ready.ok = false;\n                triggerEvent('ready');\n            }\n        }\n\n        reset();\n    };\n    $.fn.fotorama = function (opts) {\n        return this.each(function () {\n            var that = this,\n                $fotorama = $(this),\n                fotoramaData = $fotorama.data(),\n                fotorama = fotoramaData.fotorama;\n\n            if (!fotorama) {\n                waitFor(function () {\n                    return !isHidden(that);\n                }, function () {\n                    fotoramaData.urtext = $fotorama.html();\n                    new $.Fotorama($fotorama,\n                        $.extend(\n                            {},\n                            OPTIONS,\n                            window.fotoramaDefaults,\n                            opts,\n                            fotoramaData\n                        )\n                    );\n                });\n            } else {\n                fotorama.setOptions(opts, true);\n            }\n        });\n    };\n    $.Fotorama.instances = [];\n\n    function calculateIndexes() {\n        $.each($.Fotorama.instances, function (index, instance) {\n            instance.index = index;\n        });\n    }\n\n    function addInstance(instance) {\n        $.Fotorama.instances.push(instance);\n        calculateIndexes();\n    }\n\n    function hideInstance(instance) {\n        $.Fotorama.instances.splice(instance.index, 1);\n        calculateIndexes();\n    }\n\n    $.Fotorama.cache = {};\n    $.Fotorama.measures = {};\n    $ = $ || {};\n    $.Fotorama = $.Fotorama || {};\n    $.Fotorama.jst = $.Fotorama.jst || {};\n\n    $.Fotorama.jst.dots = function (v) {\n        var __t, __p = '', __e = _.escape;\n        __p += '<div class=\"fotorama__nav__frame fotorama__nav__frame--dot\" tabindex=\"0\" role=\"button\" data-gallery-role=\"nav-frame\" data-nav-type=\"thumb\" aria-label>\\r\\n    <div class=\"fotorama__dot\"></div>\\r\\n</div>';\n        return __p\n    };\n\n    $.Fotorama.jst.frameCaption = function (v) {\n        var __t, __p = '', __e = _.escape;\n        __p += '<div class=\"fotorama__caption\" aria-hidden=\"true\">\\r\\n    <div class=\"fotorama__caption__wrap\" id=\"' +\n            ((__t = ( v.labelledby )) == null ? '' : __t) +\n            '\">' +\n            ((__t = ( v.caption )) == null ? '' : __t) +\n            '</div>\\r\\n</div>\\r\\n';\n        return __p\n    };\n\n    $.Fotorama.jst.style = function (v) {\n        var __t, __p = '', __e = _.escape;\n        __p += '.fotorama' +\n            ((__t = ( v.s )) == null ? '' : __t) +\n            ' .fotorama__nav--thumbs .fotorama__nav__frame{\\r\\npadding:' +\n            ((__t = ( v.m )) == null ? '' : __t) +\n            'px;\\r\\nheight:' +\n            ((__t = ( v.h )) == null ? '' : __t) +\n            'px}\\r\\n.fotorama' +\n            ((__t = ( v.s )) == null ? '' : __t) +\n            ' .fotorama__thumb-border{\\r\\nheight:' +\n            ((__t = ( v.h )) == null ? '' : __t) +\n            'px;\\r\\nborder-width:' +\n            ((__t = ( v.b )) == null ? '' : __t) +\n            'px;\\r\\nmargin-top:' +\n            ((__t = ( v.m )) == null ? '' : __t) +\n            'px}';\n        return __p\n    };\n\n    $.Fotorama.jst.thumb = function (v) {\n        var __t, __p = '', __e = _.escape;\n        __p += '<div class=\"fotorama__nav__frame fotorama__nav__frame--thumb\" tabindex=\"0\" role=\"button\" data-gallery-role=\"nav-frame\" data-nav-type=\"thumb\" aria-label>\\r\\n    <div class=\"fotorama__thumb\">\\r\\n    </div>\\r\\n</div>';\n        return __p\n    };\n})(window, document, location, typeof jQuery !== 'undefined' && jQuery);\n","Magento_CardinalCommerce/js/cardinal-client.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiClass',\n    'Magento_CardinalCommerce/js/cardinal-factory',\n    'Magento_Checkout/js/model/quote',\n    'mage/translate'\n], function ($, Class, cardinalFactory, quote, $t) {\n    'use strict';\n\n    return {\n        /**\n         * Starts Cardinal Consumer Authentication\n         *\n         * @param {Object} cardData\n         * @return {jQuery.Deferred}\n         */\n        startAuthentication: function (cardData) {\n            var deferred = $.Deferred();\n\n            if (this.cardinalClient) {\n                this._startAuthentication(deferred, cardData);\n            } else {\n                cardinalFactory(this.getEnvironment())\n                    .done(function (client) {\n                        this.cardinalClient = client;\n                        this._startAuthentication(deferred, cardData);\n                    }.bind(this));\n            }\n\n            return deferred.promise();\n        },\n\n        /**\n         * Cardinal Consumer Authentication\n         *\n         * @param {jQuery.Deferred} deferred\n         * @param {Object} cardData\n         */\n        _startAuthentication: function (deferred, cardData) {\n            //this.cardinalClient.configure({ logging: { level: 'verbose' } });\n            this.cardinalClient.on('payments.validated', function (data, jwt) {\n                if (data.ErrorNumber !== 0) {\n                    deferred.reject(data.ErrorDescription);\n                } else if ($.inArray(data.ActionCode, ['FAILURE', 'ERROR']) !== -1) {\n                    deferred.reject($t('Authentication Failed. Please try again with another form of payment.'));\n                } else {\n                    deferred.resolve(jwt);\n                }\n                this.cardinalClient.off('payments.validated');\n            }.bind(this));\n\n            this.cardinalClient.on('payments.setupComplete', function () {\n                this.cardinalClient.start('cca', this.getRequestOrderObject(cardData));\n                this.cardinalClient.off('payments.setupComplete');\n            }.bind(this));\n\n            this.cardinalClient.setup('init', {\n                jwt: this.getRequestJWT()\n            });\n        },\n\n        /**\n         * Returns request order object.\n         *\n         * The request order object is structured object that is used to pass data\n         * to Cardinal that describes an order you'd like to process.\n         *\n         * If you pass a request object in both the JWT and the browser,\n         * Cardinal will merge the objects together where the browser overwrites\n         * the JWT object as it is considered the most recently captured data.\n         *\n         * @param {Object} cardData\n         * @returns {Object}\n         */\n        getRequestOrderObject: function (cardData) {\n            var totalAmount = quote.totals()['base_grand_total'],\n                currencyCode = quote.totals()['base_currency_code'],\n                billingAddress = quote.billingAddress(),\n                requestObject;\n\n            requestObject = {\n                OrderDetails: {\n                    Amount: totalAmount * 100,\n                    CurrencyCode: currencyCode\n                },\n                Consumer: {\n                    Account: {\n                        AccountNumber: cardData.accountNumber,\n                        ExpirationMonth: cardData.expMonth,\n                        ExpirationYear: cardData.expYear,\n                        CardCode: cardData.cardCode\n                    },\n                    BillingAddress: {\n                        FirstName: billingAddress.firstname,\n                        LastName: billingAddress.lastname,\n                        Address1: billingAddress.street[0],\n                        Address2: billingAddress.street[1],\n                        City: billingAddress.city,\n                        State: billingAddress.region,\n                        PostalCode: billingAddress.postcode,\n                        CountryCode: billingAddress.countryId,\n                        Phone1: billingAddress.telephone\n                    }\n                }\n            };\n\n            return requestObject;\n        },\n\n        /**\n         * Returns request JWT\n         * @returns {String}\n         */\n        getRequestJWT: function () {\n            return window.checkoutConfig.cardinal.requestJWT;\n        },\n\n        /**\n         * Returns type of environment\n         * @returns {String}\n         */\n        getEnvironment: function () {\n            return window.checkoutConfig.cardinal.environment;\n        }\n    };\n});\n","Magento_CardinalCommerce/js/cardinal-factory.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    return function (environment) {\n        var deferred = $.Deferred(),\n            dependency = 'cardinaljs';\n\n        if (environment === 'sandbox') {\n            dependency = 'cardinaljsSandbox';\n        }\n\n        require(\n            [dependency],\n            function (Cardinal) {\n                deferred.resolve(Cardinal);\n            },\n            deferred.reject\n        );\n\n        return deferred.promise();\n    };\n});\n","js-storage/storage-wrapper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'js-storage/js.storage'\n], function ($, storage) {\n    'use strict';\n\n    if (window.cookieStorage) {\n        var cookiesConfig = window.cookiesConfig || {};\n\n        $.extend(window.cookieStorage, {\n            _secure: !!cookiesConfig.secure,\n            _samesite: cookiesConfig.samesite ? cookiesConfig.samesite : 'lax',\n\n            /**\n             * Set value under name\n             * @param {String} name\n             * @param {String} value\n             * @param {Object} [options]\n             */\n            setItem: function (name, value, options) {\n                var _default = {\n                    expires: this._expires,\n                    path: this._path,\n                    domain: this._domain,\n                    secure: this._secure,\n                    samesite: this._samesite\n                };\n\n                $.cookie(this._prefix + name, value, $.extend(_default, options || {}));\n            },\n\n            /**\n             * Set default options\n             * @param {Object} c\n             * @returns {storage}\n             */\n            setConf: function (c) {\n                if (c.path) {\n                    this._path = c.path;\n                }\n\n                if (c.domain) {\n                    this._domain = c.domain;\n                }\n\n                if (c.expires) {\n                    this._expires = c.expires;\n                }\n\n                if (typeof c.secure !== 'undefined') {\n                    this._secure = c.secure;\n                }\n\n                if (typeof c.samesite !== 'undefined') {\n                    this._samesite = c.samesite;\n                }\n\n                return this;\n            }\n        });\n    }\n\n    $.alwaysUseJsonInStorage = $.alwaysUseJsonInStorage || storage.alwaysUseJsonInStorage;\n    $.cookieStorage = $.cookieStorage || storage.cookieStorage;\n    $.initNamespaceStorage = $.initNamespaceStorage || storage.initNamespaceStorage;\n    $.localStorage = $.localStorage || storage.localStorage;\n    $.namespaceStorages = $.namespaceStorages || storage.namespaceStorages;\n    $.removeAllStorages = $.removeAllStorages || storage.removeAllStorages;\n    $.sessionStorage = $.sessionStorage || storage.sessionStorage;\n});\n","js-storage/js.storage.js":"/*\n * JS Storage Plugin\n *\n * Copyright (c) 2019 Julien Maurel\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/mit-license.php\n *\n * Project home:\n * https://github.com/julien-maurel/js-storage\n *\n * Version: 1.1.0\n */\n(function (factory) {\n    var registeredInModuleLoader = false;\n    if (typeof define === 'function' && define.amd) {\n        define(['jquery', 'jquery/jquery.cookie'], factory);\n        registeredInModuleLoader = true;\n    }\n    if (typeof exports === 'object') {\n        module.exports = factory();\n        registeredInModuleLoader = true;\n    }\n    if (!registeredInModuleLoader) {\n        var OldStorages = window.Storages;\n        var api = window.Storages = factory();\n        api.noConflict = function () {\n            window.Storages = OldStorages;\n            return api;\n        };\n    }\n}(function () {\n    // Variables used by utilities functions (like isPlainObject...)\n    var class2type = {};\n    var toString = class2type.toString;\n    var hasOwn = class2type.hasOwnProperty;\n    var fnToString = hasOwn.toString;\n    var ObjectFunctionString = fnToString.call(Object);\n    var getProto = Object.getPrototypeOf;\n    var apis = {};\n\n    // Prefix to use with cookie fallback\n    var cookie_local_prefix = \"ls_\";\n    var cookie_session_prefix = \"ss_\";\n\n    // Get items from a storage\n    function _get() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], vi, ret, tmp, i, j;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        } else if (Array.isArray(a0)) {\n            // If second argument is an array, return an object with value of storage for each item in this array\n            ret = {};\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    vi = a0[i];\n                    try {\n                        ret[vi] = JSON.parse(s.getItem(vi));\n                    } catch (e) {\n                        ret[vi] = s.getItem(vi);\n                    }\n                }\n            }\n            return ret;\n        } else if (l == 1) {\n            // If only 1 argument, return value directly\n            try {\n                return JSON.parse(s.getItem(a0));\n            } catch (e) {\n                return s.getItem(a0);\n            }\n        } else {\n            // If more than 1 argument, parse storage to retrieve final value to return it\n            // Get first level\n            try {\n                ret = JSON.parse(s.getItem(a0));\n                if (!ret) {\n                    throw new ReferenceError(a0 + ' is not defined in this storage');\n                }\n            } catch (e) {\n                throw new ReferenceError(a0 + ' is not defined in this storage');\n            }\n            // Parse next levels\n            for (i = 1; i < l - 1; i++) {\n                ret = ret[a[i]];\n                if (ret === undefined) {\n                    throw new ReferenceError([].slice.call(a, 0, i + 1).join('.') + ' is not defined in this storage');\n                }\n            }\n            // If last argument is an array, return an object with value for each item in this array\n            // Else return value normally\n            if (Array.isArray(a[i])) {\n                tmp = ret;\n                ret = {};\n                for (j in a[i]) {\n                    if (a[i].hasOwnProperty(j)) {\n                        ret[a[i][j]] = tmp[a[i][j]];\n                    }\n                }\n                return ret;\n            } else {\n                return ret[a[i]];\n            }\n        }\n    }\n\n    // Set items of a storage\n    function _set() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], a1 = a[1], vi, to_store = isNaN(a1) ? {} : [], type, tmp, i;\n        if (l < 1 || !_isPlainObject(a0) && l < 2) {\n            throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n        } else if (_isPlainObject(a0)) {\n            // If first argument is an object, set values of storage for each property of this object\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    vi = a0[i];\n                    if (!_isPlainObject(vi) && !this.alwaysUseJson) {\n                        s.setItem(i, vi);\n                    } else {\n                        s.setItem(i, JSON.stringify(vi));\n                    }\n                }\n            }\n            return a0;\n        } else if (l == 2) {\n            // If only 2 arguments, set value of storage directly\n            if (typeof a1 === 'object' || this.alwaysUseJson) {\n                s.setItem(a0, JSON.stringify(a1));\n            } else {\n                s.setItem(a0, a1);\n            }\n            return a1;\n        } else {\n            // If more than 3 arguments, parse storage to retrieve final node and set value\n            // Get first level\n            try {\n                tmp = s.getItem(a0);\n                if (tmp != null) {\n                    to_store = JSON.parse(tmp);\n                }\n            } catch (e) {\n            }\n            tmp = to_store;\n            // Parse next levels and set value\n            for (i = 1; i < l - 2; i++) {\n                vi = a[i];\n                type = isNaN(a[i + 1]) ? \"object\" : \"array\";\n                if (!tmp[vi] || type == \"object\" && !_isPlainObject(tmp[vi]) || type == \"array\" && !Array.isArray(tmp[vi])) {\n                    if (type == \"array\") tmp[vi] = [];\n                    else tmp[vi] = {};\n                }\n                tmp = tmp[vi];\n            }\n            tmp[a[i]] = a[i + 1];\n            s.setItem(a0, JSON.stringify(to_store));\n            return to_store;\n        }\n    }\n\n    // Remove items from a storage\n    function _remove() {\n        var storage = this._type, l = arguments.length, s = window[storage], a = arguments, a0 = a[0], to_store, tmp, i, j;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        } else if (Array.isArray(a0)) {\n            // If first argument is an array, remove values from storage for each item of this array\n            for (i in a0) {\n                if (a0.hasOwnProperty(i)) {\n                    s.removeItem(a0[i]);\n                }\n            }\n            return true;\n        } else if (l == 1) {\n            // If only 2 arguments, remove value from storage directly\n            s.removeItem(a0);\n            return true;\n        } else {\n            // If more than 2 arguments, parse storage to retrieve final node and remove value\n            // Get first level\n            try {\n                to_store = tmp = JSON.parse(s.getItem(a0));\n            } catch (e) {\n                throw new ReferenceError(a0 + ' is not defined in this storage');\n            }\n            // Parse next levels and remove value\n            for (i = 1; i < l - 1; i++) {\n                tmp = tmp[a[i]];\n                if (tmp === undefined) {\n                    throw new ReferenceError([].slice.call(a, 1, i).join('.') + ' is not defined in this storage');\n                }\n            }\n            // If last argument is an array,remove value for each item in this array\n            // Else remove value normally\n            if (Array.isArray(a[i])) {\n                for (j in a[i]) {\n                    if (a[i].hasOwnProperty(j)) {\n                        delete tmp[a[i][j]];\n                    }\n                }\n            } else {\n                delete tmp[a[i]];\n            }\n            s.setItem(a0, JSON.stringify(to_store));\n            return true;\n        }\n    }\n\n    // Remove all items from a storage\n    function _removeAll(reinit_ns) {\n        var keys = _keys.call(this), i;\n        for (i in keys) {\n            if (keys.hasOwnProperty(i)) {\n                _remove.call(this, keys[i]);\n            }\n        }\n        // Reinitialize all namespace storages\n        if (reinit_ns) {\n            for (i in apis.namespaceStorages) {\n                if (apis.namespaceStorages.hasOwnProperty(i)) {\n                    _createNamespace(i);\n                }\n            }\n        }\n    }\n\n    // Check if items of a storage are empty\n    function _isEmpty() {\n        var l = arguments.length, a = arguments, a0 = a[0], i;\n        if (l == 0) {\n            // If no argument, test if storage is empty\n            return (_keys.call(this).length == 0);\n        } else if (Array.isArray(a0)) {\n            // If first argument is an array, test each item of this array and return true only if all items are empty\n            for (i = 0; i < a0.length; i++) {\n                if (!_isEmpty.call(this, a0[i])) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            // If at least 1 argument, try to get value and test it\n            try {\n                var v = _get.apply(this, arguments);\n                // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n                if (!Array.isArray(a[l - 1])) {\n                    v = {'totest': v};\n                }\n                for (i in v) {\n                    if (v.hasOwnProperty(i) && !(\n                        (_isPlainObject(v[i]) && _isEmptyObject(v[i])) ||\n                        (Array.isArray(v[i]) && !v[i].length) ||\n                        (typeof v[i] !== 'boolean' && !v[i])\n                    )) {\n                        return false;\n                    }\n                }\n                return true;\n            } catch (e) {\n                return true;\n            }\n        }\n    }\n\n    // Check if items of a storage exist\n    function _isSet() {\n        var l = arguments.length, a = arguments, a0 = a[0], i;\n        if (l < 1) {\n            throw new Error('Minimum 1 argument must be given');\n        }\n        if (Array.isArray(a0)) {\n            // If first argument is an array, test each item of this array and return true only if all items exist\n            for (i = 0; i < a0.length; i++) {\n                if (!_isSet.call(this, a0[i])) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            // For other case, try to get value and test it\n            try {\n                var v = _get.apply(this, arguments);\n                // Convert result to an object (if last argument is an array, _get return already an object) and test each item\n                if (!Array.isArray(a[l - 1])) {\n                    v = {'totest': v};\n                }\n                for (i in v) {\n                    if (v.hasOwnProperty(i) && !(v[i] !== undefined && v[i] !== null)) {\n                        return false;\n                    }\n                }\n                return true;\n            } catch (e) {\n                return false;\n            }\n        }\n    }\n\n    // Get keys of a storage or of an item of the storage\n    function _keys() {\n        var storage = this._type, l = arguments.length, s = window[storage], keys = [], o = {};\n        // If at least 1 argument, get value from storage to retrieve keys\n        // Else, use storage to retrieve keys\n        if (l > 0) {\n            o = _get.apply(this, arguments);\n        } else {\n            o = s;\n        }\n        if (o && o._cookie) {\n            // If storage is a cookie, use js-cookie to retrieve keys\n            var cookies = Cookies.get();\n            for (var key in cookies) {\n                if (cookies.hasOwnProperty(key) && key != '') {\n                    keys.push(key.replace(o._prefix, ''));\n                }\n            }\n        } else {\n            for (var i in o) {\n                if (o.hasOwnProperty(i)) {\n                    keys.push(i);\n                }\n            }\n        }\n        return keys;\n    }\n\n    // Create new namespace storage\n    function _createNamespace(name) {\n        if (!name || typeof name != \"string\") {\n            throw new Error('First parameter must be a string');\n        }\n        if (storage_available) {\n            if (!window.localStorage.getItem(name)) {\n                window.localStorage.setItem(name, '{}');\n            }\n            if (!window.sessionStorage.getItem(name)) {\n                window.sessionStorage.setItem(name, '{}');\n            }\n        } else {\n            if (!window.localCookieStorage.getItem(name)) {\n                window.localCookieStorage.setItem(name, '{}');\n            }\n            if (!window.sessionCookieStorage.getItem(name)) {\n                window.sessionCookieStorage.setItem(name, '{}');\n            }\n        }\n        var ns = {\n            localStorage: _extend({}, apis.localStorage, {_ns: name}),\n            sessionStorage: _extend({}, apis.sessionStorage, {_ns: name})\n        };\n        if (cookies_available) {\n            if (!window.cookieStorage.getItem(name)) {\n                window.cookieStorage.setItem(name, '{}');\n            }\n            ns.cookieStorage = _extend({}, apis.cookieStorage, {_ns: name});\n        }\n        apis.namespaceStorages[name] = ns;\n        return ns;\n    }\n\n    // Test if storage is natively available on browser\n    function _testStorage(name) {\n        var foo = 'jsapi';\n        try {\n            if (!window[name]) {\n                return false;\n            }\n            window[name].setItem(foo, foo);\n            window[name].removeItem(foo);\n            return true;\n        } catch (e) {\n            return false;\n        }\n    }\n\n    // Test if a variable is a plain object (from jQuery)\n    function _isPlainObject(obj) {\n        var proto, Ctor;\n\n        // Detect obvious negatives\n        // Use toString instead of jQuery.type to catch host objects\n        if (!obj || toString.call(obj) !== \"[object Object]\") {\n            return false;\n        }\n\n        proto = getProto(obj);\n\n        // Objects with no prototype (e.g., `Object.create( null )`) are plain\n        if (!proto) {\n            return true;\n        }\n\n        // Objects with prototype are plain iff they were constructed by a global Object function\n        Ctor = hasOwn.call(proto, \"constructor\") && proto.constructor;\n        return typeof Ctor === \"function\" && fnToString.call(Ctor) === ObjectFunctionString;\n    }\n\n    // Test if a variable is an empty object (from jQuery)\n    function _isEmptyObject(obj) {\n        var name;\n\n        for (name in obj) {\n            return false;\n        }\n        return true;\n    }\n\n    // Merge objects\n    function _extend() {\n        var i = 1;\n        var result = arguments[0];\n        for (; i < arguments.length; i++) {\n            var attributes = arguments[i];\n            for (var key in attributes) {\n                if (attributes.hasOwnProperty(key)) {\n                    result[key] = attributes[key];\n                }\n            }\n        }\n        return result;\n    }\n\n    // Check if storages are natively available on browser and check is js-cookie is present\n    var storage_available = _testStorage('localStorage');\n    var cookies_available = typeof Cookies !== 'undefined';\n\n    // Namespace object\n    var storage = {\n        _type: '',\n        _ns: '',\n        _callMethod: function (f, a) {\n            a = Array.prototype.slice.call(a);\n            var p = [], a0 = a[0];\n            if (this._ns) {\n                p.push(this._ns);\n            }\n            if (typeof a0 === 'string' && a0.indexOf('.') !== -1) {\n                a.shift();\n                [].unshift.apply(a, a0.split('.'));\n            }\n            [].push.apply(p, a);\n            return f.apply(this, p);\n        },\n        // Define if plugin always use JSON to store values (even to store simple values like string, int...) or not\n        alwaysUseJson: false,\n        // Get items. If no parameters and storage have a namespace, return all namespace\n        get: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_get, arguments);\n        },\n        // Set items\n        set: function () {\n            var l = arguments.length, a = arguments, a0 = a[0];\n            if (l < 1 || !_isPlainObject(a0) && l < 2) {\n                throw new Error('Minimum 2 arguments must be given or first parameter must be an object');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            // If first argument is an object and storage is a namespace storage, set values individually\n            if (_isPlainObject(a0) && this._ns) {\n                for (var i in a0) {\n                    if (a0.hasOwnProperty(i)) {\n                        this._callMethod(_set, [i, a0[i]]);\n                    }\n                }\n                return a0;\n            } else {\n                var r = this._callMethod(_set, a);\n                if (this._ns) {\n                    return r[a0.split('.')[0]];\n                } else {\n                    return r;\n                }\n            }\n        },\n        // Delete items\n        remove: function () {\n            if (arguments.length < 1) {\n                throw new Error('Minimum 1 argument must be given');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_remove, arguments);\n        },\n        // Delete all items\n        removeAll: function (reinit_ns) {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            if (this._ns) {\n                this._callMethod(_set, [{}]);\n                return true;\n            } else {\n                return this._callMethod(_removeAll, [reinit_ns]);\n            }\n        },\n        // Items empty\n        isEmpty: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_isEmpty, arguments);\n        },\n        // Items exists\n        isSet: function () {\n            if (arguments.length < 1) {\n                throw new Error('Minimum 1 argument must be given');\n            }\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_isSet, arguments);\n        },\n        // Get keys of items\n        keys: function () {\n            if (!storage_available && !cookies_available){\n                return null;\n            }\n            return this._callMethod(_keys, arguments);\n        }\n    };\n\n    // Use js-cookie for compatibility with old browsers and give access to cookieStorage\n    if (cookies_available) {\n        // sessionStorage is valid for one window/tab. To simulate that with cookie, we set a name for the window and use it for the name of the cookie\n        if (!window.name) {\n            window.name = Math.floor(Math.random() * 100000000);\n        }\n        var cookie_storage = {\n            _cookie: true,\n            _prefix: '',\n            _expires: null,\n            _path: null,\n            _domain: null,\n            _secure: false,\n            setItem: function (n, v) {\n                Cookies.set(this._prefix + n, v, {expires: this._expires, path: this._path, domain: this._domain, secure: this._secure});\n            },\n            getItem: function (n) {\n                return Cookies.get(this._prefix + n);\n            },\n            removeItem: function (n) {\n                return Cookies.remove(this._prefix + n, {path: this._path});\n            },\n            clear: function () {\n                var cookies = Cookies.get();\n                for (var key in cookies) {\n                    if (cookies.hasOwnProperty(key) && key != '') {\n                        if (!this._prefix && key.indexOf(cookie_local_prefix) === -1 && key.indexOf(cookie_session_prefix) === -1 || this._prefix && key.indexOf(this._prefix) === 0) {\n                            Cookies.remove(key);\n                        }\n                    }\n                }\n            },\n            setExpires: function (e) {\n                this._expires = e;\n                return this;\n            },\n            setPath: function (p) {\n                this._path = p;\n                return this;\n            },\n            setDomain: function (d) {\n                this._domain = d;\n                return this;\n            },\n            setSecure: function (s) {\n                this._secure = s;\n                return this;\n            },\n            setConf: function (c) {\n                if (c.path) {\n                    this._path = c.path;\n                }\n                if (c.domain) {\n                    this._domain = c.domain;\n                }\n                if (c.secure) {\n                    this._secure = c.secure;\n                }\n                if (c.expires) {\n                    this._expires = c.expires;\n                }\n                return this;\n            },\n            setDefaultConf: function () {\n                this._path = this._domain = this._expires = null;\n                this._secure = false;\n            }\n        };\n        if (!storage_available) {\n            window.localCookieStorage = _extend({}, cookie_storage, {\n                _prefix: cookie_local_prefix,\n                _expires: 365 * 10,\n                _secure: true\n            });\n            window.sessionCookieStorage = _extend({}, cookie_storage, {\n                _prefix: cookie_session_prefix + window.name + '_',\n                _secure: true\n            });\n        }\n        window.cookieStorage = _extend({}, cookie_storage);\n        // cookieStorage API\n        apis.cookieStorage = _extend({}, storage, {\n            _type: 'cookieStorage',\n            setExpires: function (e) {\n                window.cookieStorage.setExpires(e);\n                return this;\n            },\n            setPath: function (p) {\n                window.cookieStorage.setPath(p);\n                return this;\n            },\n            setDomain: function (d) {\n                window.cookieStorage.setDomain(d);\n                return this;\n            },\n            setSecure: function (s) {\n                window.cookieStorage.setSecure(s);\n                return this;\n            },\n            setConf: function (c) {\n                window.cookieStorage.setConf(c);\n                return this;\n            },\n            setDefaultConf: function () {\n                window.cookieStorage.setDefaultConf();\n                return this;\n            }\n        });\n    }\n\n    // Get a new API on a namespace\n    apis.initNamespaceStorage = function (ns) {\n        return _createNamespace(ns);\n    };\n    if (storage_available) {\n        // localStorage API\n        apis.localStorage = _extend({}, storage, {_type: 'localStorage'});\n        // sessionStorage API\n        apis.sessionStorage = _extend({}, storage, {_type: 'sessionStorage'});\n    } else {\n        // localStorage API\n        apis.localStorage = _extend({}, storage, {_type: 'localCookieStorage'});\n        // sessionStorage API\n        apis.sessionStorage = _extend({}, storage, {_type: 'sessionCookieStorage'});\n    }\n    // List of all namespace storage\n    apis.namespaceStorages = {};\n    // Remove all items in all storages\n    apis.removeAllStorages = function (reinit_ns) {\n        apis.localStorage.removeAll(reinit_ns);\n        apis.sessionStorage.removeAll(reinit_ns);\n        if (apis.cookieStorage) {\n            apis.cookieStorage.removeAll(reinit_ns);\n        }\n        if (!reinit_ns) {\n            apis.namespaceStorages = {};\n        }\n    };\n    // About alwaysUseJson\n    // By default, all values are string on html storages and the plugin don't use json to store simple values (strings, int, float...)\n    // So by default, if you do storage.setItem('test',2), value in storage will be \"2\", not 2\n    // If you set this property to true, all values set with the plugin will be stored as json to have typed values in any cases\n    apis.alwaysUseJsonInStorage = function (value) {\n        storage.alwaysUseJson = value;\n        apis.localStorage.alwaysUseJson = value;\n        apis.sessionStorage.alwaysUseJson = value;\n        if (apis.cookieStorage) {\n            apis.cookieStorage.alwaysUseJson = value;\n        }\n    };\n\n    return apis;\n}));\n","Magento_Security/js/escaper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * A loose JavaScript version of Magento\\Framework\\Escaper\n *\n * Due to differences in how XML/HTML is processed in PHP vs JS there are a couple of minor differences in behavior\n * from the PHP counterpart.\n *\n * The first difference is that the default invocation of escapeHtml without allowedTags will double-escape existing\n * entities as the intention of such an invocation is that the input isn't supposed to contain any HTML.\n *\n * The second difference is that escapeHtml will not escape quotes. Since the input is actually being processed by the\n * DOM there is no chance of quotes being mixed with HTML syntax. And, since escapeHtml is not\n * intended to be used with raw injection into a HTML attribute, this is acceptable.\n *\n * @api\n */\ndefine([], function () {\n    'use strict';\n\n    return {\n        neverAllowedElements: ['script', 'img', 'embed', 'iframe', 'video', 'source', 'object', 'audio'],\n        generallyAllowedAttributes: ['id', 'class', 'href', 'title', 'style'],\n        forbiddenAttributesByElement: {\n            a: ['style']\n        },\n\n        /**\n         * Escape a string for safe injection into HTML\n         *\n         * @param {String} data\n         * @param {Array|null} allowedTags\n         * @returns {String}\n         */\n        escapeHtml: function (data, allowedTags) {\n            var domParser = new DOMParser(),\n                fragment = domParser.parseFromString('<div></div>', 'text/html');\n\n            fragment = fragment.body.childNodes[0];\n            allowedTags = typeof allowedTags === 'object' && allowedTags.length ? allowedTags : null;\n\n            if (allowedTags) {\n                fragment.innerHTML = data || '';\n                allowedTags = this._filterProhibitedTags(allowedTags);\n\n                this._removeComments(fragment);\n                this._removeNotAllowedElements(fragment, allowedTags);\n                this._removeNotAllowedAttributes(fragment);\n\n                return fragment.innerHTML;\n            }\n\n            fragment.textContent = data || '';\n\n            return fragment.innerHTML;\n        },\n\n        /**\n         * Remove the always forbidden tags from a list of provided tags\n         *\n         * @param {Array} tags\n         * @returns {Array}\n         * @private\n         */\n        _filterProhibitedTags: function (tags) {\n            return tags.filter(function (n) {\n                return this.neverAllowedElements.indexOf(n) === -1;\n            }.bind(this));\n        },\n\n        /**\n         * Remove comment nodes from the given node\n         *\n         * @param {Node} node\n         * @private\n         */\n        _removeComments: function (node) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_COMMENT,\n                    function () {\n                        return NodeFilter.FILTER_ACCEPT;\n                    },\n                    false\n                ),\n                nodesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                nodesToRemove.push(treeWalker.currentNode);\n            }\n\n            nodesToRemove.forEach(function (nodeToRemove) {\n                nodeToRemove.parentNode.removeChild(nodeToRemove);\n            });\n        },\n\n        /**\n         * Strip the given node of all disallowed tags while permitting any nested text nodes\n         *\n         * @param {Node} node\n         * @param {Array|null} allowedTags\n         * @private\n         */\n        _removeNotAllowedElements: function (node, allowedTags) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_ELEMENT,\n                    function (currentNode) {\n                        return allowedTags.indexOf(currentNode.nodeName.toLowerCase()) === -1 ?\n                            NodeFilter.FILTER_ACCEPT\n                            // SKIP instead of REJECT because REJECT also rejects child nodes\n                            : NodeFilter.FILTER_SKIP;\n                    },\n                false\n                ),\n                nodesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                if (allowedTags.indexOf(treeWalker.currentNode.nodeName.toLowerCase()) === -1) {\n                    nodesToRemove.push(treeWalker.currentNode);\n                }\n            }\n\n            nodesToRemove.forEach(function (nodeToRemove) {\n                nodeToRemove.parentNode.replaceChild(\n                    node.ownerDocument.createTextNode(nodeToRemove.textContent),\n                    nodeToRemove\n                );\n            });\n        },\n\n        /**\n         * Remove any invalid attributes from the given node\n         *\n         * @param {Node} node\n         * @private\n         */\n        _removeNotAllowedAttributes: function (node) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_ELEMENT,\n                    function () {\n                        return NodeFilter.FILTER_ACCEPT;\n                    },\n                false\n                ),\n                i,\n                attribute,\n                nodeName,\n                attributesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                for (i = 0; i < treeWalker.currentNode.attributes.length; i++) {\n                    attribute = treeWalker.currentNode.attributes[i];\n                    nodeName = treeWalker.currentNode.nodeName.toLowerCase();\n\n                    if (this.generallyAllowedAttributes.indexOf(attribute.name) === -1  || // eslint-disable-line max-depth,max-len\n                        this._checkHrefValue(attribute) ||\n                        this.forbiddenAttributesByElement[nodeName] &&\n                        this.forbiddenAttributesByElement[nodeName].indexOf(attribute.name) !== -1\n                    ) {\n                        attributesToRemove.push(attribute);\n                    }\n                }\n            }\n\n            attributesToRemove.forEach(function (attributeToRemove) {\n                attributeToRemove.ownerElement.removeAttribute(attributeToRemove.name);\n            });\n        },\n\n        /**\n         * Check that attribute contains script content\n         *\n         * @param {Object} attribute\n         * @private\n         */\n        _checkHrefValue: function (attribute) {\n            return attribute.nodeName === 'href' && attribute.nodeValue.startsWith('javascript');\n        }\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/reCaptchaScriptLoader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    var scriptTagAdded = false;\n\n    return {\n        /**\n         * Add script tag. Script tag should be added once\n         */\n        addReCaptchaScriptTag: function () {\n            var element, scriptTag;\n\n            if (!scriptTagAdded) {\n                element = document.createElement('script');\n                scriptTag = document.getElementsByTagName('script')[0];\n\n                element.async = true;\n                element.src = 'https://www.google.com/recaptcha/api.js' +\n                    '?onload=globalOnRecaptchaOnLoadCallback&render=explicit';\n\n                scriptTag.parentNode.insertBefore(element, scriptTag);\n                scriptTagAdded = true;\n            }\n        }\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['ko'], function (ko) {\n    'use strict';\n\n    return {\n        ids: ko.observableArray([]),\n        captchaList: ko.observableArray([]),\n        tokenFields: ko.observableArray([])\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/reCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global grecaptcha */\ndefine(\n    [\n        'uiComponent',\n        'jquery',\n        'ko',\n        'underscore',\n        'Magento_ReCaptchaFrontendUi/js/registry',\n        'Magento_ReCaptchaFrontendUi/js/reCaptchaScriptLoader',\n        'Magento_ReCaptchaFrontendUi/js/nonInlineReCaptchaRenderer'\n    ], function (Component, $, ko, _, registry, reCaptchaLoader, nonInlineReCaptchaRenderer) {\n        'use strict';\n\n        return Component.extend({\n\n            defaults: {\n                template: 'Magento_ReCaptchaFrontendUi/reCaptcha',\n                reCaptchaId: 'recaptcha'\n            },\n\n            /**\n             * @inheritdoc\n             */\n            initialize: function () {\n                this._super();\n                this._loadApi();\n            },\n\n            /**\n             * Loads recaptchaapi API and triggers event, when loaded\n             * @private\n             */\n            _loadApi: function () {\n                if (this._isApiRegistered !== undefined) {\n                    if (this._isApiRegistered === true) {\n                        $(window).trigger('recaptchaapiready');\n                    }\n\n                    return;\n                }\n                this._isApiRegistered = false;\n\n                // global function\n                window.globalOnRecaptchaOnLoadCallback = function () {\n                    this._isApiRegistered = true;\n                    $(window).trigger('recaptchaapiready');\n                }.bind(this);\n\n                reCaptchaLoader.addReCaptchaScriptTag();\n            },\n\n            /**\n             * Checking that reCAPTCHA is invisible type\n             * @returns {Boolean}\n             */\n            getIsInvisibleRecaptcha: function () {\n                if (this.settings ===\n\n                    void 0) {\n                    return false;\n                }\n\n                return this.settings.invisible;\n            },\n\n            /**\n             * reCAPTCHA callback\n             * @param {String} token\n             */\n            reCaptchaCallback: function (token) {\n                var submitButton;\n\n                if (this.getIsInvisibleRecaptcha()) {\n                    this.tokenField.value = token;\n                    submitButton = this.$parentForm.find('button:not([type]), [type=submit]');\n                    if (submitButton.length) { //eslint-disable-line max-depth\n                        submitButton.attr('disabled', false);\n                    }\n                    this.$parentForm.submit();\n                }\n            },\n\n            /**\n             * Initialize reCAPTCHA after first rendering\n             */\n            initCaptcha: function () {\n                var $parentForm,\n                    $wrapper,\n                    $reCaptcha,\n                    widgetId,\n                    parameters;\n\n                if (this.captchaInitialized || this.settings ===\n\n                    void 0) {\n                    return;\n                }\n\n                this.captchaInitialized = true;\n\n                /*\n                 * Workaround for data-bind issue:\n                 * We cannot use data-bind to link a dynamic id to our component\n                 * See:\n                 * https://stackoverflow.com/questions/46657573/recaptcha-the-bind-parameter-must-be-an-element-or-id\n                 *\n                 * We create a wrapper element with a wrapping id and we inject the real ID with jQuery.\n                 * In this way we have no data-bind attribute at all in our reCAPTCHA div\n                 */\n                $wrapper = $('#' + this.getReCaptchaId() + '-wrapper');\n                $reCaptcha = $wrapper.find('.g-recaptcha');\n                $reCaptcha.attr('id', this.getReCaptchaId());\n\n                $parentForm = $wrapper.parents('form');\n\n                if (this.settings === undefined) {\n\n                    return;\n                }\n\n                parameters = _.extend(\n                    {\n                        'callback': function (token) { // jscs:ignore jsDoc\n                            this.reCaptchaCallback(token);\n                            this.validateReCaptcha(true);\n                        }.bind(this),\n                        'expired-callback': function () {\n                            this.validateReCaptcha(false);\n                        }.bind(this)\n                    },\n                    this.settings.rendering\n                );\n\n                if (parameters.size === 'invisible' && parameters.badge !== 'inline') {\n                    nonInlineReCaptchaRenderer.add($reCaptcha, parameters);\n                }\n\n                // eslint-disable-next-line no-undef\n                widgetId = grecaptcha.render(this.getReCaptchaId(), parameters);\n                this.initParentForm($parentForm, widgetId);\n\n                registry.ids.push(this.getReCaptchaId());\n                registry.captchaList.push(widgetId);\n                registry.tokenFields.push(this.tokenField);\n\n            },\n\n            /**\n             * Initialize parent form.\n             *\n             * @param {Object} parentForm\n             * @param {String} widgetId\n             */\n            initParentForm: function (parentForm, widgetId) {\n                var listeners;\n\n                if (this.getIsInvisibleRecaptcha() && parentForm.length > 0) {\n                    parentForm.submit(function (event) {\n                        var submitButton;\n\n                        if (!this.tokenField.value) {\n                            submitButton = this.$parentForm.find('button:not([type]), [type=submit]');\n                            if (submitButton.length) { //eslint-disable-line max-depth\n                                submitButton.attr('disabled', true);\n                            }\n                            // eslint-disable-next-line no-undef\n                            grecaptcha.execute(widgetId);\n                            event.preventDefault(event);\n                            event.stopImmediatePropagation();\n                        }\n                    }.bind(this));\n\n                    // Move our (last) handler topmost. We need this to avoid submit bindings with ko.\n                    listeners = $._data(parentForm[0], 'events').submit;\n                    listeners.unshift(listeners.pop());\n\n                    // Create a virtual token field\n                    this.tokenField = $('<input type=\"text\" name=\"token\" style=\"display: none\" />')[0];\n                    this.$parentForm = parentForm;\n                    parentForm.append(this.tokenField);\n                } else {\n                    this.tokenField = null;\n                }\n                let submitButton = parentForm.find('button:not([type]), [type=submit]');\n\n                if (submitButton.length) {\n                    submitButton.prop('disabled', false);\n                }\n            },\n\n            /**\n             * Validates reCAPTCHA\n             * @param {*} state\n             * @returns {jQuery}\n             */\n            validateReCaptcha: function (state) {\n                if (!this.getIsInvisibleRecaptcha()) {\n                    return $(document).find('input[type=checkbox].required-captcha').prop('checked', state);\n                }\n            },\n\n            /**\n             * Render reCAPTCHA\n             */\n            renderReCaptcha: function () {\n                if (window.grecaptcha && window.grecaptcha.render) { // Check if reCAPTCHA is already loaded\n                    this.initCaptcha();\n                } else { // Wait for reCAPTCHA to be loaded\n                    $(window).on('recaptchaapiready', function () {\n                        this.initCaptcha();\n                    }.bind(this));\n                }\n            },\n\n            /**\n             * Get reCAPTCHA ID\n             * @returns {String}\n             */\n            getReCaptchaId: function () {\n                return this.reCaptchaId;\n            }\n        });\n    });\n","Magento_ReCaptchaFrontendUi/js/nonInlineReCaptchaRenderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global grecaptcha */\ndefine([\n    'jquery',\n    'jquery/z-index'\n], function ($) {\n    'use strict';\n\n    var reCaptchaEntities = [],\n        initialized = false,\n        rendererRecaptchaId = 'recaptcha-invisible',\n        rendererReCaptcha = null;\n\n    return {\n        /**\n         * Add reCaptcha entity to checklist.\n         *\n         * @param {jQuery} reCaptchaEntity\n         * @param {Object} parameters\n         */\n        add: function (reCaptchaEntity, parameters) {\n            if (!initialized) {\n                this.init();\n                grecaptcha.render(rendererRecaptchaId, parameters);\n                setInterval(this.resolveVisibility, 100);\n                initialized = true;\n            }\n\n            reCaptchaEntities.push(reCaptchaEntity);\n        },\n\n        /**\n         * Show additional reCaptcha instance if any other should be visible, otherwise hide it.\n         */\n        resolveVisibility: function () {\n            reCaptchaEntities.some(function (entity) {\n                return entity.is(':visible') &&\n                    // 900 is some magic z-index value of modal popups.\n                    (entity.closest('[data-role=\\'modal\\']').length === 0 || entity.zIndex() > 900);\n            }) ? rendererReCaptcha.show() : rendererReCaptcha.hide();\n        },\n\n        /**\n         * Initialize additional reCaptcha instance.\n         */\n        init: function () {\n            rendererReCaptcha = $('<div/>', {\n                'id': rendererRecaptchaId\n            });\n            rendererReCaptcha.hide();\n            $('body').append(rendererReCaptcha);\n        }\n    };\n});\n","Magento_ReCaptchaFrontendUi/js/ui-messages-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['Magento_ReCaptchaFrontendUi/js/registry'], function (registry) {\n    'use strict';\n\n    return function (originalComponent) {\n        return originalComponent.extend({\n            /**\n             * Initialize reset on messages\n             * @returns {initialize}\n             */\n            initialize: function () {\n                this._super();\n\n                this.messageContainer.errorMessages.subscribe(function () {\n                    var\n                        i,\n                        captchaList = registry.captchaList(),\n                        tokenFieldsList = registry.tokenFields();\n\n                    for (i = 0; i < captchaList.length; i++) {\n                        // eslint-disable-next-line no-undef\n                        grecaptcha.reset(captchaList[i]);\n\n                        if (tokenFieldsList[i]) {\n                            tokenFieldsList[i].value = '';\n                        }\n                    }\n                }, null, 'arrayChange');\n\n                return this;\n            }\n        });\n    };\n});\n","Amasty_Conditions/js/action/recollect-totals.js":"define([\n    'jquery',\n    'mage/utils/wrapper',\n    'underscore',\n    'Amasty_Conditions/js/model/resource-url-manager',\n    'Magento_Checkout/js/model/quote',\n    'mage/storage',\n    'Magento_Checkout/js/model/totals',\n    'Magento_Checkout/js/model/error-processor',\n    'Magento_Customer/js/customer-data',\n    'uiRegistry',\n    'Amasty_Conditions/js/model/subscriber'\n], function ($, wrapper, _, resourceUrlManager, quote, storage, totalsService, errorProcessor, customerData, registry, subscriber) {\n    'use strict';\n\n    var ajax,\n        sendTimeout,\n        sendingPayload;\n\n    return function (force) {\n        var serviceUrl,\n            payload,\n            address,\n            paymentMethod,\n            requiredFields = ['countryId', 'region', 'regionId', 'postcode', 'city'],\n            newAddress = quote.shippingAddress() ? quote.shippingAddress() : quote.billingAddress(),\n            city;\n\n        serviceUrl = resourceUrlManager.getUrlForTotalsEstimationForNewAddress(quote);\n        address = _.pick(newAddress, requiredFields);\n        paymentMethod = quote.paymentMethod() ? quote.paymentMethod().method : null;\n        \n        city = '';\n        if (quote.isVirtual() && quote.billingAddress()) {\n            city = quote.billingAddress().city;\n        } else if (quote.shippingAddress()) {\n            city = quote.shippingAddress().city;\n        }\n        \n        address.extension_attributes = {\n            advanced_conditions: {\n                custom_attributes: quote.shippingAddress() ? quote.shippingAddress().custom_attributes : [],\n                payment_method: paymentMethod,\n                city: city,\n                shipping_address_line: quote.shippingAddress() ? quote.shippingAddress().street : null,\n                billing_address_country: quote.billingAddress() ? quote.billingAddress().countryId : null,\n                currency: totalsService.totals() ? totalsService.totals().quote_currency_code : null\n            }\n        };\n\n        payload = {\n            addressInformation: {\n                address: address\n            }\n        };\n\n        if (quote.shippingMethod() && quote.shippingMethod()['method_code']) {\n            payload.addressInformation['shipping_method_code'] = quote.shippingMethod()['method_code'];\n            payload.addressInformation['shipping_carrier_code'] = quote.shippingMethod()['carrier_code'];\n        }\n\n        if (!_.isEqual(sendingPayload, payload) || force === true) {\n            sendingPayload = payload;\n            clearTimeout(sendTimeout);\n            //delay for avoid multi request\n            sendTimeout = setTimeout(function(){\n                clearTimeout(sendTimeout);\n                if (subscriber.isLoading() === true) {\n                    ajax.abort();\n                } else {\n                    // Start loader for totals block\n                    totalsService.isLoading(true);\n                    subscriber.isLoading(true);\n                }\n\n                ajax = storage.post(\n                    serviceUrl,\n                    JSON.stringify(payload),\n                    false\n                ).done(function (result) {\n                    quote.setTotals(result);\n                    // Stop loader for totals block\n                    totalsService.isLoading(false);\n                    subscriber.isLoading(false);\n                }).fail(function (response) {\n                    if (response.responseText || response.status) {\n                        errorProcessor.process(response);\n                    }\n                });\n            }, 200);\n        }\n    };\n});","Amasty_Conditions/js/model/subscriber.js":"define([\n    'ko'\n    ], function (ko) {\n        return {\n            isLoading: ko.observable(false)\n        }\n    }\n);","Amasty_Conditions/js/model/resource-url-manager.js":"define([\n    'Magento_Checkout/js/model/resource-url-manager'\n], function (resourceUrlManager) {\n    'use strict';\n\n    return {\n        /**\n         * Making url for total estimation request.\n         *\n         * @param {Object} quote - Quote model.\n         * @returns {String} Result url.\n         */\n        getUrlForTotalsEstimationForNewAddress: function (quote) {\n            if (window.checkoutConfig.isNegotiableQuote) {\n                var params = {\n                        quoteId: quote.getQuoteId()\n                    },\n                    urls = {\n                        'negotiable': '/negotiable-carts/:quoteId/totals-information/?isNegotiableQuote=true'\n                    };\n\n                return resourceUrlManager.getUrl(urls, params);\n            }\n\n            return resourceUrlManager.getUrlForTotalsEstimationForNewAddress(quote);\n        },\n    };\n});\n","Amasty_Conditions/js/model/shipping-rates-validation-rules-mixin.js":"define([\n    'jquery',\n    'mage/utils/wrapper',\n    'uiRegistry'\n], function ($, wrapper) {\n    \"use strict\";\n\n    return function (shippingRatesValidationRules) {\n        shippingRatesValidationRules.getObservableFields = wrapper.wrap(shippingRatesValidationRules.getObservableFields,\n            function (originalAction) {\n                var fields = originalAction();\n                fields.push('street');\n                fields.push('city');\n                fields.push('region_id');\n\n                return fields;\n            }\n        );\n\n        return shippingRatesValidationRules;\n    };\n});\n","Amasty_Conditions/js/model/conditions-subscribe.js":"define([\n    'jquery',\n    'underscore',\n    'uiComponent',\n    'Magento_Checkout/js/model/quote',\n    'Amasty_Conditions/js/action/recollect-totals',\n    'Amasty_Conditions/js/model/subscriber',\n    'Magento_Checkout/js/model/shipping-service',\n    'Magento_Checkout/js/model/shipping-rate-processor/new-address',\n    'Magento_Checkout/js/model/totals',\n    'Magento_SalesRule/js/view/payment/discount',\n    'rjsResolver'\n], function ($, _, Component, quote, recollect, subscriber, shippingService, shippingProcessor, totals, discount, resolver) {\n    'use strict';\n\n    return Component.extend({\n        previousShippingMethodData: {},\n        previousItemsData: [],\n        billingAddressCountry: null,\n        city: null,\n        street: null,\n        isPageLoaded: false,\n        initialize: function () {\n            this._insertPolyfills();\n            this._super();\n\n            resolver(function() {\n                this.isPageLoaded = true;\n\n                totals.getItems().subscribe(this.storeOldItems, this, \"beforeChange\");\n                totals.getItems().subscribe(this.recollectOnItems, this);\n            }.bind(this));\n\n            discount().isApplied.subscribe(function () {\n                recollect(true);\n            });\n\n            quote.shippingAddress.subscribe(function (newShippingAddress) {\n                // while page is loading do not recollect, should be recollected after shipping rates\n                // for avoid extra requests to server\n                if (this.isPageLoaded && this._isNeededRecollectShipping(newShippingAddress, this.city, this.street)) {\n                    this.city = newShippingAddress.city;\n                    this.street = newShippingAddress.street;\n                    if (newShippingAddress) {\n                        recollect();\n                    }\n                }\n            }.bind(this));\n\n            quote.billingAddress.subscribe(function (newBillAddress) {\n                if (this._isNeededRecollectBilling(\n                    newBillAddress,\n                    this.billingAddressCountry,\n                    this.billingAddressCity\n                )) {\n                    this.billingAddressCountry = newBillAddress.countryId;\n                    this.billingAddressCity = newBillAddress.city;\n                    if (!this._isVirtualQuote()\n                        && (quote.shippingAddress() && newBillAddress.countryId !== quote.shippingAddress().countryId)\n                    ) {\n                        shippingProcessor.getRates(quote.shippingAddress());\n                    }\n                    recollect();\n                }\n            }.bind(this));\n\n            //for invalid shipping address update\n            shippingService.getShippingRates().subscribe(function (rates) {\n                if (!this._isVirtualQuote()) {\n                    recollect();\n                }\n            }.bind(this));\n\n            quote.paymentMethod.subscribe(function (newMethodData) {\n                recollect();\n            }, this);\n\n            quote.shippingMethod.subscribe(this.storeOldMethod, this, \"beforeChange\");\n            quote.shippingMethod.subscribe(this.recollectOnShippingMethod, this);\n\n            return this;\n        },\n\n        /**\n         * Store before change shipping method, because sometimes shipping methods updates always (not by change)\n         *\n         * @param {Object} oldMethod\n         */\n        storeOldMethod: function (oldMethod) {\n            this.previousShippingMethodData = oldMethod;\n        },\n\n        recollectOnShippingMethod: function (newMethodData) {\n            if (!_.isEqual(this.previousShippingMethodData, newMethodData)) {\n                recollect();\n            }\n        },\n\n        /**\n         * Store before change cart items\n         *\n         * @param {Array} oldItems\n         * @since 1.3.13\n         */\n        storeOldItems: function (oldItems) {\n            this.previousItemsData = this._prepareArrayForCompare(oldItems);\n        },\n\n        /**\n         * Recollect totals on cart items update\n         *\n         * @param {Array} newItems\n         * @since 1.3.13 improve compatibility with modules which allow update cart items on checkout page\n         *        and ajax update cart items\n         */\n        recollectOnItems: function (newItems) {\n            if (!_.isEqual(this.previousItemsData, this._prepareArrayForCompare(newItems))) {\n                // totals should be already collected, trigger subscribers\n                // for more stability but less performance can be replaced with recollect(true);\n                subscriber.isLoading.valueHasMutated();\n            }\n        },\n\n        /**\n         * Remove all not simple types from array items\n         *\n         * @param {Array} data\n         * @returns {Array}\n         * @private\n         * @since 1.3.13\n         */\n        _prepareArrayForCompare: function (data) {\n            var result = [],\n                itemData = {};\n\n            _.each(data, function(item) {\n                itemData = _.pick(item, function (value) {\n                    return !_.isObject(value);\n                });\n                result.push(itemData);\n            }.bind(this));\n\n            return result;\n        },\n\n        _isVirtualQuote: function () {\n            return quote.isVirtual()\n                || window.checkoutConfig.activeCarriers && window.checkoutConfig.activeCarriers.length === 0;\n        },\n\n        _isNeededRecollectShipping: function (newShippingAddress, city, street) {\n            return !this._isVirtualQuote()\n                && (\n                    newShippingAddress\n                    && (newShippingAddress.city || newShippingAddress.street)\n                    && (newShippingAddress.city != city || !_.isEqual(newShippingAddress.street, street)));\n        },\n\n        _isNeededRecollectBilling: function (newBillAddress, billingAddressCountry, billingAddressCity) {\n            var isNeedRecollectByCountry = newBillAddress\n                    && newBillAddress.countryId\n                    && newBillAddress.countryId !== billingAddressCountry,\n                isNeedRecollectByCity = newBillAddress\n                    && newBillAddress.city\n                    && newBillAddress.city !== billingAddressCity;\n\n            return this.isPageLoaded && (isNeedRecollectByCountry || isNeedRecollectByCity);\n        },\n\n        _insertPolyfills: function () {\n            if (typeof Object.assign != 'function') {\n                // Must be writable: true, enumerable: false, configurable: true\n                Object.defineProperty(Object, \"assign\", {\n                    value: function assign(target, varArgs) { // .length of function is 2\n                        'use strict';\n                        if (target == null) { // TypeError if undefined or null\n                            throw new TypeError('Cannot convert undefined or null to object');\n                        }\n\n                        var to = Object(target);\n\n                        for (var index = 1; index < arguments.length; index++) {\n                            var nextSource = arguments[index];\n\n                            if (nextSource != null) { // Skip over if undefined or null\n                                for (var nextKey in nextSource) {\n                                    // Avoid bugs when hasOwnProperty is shadowed\n                                    if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {\n                                        to[nextKey] = nextSource[nextKey];\n                                    }\n                                }\n                            }\n                        }\n                        return to;\n                    },\n                    writable: true,\n                    configurable: true\n                });\n            }\n        }\n    });\n});\n","Magento_LoginAsCustomerAssistance/js/opt-in.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    return function (config, element) {\n        $(element).on('submit', function () {\n            this.elements['assistance_allowed'].value =\n                this.elements['assistance_allowed_checkbox'].checked ?\n                    config.allowAccess : config.denyAccess;\n        });\n    };\n});\n","Magento_ReCaptchaWebapiUi/js/jquery-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n// jscs:disable requireDotNotation\n\ndefine([\n    'mage/utils/wrapper'\n], function (wrapper) {\n    'use strict';\n\n    return function (jQuery) {\n        jQuery.ajax = wrapper.wrapSuper(jQuery.ajax, function () {\n            //Moving ReCaptcha value from payload to the header for requests to web API\n            var settings,\n                payload;\n\n            if (arguments.length !== 0) {\n                settings = arguments.length === 1 ? arguments[0] : arguments[1];\n            }\n\n            if (settings && settings.hasOwnProperty('data')) {\n                //The request has a body, trying to parse JSON data\n                try {\n                    payload = JSON.parse(settings.data);\n                } catch (e) {\n                    //Not JSON\n                }\n            }\n\n            if (payload && payload.hasOwnProperty('xReCaptchaValue')) {\n                if (!settings.hasOwnProperty('headers')) {\n                    settings.headers = {};\n                }\n                settings.headers['X-ReCaptcha'] = payload.xReCaptchaValue;\n                delete payload['xReCaptchaValue'];\n                settings.data = JSON.stringify(payload);\n            }\n\n            return this._super.apply(this, arguments);\n        });\n\n        return jQuery;\n    };\n});\n","Magento_ReCaptchaWebapiUi/js/webapiReCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n// jscs:disable jsDoc\n\n/* global grecaptcha */\ndefine(\n    [\n        'Magento_ReCaptchaFrontendUi/js/reCaptcha',\n        'Magento_ReCaptchaWebapiUi/js/webapiReCaptchaRegistry'\n    ],\n    function (Component, registry) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                autoTrigger: false\n            },\n\n            /**\n             * Provide the token to the registry.\n             *\n             * @param {String} token\n             */\n            reCaptchaCallback: function (token) {\n                //Make the token retrievable in other UI components.\n                registry.tokens[this.getReCaptchaId()] = token;\n\n                if (typeof registry._listeners[this.getReCaptchaId()] !== 'undefined') {\n                    registry._listeners[this.getReCaptchaId()](token);\n                }\n            },\n\n            /**\n             * Register this ReCaptcha.\n             *\n             * @param {Object} parentForm\n             * @param {String} widgetId\n             */\n            initParentForm: function (parentForm, widgetId) {\n                var self = this,\n                    trigger;\n\n                trigger = function () {\n                    self.reCaptchaCallback(grecaptcha.getResponse(widgetId));\n                };\n                registry._isInvisibleType[this.getReCaptchaId()] = false;\n\n                if (this.getIsInvisibleRecaptcha()) {\n                    trigger = function () {\n                        grecaptcha.execute(widgetId);\n                    };\n                    registry._isInvisibleType[this.getReCaptchaId()] = true;\n                }\n\n                if (this.autoTrigger) {\n                    //Validate ReCaptcha when initiated\n                    trigger();\n                    registry.triggers[this.getReCaptchaId()] = new Function();\n                } else {\n                    registry.triggers[this.getReCaptchaId()] = trigger;\n                }\n                this.tokenField = null;\n            }\n        });\n    }\n);\n","Magento_ReCaptchaWebapiUi/js/webapiReCaptchaRegistry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    return {\n        /**\n         * recaptchaId: token map.\n         *\n         * Tokens for already verified recaptcha.\n         */\n        tokens: {},\n\n        /**\n         * recaptchaId: triggerFn map.\n         *\n         * Call a trigger to initiate a recaptcha verification.\n         */\n        triggers: {},\n\n        /**\n         * recaptchaId: callback map\n         */\n        _listeners: {},\n\n        /**\n         * recaptchaId: bool map\n         */\n        _isInvisibleType: {},\n\n        /**\n         * Add a listener to when the ReCaptcha finishes verification\n         * @param {String} id - ReCaptchaId\n         * @param {Function} func - Will be called back with the token\n         */\n        addListener: function (id, func) {\n            if (this.tokens.hasOwnProperty(id)) {\n                func(this.tokens[id]);\n            } else {\n                this._listeners[id] = func;\n            }\n        },\n\n        /**\n         * Remove a listener\n         *\n         * @param id\n         */\n        removeListener: function (id) {\n            this._listeners[id] = undefined;\n        }\n    };\n});\n","Magento_Customer/js/customer-global-session-loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Customer/js/customer-data'\n], function ($, customerData) {\n    'use strict';\n\n    return function () {\n        var customer;\n\n        // When the session is available, this customer menu will be available\n        if ($('.customer-menu').length > 0) {\n            customer = customerData.get('customer');\n\n            customerData.getInitCustomerData().done(function () {\n                // Check if the customer data is set in local storage, if not reload data from server\n                if (!customer().firstname) {\n                    customerData.reload([], false);\n                }\n            });\n        }\n    };\n});\n","Magento_Customer/js/customer-data.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore',\n    'ko',\n    'Magento_Customer/js/section-config',\n    'mage/url',\n    'mage/storage',\n    'jquery/jquery-storageapi'\n], function ($, _, ko, sectionConfig, url) {\n    'use strict';\n\n    var options = {},\n        storage,\n        storageInvalidation,\n        invalidateCacheBySessionTimeOut,\n        invalidateCacheByCloseCookieSession,\n        dataProvider,\n        buffer,\n        customerData,\n        deferred = $.Deferred();\n\n    url.setBaseUrl(window.BASE_URL);\n    options.sectionLoadUrl = url.build('customer/section/load');\n\n    /**\n     * @param {Object} invalidateOptions\n     */\n    invalidateCacheBySessionTimeOut = function (invalidateOptions) {\n        var date;\n\n        if (new Date($.localStorage.get('mage-cache-timeout')) < new Date()) {\n            storage.removeAll();\n        }\n        date = new Date(Date.now() + parseInt(invalidateOptions.cookieLifeTime, 10) * 1000);\n        $.localStorage.set('mage-cache-timeout', date);\n    };\n\n    /**\n     * Invalidate Cache By Close Cookie Session\n     */\n    invalidateCacheByCloseCookieSession = function () {\n        var isLoggedIn = parseInt(options.isLoggedIn, 10) || 0;\n\n        if (!$.cookieStorage.isSet('mage-cache-sessid')) {\n            storage.removeAll();\n        }\n\n        if (!$.localStorage.isSet('mage-customer-login')) {\n            $.localStorage.set('mage-customer-login', isLoggedIn);\n        }\n        if ($.localStorage.get('mage-customer-login') !== isLoggedIn) {\n            $.localStorage.set('mage-customer-login', isLoggedIn);\n            storage.removeAll();\n        }\n\n        $.cookieStorage.set('mage-cache-sessid', true);\n    };\n\n    dataProvider = {\n\n        /**\n         * @param {Object} sectionNames\n         * @return {Object}\n         */\n        getFromStorage: function (sectionNames) {\n            var result = {};\n\n            _.each(sectionNames, function (sectionName) {\n                result[sectionName] = storage.get(sectionName);\n            });\n\n            return result;\n        },\n\n        /**\n         * @param {Object} sectionNames\n         * @param {Boolean} forceNewSectionTimestamp\n         * @return {*}\n         */\n        getFromServer: function (sectionNames, forceNewSectionTimestamp) {\n            var parameters;\n\n            sectionNames = sectionConfig.filterClientSideSections(sectionNames);\n            parameters = _.isArray(sectionNames) && sectionNames.indexOf('*') < 0 ? {\n                sections: sectionNames.join(',')\n            } : [];\n            parameters['force_new_section_timestamp'] = forceNewSectionTimestamp;\n\n            return $.getJSON(options.sectionLoadUrl, parameters).fail(function (jqXHR) {\n                throw new Error(jqXHR);\n            });\n        }\n    };\n\n    /**\n     * @param {Function} target\n     * @param {String} sectionName\n     * @return {*}\n     */\n    ko.extenders.disposableCustomerData = function (target, sectionName) {\n        var sectionDataIds, newSectionDataIds = {};\n\n        target.subscribe(function () {\n            setTimeout(function () {\n                storage.remove(sectionName);\n                sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n                _.each(sectionDataIds, function (data, name) {\n                    if (name !== sectionName) {\n                        newSectionDataIds[name] = data;\n                    }\n                });\n                $.cookieStorage.set('section_data_ids', newSectionDataIds);\n            }, 3000);\n        });\n\n        return target;\n    };\n\n    buffer = {\n        data: {},\n\n        /**\n         * @param {String} sectionName\n         */\n        bind: function (sectionName) {\n            this.data[sectionName] = ko.observable({});\n        },\n\n        /**\n         * @param {String} sectionName\n         * @return {Object}\n         */\n        get: function (sectionName) {\n            if (!this.data[sectionName]) {\n                this.bind(sectionName);\n            }\n\n            return this.data[sectionName];\n        },\n\n        /**\n         * @return {Array}\n         */\n        keys: function () {\n            return _.keys(this.data);\n        },\n\n        /**\n         * @param {String} sectionName\n         * @param {Object} sectionData\n         */\n        notify: function (sectionName, sectionData) {\n            if (!this.data[sectionName]) {\n                this.bind(sectionName);\n            }\n            this.data[sectionName](sectionData);\n        },\n\n        /**\n         * @param {Object} sections\n         */\n        update: function (sections) {\n            var sectionId = 0,\n                sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n\n            _.each(sections, function (sectionData, sectionName) {\n                sectionId = sectionData['data_id'];\n                sectionDataIds[sectionName] = sectionId;\n                storage.set(sectionName, sectionData);\n                storageInvalidation.remove(sectionName);\n                buffer.notify(sectionName, sectionData);\n            });\n            $.cookieStorage.set('section_data_ids', sectionDataIds);\n        },\n\n        /**\n         * @param {Object} sections\n         */\n        remove: function (sections) {\n            _.each(sections, function (sectionName) {\n                storage.remove(sectionName);\n\n                if (!sectionConfig.isClientSideSection(sectionName)) {\n                    storageInvalidation.set(sectionName, true);\n                }\n            });\n        }\n    };\n\n    customerData = {\n\n        /**\n         * Customer data initialization\n         */\n        init: function () {\n            var expiredSectionNames = this.getExpiredSectionNames();\n\n            if (expiredSectionNames.length > 0) {\n                _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n                    buffer.notify(sectionName, sectionData);\n                });\n                this.reload(expiredSectionNames, false);\n            } else {\n                _.each(dataProvider.getFromStorage(storage.keys()), function (sectionData, sectionName) {\n                    buffer.notify(sectionName, sectionData);\n                });\n\n                if (!_.isEmpty(storageInvalidation.keys())) {\n                    this.reload(storageInvalidation.keys(), false);\n                }\n            }\n\n            if (!_.isEmpty($.cookieStorage.get('section_data_clean'))) {\n                this.reload(sectionConfig.getSectionNames(), true);\n                $.cookieStorage.set('section_data_clean', '');\n            }\n        },\n\n        /**\n         * Storage init\n         */\n        initStorage: function () {\n            $.cookieStorage.setConf({\n                path: '/',\n                expires: new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000)\n            });\n\n            if (options.cookieDomain) {\n                $.cookieStorage.setConf({\n                    domain: options.cookieDomain\n                });\n            }\n\n            storage = $.initNamespaceStorage('mage-cache-storage').localStorage;\n            storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;\n        },\n\n        /**\n         * Retrieve the list of sections that has expired since last page reload.\n         *\n         * Sections can expire due to lifetime constraints or due to inconsistent storage information\n         * (validated by cookie data).\n         *\n         * @return {Array}\n         */\n        getExpiredSectionNames: function () {\n            var expiredSectionNames = [],\n                cookieSectionTimestamps = $.cookieStorage.get('section_data_ids') || {},\n                sectionLifetime = options.expirableSectionLifetime * 60,\n                currentTimestamp = Math.floor(Date.now() / 1000),\n                sectionData;\n\n            // process sections that can expire due to lifetime constraints\n            _.each(options.expirableSectionNames, function (sectionName) {\n                sectionData = storage.get(sectionName);\n\n                if (typeof sectionData === 'object' && sectionData['data_id'] + sectionLifetime <= currentTimestamp) {\n                    expiredSectionNames.push(sectionName);\n                }\n            });\n\n            // process sections that can expire due to storage information inconsistency\n            _.each(cookieSectionTimestamps, function (cookieSectionTimestamp, sectionName) {\n                if (storage !== undefined) {\n                    sectionData = storage.get(sectionName);\n                }\n\n                if (typeof sectionData === 'undefined' ||\n                    typeof sectionData === 'object' &&\n                    cookieSectionTimestamp !== sectionData['data_id']\n                ) {\n                    expiredSectionNames.push(sectionName);\n                }\n            });\n\n            //remove expired section names of previously installed/enable modules\n            expiredSectionNames = _.intersection(expiredSectionNames, sectionConfig.getSectionNames());\n\n            return _.uniq(expiredSectionNames);\n        },\n\n        /**\n         * Check if some sections have to be reloaded.\n         *\n         * @deprecated Use getExpiredSectionNames instead.\n         *\n         * @return {Boolean}\n         */\n        needReload: function () {\n            var expiredSectionNames = this.getExpiredSectionNames();\n\n            return expiredSectionNames.length > 0;\n        },\n\n        /**\n         * Retrieve the list of expired keys.\n         *\n         * @deprecated Use getExpiredSectionNames instead.\n         *\n         * @return {Array}\n         */\n        getExpiredKeys: function () {\n            return this.getExpiredSectionNames();\n        },\n\n        /**\n         * @param {String} sectionName\n         * @return {*}\n         */\n        get: function (sectionName) {\n            return buffer.get(sectionName);\n        },\n\n        /**\n         * @param {String} sectionName\n         * @param {Object} sectionData\n         */\n        set: function (sectionName, sectionData) {\n            var data = {};\n\n            data[sectionName] = sectionData;\n            buffer.update(data);\n        },\n\n        /**\n         * Avoid using this function directly 'cause of possible performance drawbacks.\n         * Each customer section reload brings new non-cached ajax request.\n         *\n         * @param {Array} sectionNames\n         * @param {Boolean} forceNewSectionTimestamp\n         * @return {*}\n         */\n        reload: function (sectionNames, forceNewSectionTimestamp) {\n            return dataProvider.getFromServer(sectionNames, forceNewSectionTimestamp).done(function (sections) {\n                $(document).trigger('customer-data-reload', [sectionNames]);\n                buffer.update(sections);\n            });\n        },\n\n        /**\n         * @param {Array} sectionNames\n         */\n        invalidate: function (sectionNames) {\n            var sectionDataIds,\n                sectionsNamesForInvalidation;\n\n            sectionsNamesForInvalidation = _.contains(sectionNames, '*') ? sectionConfig.getSectionNames() :\n                sectionNames;\n\n            $(document).trigger('customer-data-invalidate', [sectionsNamesForInvalidation]);\n            buffer.remove(sectionsNamesForInvalidation);\n            sectionDataIds = $.cookieStorage.get('section_data_ids') || {};\n\n            // Invalidate section in cookie (increase version of section with 1000)\n            _.each(sectionsNamesForInvalidation, function (sectionName) {\n                if (!sectionConfig.isClientSideSection(sectionName)) {\n                    sectionDataIds[sectionName] += 1000;\n                }\n            });\n            $.cookieStorage.set('section_data_ids', sectionDataIds);\n        },\n\n        /**\n         * Checks if customer data is initialized.\n         *\n         * @returns {jQuery.Deferred}\n         */\n        getInitCustomerData: function () {\n            return deferred.promise();\n        },\n\n        /**\n         * Reload sections on ajax complete\n         *\n         * @param {Object} jsonResponse\n         * @param {Object} settings\n         */\n        onAjaxComplete: function (jsonResponse, settings) {\n            var sections,\n                redirects;\n\n            if (settings.type.match(/post|put|delete/i)) {\n                sections = sectionConfig.getAffectedSections(settings.url);\n\n                if (sections && sections.length) {\n                    this.invalidate(sections);\n                    redirects = ['redirect', 'backUrl'];\n\n                    if (_.isObject(jsonResponse) && !_.isEmpty(_.pick(jsonResponse, redirects))) { //eslint-disable-line\n                        return;\n                    }\n                    this.reload(sections, true);\n                }\n            }\n        },\n\n        /**\n         * @param {Object} settings\n         * @constructor\n         */\n        'Magento_Customer/js/customer-data': function (settings) {\n            options = settings;\n            customerData.initStorage();\n            invalidateCacheBySessionTimeOut(settings);\n            invalidateCacheByCloseCookieSession();\n            customerData.init();\n            deferred.resolve();\n        }\n    };\n\n    /**\n     * Events listener\n     */\n    $(document).on('ajaxComplete', function (event, xhr, settings) {\n        customerData.onAjaxComplete(xhr.responseJSON, settings);\n    });\n\n    /**\n     * Events listener\n     */\n    $(document).on('submit', function (event) {\n        var sections;\n\n        if (event.target.method.match(/post|put|delete/i)) {\n            sections = sectionConfig.getAffectedSections(event.target.action);\n\n            if (sections) {\n                customerData.invalidate(sections);\n            }\n        }\n    });\n\n    return customerData;\n});\n","Magento_Customer/js/validation.js":"define([\n    'jquery',\n    'moment',\n    'mageUtils',\n    'jquery/validate',\n    'validation',\n    'mage/translate'\n], function ($, moment, utils) {\n    'use strict';\n\n    $.validator.addMethod(\n        'validate-date',\n        function (value, element, params) {\n            var dateFormat = utils.normalizeDate(params.dateFormat);\n\n            if (value === '') {\n                return true;\n            }\n\n            return moment(value, dateFormat, true).isValid();\n        },\n        $.mage.__('Invalid date')\n    );\n\n    $.validator.addMethod(\n        'validate-dob',\n        function (value, element, params) {\n            var dateFormat = utils.convertToMomentFormat(params.dateFormat);\n\n            if (value === '') {\n                return true;\n            }\n\n            return moment(value, dateFormat).isBefore(moment());\n        },\n        $.mage.__('The Date of Birth should not be greater than today.')\n    );\n});\n","Magento_Customer/js/show-password.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiComponent'\n], function ($, Component) {\n    'use strict';\n\n    return Component.extend({\n        passwordSelector: '',\n        passwordInputType: 'password',\n        textInputType: 'text',\n\n        defaults: {\n            template: 'Magento_Customer/show-password',\n            isPasswordVisible: false\n        },\n\n        /**\n         * @return {Object}\n         */\n        initObservable: function () {\n            this._super()\n                .observe(['isPasswordVisible']);\n\n            this.isPasswordVisible.subscribe(function (isChecked) {\n                this._showPassword(isChecked);\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Show/Hide password\n         * @private\n         */\n        _showPassword: function (isChecked) {\n            $(this.passwordSelector).attr('type',\n                isChecked ? this.textInputType : this.passwordInputType\n            );\n        }\n    });\n});\n","Magento_Customer/js/block-submit-on-send.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    return function (config) {\n        var dataForm = $('#' + config.formId);\n\n        dataForm.on('submit', function () {\n            $(this).find(':submit').attr('disabled', 'disabled');\n\n            if (this.isValid === false) {\n                $(this).find(':submit').prop('disabled', false);\n            }\n            this.isValid = true;\n        });\n        dataForm.on('invalid-form.validate', function () {\n            $(this).find(':submit').prop('disabled', false);\n            this.isValid = false;\n        });\n    };\n});\n","Magento_Customer/js/logout-redirect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/mage'\n], function ($) {\n    'use strict';\n\n    return function (data) {\n        $($.mage.redirect(data.url, 'assign', 5000));\n    };\n});\n","Magento_Customer/js/invalidation-processor.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiElement',\n    'Magento_Customer/js/customer-data'\n], function (_, Element, customerData) {\n    'use strict';\n\n    return Element.extend({\n        /**\n         * Initialize object\n         */\n        initialize: function () {\n            this._super();\n            this.process(customerData);\n        },\n\n        /**\n         * Process all rules in loop, each rule can invalidate some sections in customer data\n         *\n         * @param {Object} customerDataObject\n         */\n        process: function (customerDataObject) {\n            _.each(this.invalidationRules, function (rule, ruleName) {\n                _.each(rule, function (ruleArgs, rulePath) {\n                    require([rulePath], function (Rule) {\n                        var currentRule = new Rule(ruleArgs);\n\n                        if (!_.isFunction(currentRule.process)) {\n                            throw new Error('Rule ' + ruleName + ' should implement invalidationProcessor interface');\n                        }\n                        currentRule.process(customerDataObject);\n                    });\n                });\n            });\n        }\n    });\n});\n","Magento_Customer/js/addressValidation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'mageUtils',\n    'mage/translate',\n    'Magento_Checkout/js/model/postcode-validator',\n    'jquery-ui-modules/widget',\n    'validation'\n], function ($, __, utils, $t, postCodeValidator) {\n    'use strict';\n\n    $.widget('mage.addressValidation', {\n        options: {\n            selectors: {\n                button: '[data-action=save-address]',\n                zip: '#zip',\n                country: 'select[name=\"country_id\"]:visible'\n            }\n        },\n\n        zipInput: null,\n        countrySelect: null,\n\n        /**\n         * Validation creation\n         *\n         * @protected\n         */\n        _create: function () {\n            var button = $(this.options.selectors.button, this.element);\n\n            this.zipInput = $(this.options.selectors.zip, this.element);\n            this.countrySelect = $(this.options.selectors.country, this.element);\n\n            this.element.validation({\n\n                /**\n                 * Submit Handler\n                 * @param {Element} form - address form\n                 */\n                submitHandler: function (form) {\n\n                    button.attr('disabled', true);\n                    form.submit();\n                }\n            });\n\n            this._addPostCodeValidation();\n        },\n\n        /**\n         * Add postcode validation\n         *\n         * @protected\n         */\n        _addPostCodeValidation: function () {\n            var self = this;\n\n            this.zipInput.on('keyup', __.debounce(function (event) {\n                    var valid = self._validatePostCode(event.target.value);\n\n                    self._renderValidationResult(valid);\n                }, 500)\n            );\n\n            this.countrySelect.on('change', function () {\n                var valid = self._validatePostCode(self.zipInput.val());\n\n                self._renderValidationResult(valid);\n            });\n        },\n\n        /**\n         * Validate post code value.\n         *\n         * @protected\n         * @param {String} postCode - post code\n         * @return {Boolean} Whether is post code valid\n         */\n        _validatePostCode: function (postCode) {\n            var countryId = this.countrySelect.val();\n\n            if (postCode === null) {\n                return true;\n            }\n\n            return postCodeValidator.validate(postCode, countryId, this.options.postCodes);\n        },\n\n        /**\n         * Renders warning messages for invalid post code.\n         *\n         * @protected\n         * @param {Boolean} valid\n         */\n        _renderValidationResult: function (valid) {\n            var warnMessage,\n                alertDiv = this.zipInput.next();\n\n            if (!valid) {\n                warnMessage = $t('Provided Zip/Postal Code seems to be invalid.');\n\n                if (postCodeValidator.validatedPostCodeExample.length) {\n                    warnMessage += $t(' Example: ') + postCodeValidator.validatedPostCodeExample.join('; ') + '. ';\n                }\n                warnMessage += $t('If you believe it is the right one you can ignore this notice.');\n            }\n\n            alertDiv.children(':first').text(warnMessage);\n\n            if (valid) {\n                alertDiv.hide();\n            } else {\n                alertDiv.show();\n            }\n        }\n    });\n\n    return $.mage.addressValidation;\n});\n","Magento_Customer/js/change-email-password.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.changeEmailPassword', {\n        options: {\n            changeEmailSelector: '[data-role=change-email]',\n            changePasswordSelector: '[data-role=change-password]',\n            mainContainerSelector: '[data-container=change-email-password]',\n            titleSelector: '[data-title=change-email-password]',\n            emailContainerSelector: '[data-container=change-email]',\n            newPasswordContainerSelector: '[data-container=new-password]',\n            confirmPasswordContainerSelector: '[data-container=confirm-password]',\n            currentPasswordSelector: '[data-input=current-password]',\n            emailSelector: '[data-input=change-email]',\n            newPasswordSelector: '[data-input=new-password]',\n            confirmPasswordSelector: '[data-input=confirm-password]'\n        },\n\n        /**\n         * Create widget\n         * @private\n         */\n        _create: function () {\n            this.element.on('change', $.proxy(function () {\n                this._checkChoice();\n            }, this));\n\n            this._checkChoice();\n            this._bind();\n        },\n\n        /**\n         * Event binding, will monitor change, keyup and paste events.\n         * @private\n         */\n        _bind: function () {\n            this._on($(this.options.emailSelector), {\n                'change': this._updatePasswordFieldWithEmailValue,\n                'keyup': this._updatePasswordFieldWithEmailValue,\n                'paste': this._updatePasswordFieldWithEmailValue\n            });\n        },\n\n        /**\n         * Check choice\n         * @private\n         */\n        _checkChoice: function () {\n            if ($(this.options.changeEmailSelector).is(':checked') &&\n                $(this.options.changePasswordSelector).is(':checked')) {\n                this._showAll();\n            } else if ($(this.options.changeEmailSelector).is(':checked')) {\n                this._showEmail();\n            } else if ($(this.options.changePasswordSelector).is(':checked')) {\n                this._showPassword();\n            } else {\n                this._hideAll();\n            }\n        },\n\n        /**\n         * Show email and password input fields\n         * @private\n         */\n        _showAll: function () {\n            $(this.options.titleSelector).html(this.options.titleChangeEmailAndPassword);\n\n            $(this.options.mainContainerSelector).show();\n            $(this.options.emailContainerSelector).show();\n            $(this.options.newPasswordContainerSelector).show();\n            $(this.options.confirmPasswordContainerSelector).show();\n\n            $(this.options.currentPasswordSelector).attr('data-validate', '{required:true}').prop('disabled', false);\n            $(this.options.emailSelector).attr('data-validate', '{required:true}').prop('disabled', false);\n            this._updatePasswordFieldWithEmailValue();\n            $(this.options.confirmPasswordSelector).attr(\n                'data-validate',\n                '{required:true, equalTo:\"' + this.options.newPasswordSelector + '\"}'\n            ).prop('disabled', false);\n        },\n\n        /**\n         * Hide email and password input fields\n         * @private\n         */\n        _hideAll: function () {\n            $(this.options.mainContainerSelector).hide();\n            $(this.options.emailContainerSelector).hide();\n            $(this.options.newPasswordContainerSelector).hide();\n            $(this.options.confirmPasswordContainerSelector).hide();\n\n            $(this.options.currentPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.emailSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.newPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.confirmPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Show email input fields\n         * @private\n         */\n        _showEmail: function () {\n            this._showAll();\n            $(this.options.titleSelector).html(this.options.titleChangeEmail);\n\n            $(this.options.newPasswordContainerSelector).hide();\n            $(this.options.confirmPasswordContainerSelector).hide();\n\n            $(this.options.newPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n            $(this.options.confirmPasswordSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Show password input fields\n         * @private\n         */\n        _showPassword: function () {\n            this._showAll();\n            $(this.options.titleSelector).html(this.options.titleChangePassword);\n\n            $(this.options.emailContainerSelector).hide();\n\n            $(this.options.emailSelector).removeAttr('data-validate').prop('disabled', true);\n        },\n\n        /**\n         * Update password validation rules with email input field value\n         * @private\n         */\n        _updatePasswordFieldWithEmailValue: function () {\n            $(this.options.newPasswordSelector).attr(\n                'data-validate',\n                '{required:true, ' +\n                '\\'validate-customer-password\\':true, ' +\n                '\\'password-not-equal-to-user-name\\':\\'' + $(this.options.emailSelector).val() + '\\'}'\n            ).prop('disabled', false);\n        }\n    });\n\n    return $.mage.changeEmailPassword;\n});\n","Magento_Customer/js/checkout-balance.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.checkoutBalance', {\n        /**\n         * Initialize store credit events\n         * @private\n         */\n        _create: function () {\n            this.eventData = {\n                price: this.options.balance,\n                totalPrice: 0\n            };\n            this.element.on('change', $.proxy(function (e) {\n                if ($(e.target).is(':checked')) {\n                    this.eventData.price = -1 * this.options.balance;\n                } else {\n                    if (this.options.amountSubstracted) { //eslint-disable-line no-lonely-if\n                        this.eventData.price = parseFloat(this.options.usedAmount);\n                        this.options.amountSubstracted = false;\n                    } else {\n                        this.eventData.price = parseFloat(this.options.balance);\n                    }\n                }\n                this.element.trigger('updateCheckoutPrice', this.eventData);\n            }, this));\n        }\n    });\n\n    return $.mage.checkoutBalance;\n});\n","Magento_Customer/js/password-strength-indicator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Customer/js/zxcvbn',\n    'mage/translate',\n    'mage/validation'\n], function ($, zxcvbn, $t) {\n    'use strict';\n\n    $.widget('mage.passwordStrengthIndicator', {\n        options: {\n            cache: {},\n            passwordSelector: '[type=password]',\n            passwordStrengthMeterSelector: '[data-role=password-strength-meter]',\n            passwordStrengthMeterLabelSelector: '[data-role=password-strength-meter-label]',\n            formSelector: 'form',\n            emailSelector: 'input[type=\"email\"]'\n        },\n\n        /**\n         * Widget initialization\n         * @private\n         */\n        _create: function () {\n            this.options.cache.input = $(this.options.passwordSelector, this.element);\n            this.options.cache.meter = $(this.options.passwordStrengthMeterSelector, this.element);\n            this.options.cache.label = $(this.options.passwordStrengthMeterLabelSelector, this.element);\n\n            // We need to look outside the module for backward compatibility, since someone can already use the module.\n            // @todo Narrow this selector in 2.3 so it doesn't accidentally finds the email field from the\n            // newsletter email field or any other \"email\" field.\n            this.options.cache.email = $(this.options.formSelector).find(this.options.emailSelector);\n            this._bind();\n        },\n\n        /**\n         * Event binding, will monitor change, keyup and paste events.\n         * @private\n         */\n        _bind: function () {\n            this._on(this.options.cache.input, {\n                'change': this._calculateStrength,\n                'keyup': this._calculateStrength,\n                'paste': this._calculateStrength\n            });\n\n            if (this.options.cache.email.length) {\n                this._on(this.options.cache.email, {\n                    'change': this._calculateStrength,\n                    'keyup': this._calculateStrength,\n                    'paste': this._calculateStrength\n                });\n            }\n        },\n\n        /**\n         * Calculate password strength\n         * @private\n         */\n        _calculateStrength: function () {\n            var password = this._getPassword(),\n                isEmpty = password.length === 0,\n                zxcvbnScore,\n                displayScore,\n                isValid;\n\n            // Display score is based on combination of whether password is empty, valid, and zxcvbn strength\n            if (isEmpty) {\n                displayScore = 0;\n            } else {\n                this.options.cache.input.rules('add', {\n                    'password-not-equal-to-user-name': this.options.cache.email.val()\n                });\n\n                // We should only perform this check in case there is an email field on screen\n                if (this.options.cache.email.length &&\n                    password.toLowerCase() === this.options.cache.email.val().toLowerCase()) {\n                    displayScore = 1;\n                } else {\n                    isValid = $.validator.validateSingleElement(this.options.cache.input);\n                    zxcvbnScore = zxcvbn(password).score;\n                    displayScore = isValid && zxcvbnScore > 0 ? zxcvbnScore : 1;\n                }\n            }\n\n            // Update label\n            this._displayStrength(displayScore);\n        },\n\n        /**\n         * Display strength\n         * @param {Number} displayScore\n         * @private\n         */\n        _displayStrength: function (displayScore) {\n            var strengthLabel = '',\n                className;\n\n            switch (displayScore) {\n                case 0:\n                    strengthLabel = $t('No Password');\n                    className = 'password-none';\n                    break;\n\n                case 1:\n                    strengthLabel = $t('Weak');\n                    className = 'password-weak';\n                    break;\n\n                case 2:\n                    strengthLabel = $t('Medium');\n                    className = 'password-medium';\n                    break;\n\n                case 3:\n                    strengthLabel = $t('Strong');\n                    className = 'password-strong';\n                    break;\n\n                case 4:\n                    strengthLabel = $t('Very Strong');\n                    className = 'password-very-strong';\n                    break;\n            }\n\n            this.options.cache.meter\n                .removeClass()\n                .addClass(className);\n            this.options.cache.label.text(strengthLabel);\n        },\n\n        /**\n         * Get password value\n         * @returns {*}\n         * @private\n         */\n        _getPassword: function () {\n            return this.options.cache.input.val();\n        }\n    });\n\n    return $.mage.passwordStrengthIndicator;\n});\n","Magento_Customer/js/section-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['underscore'], function (_) {\n    'use strict';\n\n    var baseUrls = [],\n        sections = [],\n        clientSideSections = [],\n        sectionNames = [],\n        canonize;\n\n    /**\n     * @param {String} url\n     * @return {String}\n     */\n    canonize = function (url) {\n        var route = url;\n\n        _.some(baseUrls, function (baseUrl) {\n            route = url.replace(baseUrl, '');\n\n            return route !== url;\n        });\n\n        return route.replace(/^\\/?index.php\\/?/, '').toLowerCase();\n    };\n\n    return {\n        /**\n         * Returns a list of sections which should be invalidated for given URL.\n         * @param {String} url - URL which was requested.\n         * @return {Object} - List of sections to invalidate.\n         */\n        getAffectedSections: function (url) {\n            var route = canonize(url),\n                actions = _.find(sections, function (val, section) {\n                    var matched;\n\n                    // Covers the case where \"*\" works as a glob pattern.\n                    if (section.indexOf('*') >= 0) {\n                        section = section.replace(/\\*/g, '[^/]+') + '$';\n                        matched = route.match(section);\n\n                        return matched && matched[0] === route;\n                    }\n\n                    return route.indexOf(section) === 0;\n                });\n\n            return _.union(_.toArray(actions), sections['*']);\n        },\n\n        /**\n         * Filters the list of given sections to the ones defined as client side.\n         * @param {Object} allSections - List of sections to check.\n         * @return {Object} - List of filtered sections.\n         */\n        filterClientSideSections: function (allSections) {\n            return _.difference(allSections, clientSideSections);\n        },\n\n        /**\n         * Tells if section is defined as client side.\n         * @param {String} sectionName - Name of the section to check.\n         * @return {Boolean}\n         */\n        isClientSideSection: function (sectionName) {\n            return _.contains(clientSideSections, sectionName);\n        },\n\n        /**\n         * Returns array of section names.\n         * @returns {Array}\n         */\n        getSectionNames: function () {\n            return sectionNames;\n        },\n\n        /**\n         * @param {Object} options\n         * @constructor\n         */\n        'Magento_Customer/js/section-config': function (options) {\n            baseUrls = options.baseUrls;\n            sections = options.sections;\n            clientSideSections = options.clientSideSections;\n            sectionNames = options.sectionNames;\n        }\n    };\n});\n","Magento_Customer/js/address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/confirm',\n    'jquery-ui-modules/widget',\n    'mage/translate'\n], function ($, confirm) {\n    'use strict';\n\n    $.widget('mage.address', {\n        /**\n         * Options common to all instances of this widget.\n         * @type {Object}\n         */\n        options: {\n            deleteConfirmMessage: $.mage.__('Are you sure you want to delete this address?')\n        },\n\n        /**\n         * Bind event handlers for adding and deleting addresses.\n         * @private\n         */\n        _create: function () {\n            var options         = this.options,\n                addAddress      = options.addAddress,\n                deleteAddress   = options.deleteAddress;\n\n            if (addAddress) {\n                $(document).on('click', addAddress, this._addAddress.bind(this));\n            }\n\n            if (deleteAddress) {\n                $(document).on('click', deleteAddress, this._deleteAddress.bind(this));\n            }\n        },\n\n        /**\n         * Add a new address.\n         * @private\n         */\n        _addAddress: function () {\n            window.location = this.options.addAddressLocation;\n        },\n\n        /**\n         * Delete the address whose id is specified in a data attribute after confirmation from the user.\n         * @private\n         * @param {jQuery.Event} e\n         * @return {Boolean}\n         */\n        _deleteAddress: function (e) {\n            var self = this;\n\n            confirm({\n                content: this.options.deleteConfirmMessage,\n                actions: {\n\n                    /** @inheritdoc */\n                    confirm: function () {\n                        if (typeof $(e.target).parent().data('address') !== 'undefined') {\n                            window.location = self.options.deleteUrlPrefix + $(e.target).parent().data('address') +\n                                '/form_key/' + $.mage.cookies.get('form_key');\n                        } else {\n                            window.location = self.options.deleteUrlPrefix + $(e.target).data('address') +\n                                '/form_key/' + $.mage.cookies.get('form_key');\n                        }\n                    }\n                }\n            });\n\n            return false;\n        }\n    });\n\n    return $.mage.address;\n});\n","Magento_Customer/js/action/check-email-availability.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'mage/storage',\n    'Magento_Checkout/js/model/url-builder'\n], function (storage, urlBuilder) {\n    'use strict';\n\n    return function (deferred, email) {\n        return storage.post(\n            urlBuilder.createUrl('/customers/isEmailAvailable', {}),\n            JSON.stringify({\n                customerEmail: email\n            }),\n            false\n        ).done(function (isEmailAvailable) {\n            if (isEmailAvailable) {\n                deferred.resolve();\n            } else {\n                deferred.reject();\n            }\n        }).fail(function () {\n            deferred.reject();\n        });\n    };\n});\n","Magento_Customer/js/action/login.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/storage',\n    'Magento_Ui/js/model/messageList',\n    'Magento_Customer/js/customer-data',\n    'mage/translate'\n], function ($, storage, globalMessageList, customerData, $t) {\n    'use strict';\n\n    var callbacks = [],\n\n        /**\n         * @param {Object} loginData\n         * @param {String} redirectUrl\n         * @param {*} isGlobal\n         * @param {Object} messageContainer\n         */\n        action = function (loginData, redirectUrl, isGlobal, messageContainer) {\n            messageContainer = messageContainer || globalMessageList;\n            let customerLoginUrl = 'customer/ajax/login';\n\n            if (loginData.customerLoginUrl) {\n                customerLoginUrl = loginData.customerLoginUrl;\n                delete loginData.customerLoginUrl;\n            }\n\n            return storage.post(\n                customerLoginUrl,\n                JSON.stringify(loginData),\n                isGlobal\n            ).done(function (response) {\n                if (response.errors) {\n                    messageContainer.addErrorMessage(response);\n                    callbacks.forEach(function (callback) {\n                        callback(loginData);\n                    });\n                } else {\n                    callbacks.forEach(function (callback) {\n                        callback(loginData);\n                    });\n                    customerData.invalidate(['customer']);\n\n                    if (response.redirectUrl) {\n                        window.location.href = response.redirectUrl;\n                    } else if (redirectUrl) {\n                        window.location.href = redirectUrl;\n                    } else {\n                        location.reload();\n                    }\n                }\n            }).fail(function () {\n                messageContainer.addErrorMessage({\n                    'message': $t('Could not authenticate. Please try again later')\n                });\n                callbacks.forEach(function (callback) {\n                    callback(loginData);\n                });\n            });\n        };\n\n    /**\n     * @param {Function} callback\n     */\n    action.registerLoginCallback = function (callback) {\n        callbacks.push(callback);\n    };\n\n    return action;\n});\n","Magento_Customer/js/view/authentication-popup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'ko',\n    'Magento_Ui/js/form/form',\n    'Magento_Customer/js/action/login',\n    'Magento_Customer/js/customer-data',\n    'Magento_Customer/js/model/authentication-popup',\n    'mage/translate',\n    'mage/url',\n    'Magento_Ui/js/modal/alert',\n    'mage/validation'\n], function ($, ko, Component, loginAction, customerData, authenticationPopup, $t, url, alert) {\n    'use strict';\n\n    return Component.extend({\n        registerUrl: window.authenticationPopup.customerRegisterUrl,\n        forgotPasswordUrl: window.authenticationPopup.customerForgotPasswordUrl,\n        autocomplete: window.authenticationPopup.autocomplete,\n        modalWindow: null,\n        isLoading: ko.observable(false),\n\n        defaults: {\n            template: 'Magento_Customer/authentication-popup'\n        },\n\n        /**\n         * Init\n         */\n        initialize: function () {\n            var self = this;\n\n            this._super();\n            url.setBaseUrl(window.authenticationPopup.baseUrl);\n            loginAction.registerLoginCallback(function () {\n                self.isLoading(false);\n            });\n        },\n\n        /**\n         * Sets modal on given HTML element with on demand initialization.\n         */\n        setModalElement: function (element) {\n            var cart = customerData.get('cart');\n\n            if (cart().isGuestCheckoutAllowed === false) {\n                this.createPopup(element);\n            } else {\n                cart.subscribe(function (cartData) {\n                    if (cartData.isGuestCheckoutAllowed === false) {\n                        this.createPopup(element);\n                    }\n                }, this);\n            }\n        },\n\n        /**\n         * Initializes authentication modal on given HTML element.\n         */\n        createPopup: function (element) {\n            if (authenticationPopup.modalWindow == null) {\n                authenticationPopup.createPopUp(element);\n            }\n        },\n\n        /** Is login form enabled for current customer */\n        isActive: function () {\n            var customer = customerData.get('customer');\n\n            return customer() == false; //eslint-disable-line eqeqeq\n        },\n\n        /** Show login popup window */\n        showModal: function () {\n            if (this.modalWindow) {\n                $(this.modalWindow).modal('openModal');\n            } else {\n                alert({\n                    content: $t('Guest checkout is disabled.')\n                });\n            }\n        },\n\n        /**\n         * Provide login action\n         *\n         * @return {Boolean}\n         */\n        login: function (formUiElement, event) {\n            var loginData = {},\n                formElement = $(event.currentTarget),\n                formDataArray = formElement.serializeArray();\n\n            event.stopPropagation();\n            formDataArray.forEach(function (entry) {\n                loginData[entry.name] = entry.value;\n            });\n            loginData['customerLoginUrl'] = window.authenticationPopup.customerLoginUrl;\n            if (formElement.validation() &&\n                formElement.validation('isValid')\n            ) {\n                this.isLoading(true);\n                loginAction(loginData);\n            }\n\n            return false;\n        }\n    });\n});\n","Magento_Customer/js/view/customer.js":"/**\n* Copyright \u00a9 Magento, Inc. All rights reserved.\n* See COPYING.txt for license details.\n*/\n\ndefine([\n    'uiComponent',\n    'Magento_Customer/js/customer-data'\n], function (Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.customer = customerData.get('customer');\n        }\n    });\n});\n","Magento_Customer/js/invalidation-rules/website-rule.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'uiClass'\n], function (Element) {\n    'use strict';\n\n    return Element.extend({\n\n        defaults: {\n            scopeConfig: {}\n        },\n\n        /**\n         * Takes website id from current customer data and compare it with current website id\n         * If customer belongs to another scope, we need to invalidate current section\n         *\n         * @param {Object} customerData\n         */\n        process: function (customerData) {\n            var customer = customerData.get('customer');\n\n            if (this.scopeConfig && customer() &&\n                ~~customer().websiteId !== ~~this.scopeConfig.websiteId && ~~customer().websiteId !== 0) {\n                customerData.reload(['customer']);\n            }\n        }\n    });\n});\n","Magento_Customer/js/model/customer-addresses.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'ko',\n    './customer/address'\n], function ($, ko, Address) {\n    'use strict';\n\n    var isLoggedIn = ko.observable(window.isCustomerLoggedIn);\n\n    return {\n        /**\n         * @return {Array}\n         */\n        getAddressItems: function () {\n            var items = [],\n                customerData = window.customerData;\n\n            if (isLoggedIn()) {\n                if (Object.keys(customerData).length) {\n                    $.each(customerData.addresses, function (key, item) {\n                        items.push(new Address(item));\n                    });\n                }\n            }\n\n            return items;\n        }\n    };\n});\n","Magento_Customer/js/model/authentication-popup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/modal'\n], function ($, modal) {\n    'use strict';\n\n    return {\n        modalWindow: null,\n\n        /**\n         * Create popUp window for provided element\n         *\n         * @param {HTMLElement} element\n         */\n        createPopUp: function (element) {\n            var options = {\n                'type': 'popup',\n                'modalClass': 'popup-authentication',\n                'focus': '[name=username]',\n                'responsive': true,\n                'innerScroll': true,\n                'trigger': '.proceed-to-checkout',\n                'buttons': []\n            };\n\n            this.modalWindow = element;\n            modal(options, $(this.modalWindow));\n        },\n\n        /** Show login popup window */\n        showModal: function () {\n            $(this.modalWindow).modal('openModal').trigger('contentUpdated');\n        }\n    };\n});\n","Magento_Customer/js/model/address-list.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'ko',\n    './customer-addresses'\n], function (ko, defaultProvider) {\n    'use strict';\n\n    return ko.observableArray(defaultProvider.getAddressItems());\n});\n","Magento_Customer/js/model/customer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'ko',\n    'underscore',\n    './address-list'\n], function ($, ko, _, addressList) {\n    'use strict';\n\n    var isLoggedIn = ko.observable(window.isCustomerLoggedIn),\n        customerData = {};\n\n    if (isLoggedIn()) {\n        customerData = window.customerData;\n    } else {\n        customerData = {};\n    }\n\n    return {\n        customerData: customerData,\n        customerDetails: {},\n        isLoggedIn: isLoggedIn,\n\n        /**\n         * @param {Boolean} flag\n         */\n        setIsLoggedIn: function (flag) {\n            isLoggedIn(flag);\n        },\n\n        /**\n         * @return {Array}\n         */\n        getBillingAddressList: function () {\n            return addressList();\n        },\n\n        /**\n         * @return {Array}\n         */\n        getShippingAddressList: function () {\n            return addressList();\n        },\n\n        /**\n         * @param {String} fieldName\n         * @param {*} value\n         */\n        setDetails: function (fieldName, value) {\n            if (fieldName) {\n                this.customerDetails[fieldName] = value;\n            }\n        },\n\n        /**\n         * @param {String} fieldName\n         * @return {*}\n         */\n        getDetails: function (fieldName) {\n            if (fieldName) {\n                if (this.customerDetails.hasOwnProperty(fieldName)) {\n                    return this.customerDetails[fieldName];\n                }\n\n                return undefined;\n            }\n\n            return this.customerDetails;\n        },\n\n        /**\n         * @param {Array} address\n         * @return {Number}\n         */\n        addCustomerAddress: function (address) {\n            var fields = [\n                    'customer_id', 'country_id', 'street', 'company', 'telephone', 'fax', 'postcode', 'city',\n                    'firstname', 'lastname', 'middlename', 'prefix', 'suffix', 'vat_id', 'default_billing',\n                    'default_shipping'\n                ],\n                customerAddress = {},\n                hasAddress = 0,\n                existingAddress;\n\n            if (!this.customerData.addresses) {\n                this.customerData.addresses = [];\n            }\n\n            customerAddress = _.pick(address, fields);\n\n            if (address.hasOwnProperty('region_id')) {\n                customerAddress.region = {\n                    'region_id': address['region_id'],\n                    region: address.region\n                };\n            }\n\n            for (existingAddress in this.customerData.addresses) {\n                if (this.customerData.addresses.hasOwnProperty(existingAddress)) {\n                    if (_.isEqual(this.customerData.addresses[existingAddress], customerAddress)) { //eslint-disable-line\n                        hasAddress = existingAddress;\n                        break;\n                    }\n                }\n            }\n\n            if (hasAddress === 0) {\n                return this.customerData.addresses.push(customerAddress) - 1;\n            }\n\n            return hasAddress;\n        },\n\n        /**\n         * @param {*} addressId\n         * @return {Boolean}\n         */\n        setAddressAsDefaultBilling: function (addressId) {\n            if (this.customerData.addresses[addressId]) {\n                this.customerData.addresses[addressId]['default_billing'] = 1;\n\n                return true;\n            }\n\n            return false;\n        },\n\n        /**\n         * @param {*} addressId\n         * @return {Boolean}\n         */\n        setAddressAsDefaultShipping: function (addressId) {\n            if (this.customerData.addresses[addressId]) {\n                this.customerData.addresses[addressId]['default_shipping'] = 1;\n\n                return true;\n            }\n\n            return false;\n        }\n    };\n});\n","Magento_Customer/js/model/customer/address.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(['underscore'], function (_) {\n    'use strict';\n\n    /**\n     * Returns new address object.\n     *\n     * @param {Object} addressData\n     * @return {Object}\n     */\n    return function (addressData) {\n        var regionId;\n\n        if (addressData.region['region_id'] && addressData.region['region_id'] !== '0') {\n            regionId = addressData.region['region_id'] + '';\n        }\n\n        return {\n            customerAddressId: addressData.id,\n            email: addressData.email,\n            countryId: addressData['country_id'],\n            regionId: regionId,\n            regionCode: addressData.region['region_code'],\n            region: addressData.region.region,\n            customerId: addressData['customer_id'],\n            street: addressData.street,\n            company: addressData.company,\n            telephone: addressData.telephone,\n            fax: addressData.fax,\n            postcode: addressData.postcode,\n            city: addressData.city,\n            firstname: addressData.firstname,\n            lastname: addressData.lastname,\n            middlename: addressData.middlename,\n            prefix: addressData.prefix,\n            suffix: addressData.suffix,\n            vatId: addressData['vat_id'],\n            sameAsBilling: addressData['same_as_billing'],\n            saveInAddressBook: addressData['save_in_address_book'],\n            customAttributes: _.toArray(addressData['custom_attributes']).reverse(),\n\n            /**\n             * @return {*}\n             */\n            isDefaultShipping: function () {\n                return addressData['default_shipping'];\n            },\n\n            /**\n             * @return {*}\n             */\n            isDefaultBilling: function () {\n                return addressData['default_billing'];\n            },\n\n            /**\n             * @return {*}\n             */\n            getAddressInline: function () {\n                return addressData.inline;\n            },\n\n            /**\n             * @return {String}\n             */\n            getType: function () {\n                return 'customer-address';\n            },\n\n            /**\n             * @return {String}\n             */\n            getKey: function () {\n                return this.getType() + this.customerAddressId;\n            },\n\n            /**\n             * @return {String}\n             */\n            getCacheKey: function () {\n                return this.getKey();\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            isEditable: function () {\n                return false;\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            canUseForBilling: function () {\n                return true;\n            }\n        };\n    };\n});\n","Mageplaza_Core/js/bootstrap.min.js":"/*!\n * Bootstrap v5.0.2 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e(require(\"@popperjs/core\")):\"function\"==typeof define&&define.amd?define([\"@popperjs/core\"],e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).bootstrap=e(t.Popper)}(this,(function(t){\"use strict\";function e(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach((function(s){if(\"default\"!==s){var i=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,i.get?i:{enumerable:!0,get:function(){return t[s]}})}})),e.default=t,Object.freeze(e)}var s=e(t);const i={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter(t=>t.matches(e)),parents(t,e){const s=[];let i=t.parentNode;for(;i&&i.nodeType===Node.ELEMENT_NODE&&3!==i.nodeType;)i.matches(e)&&s.push(i),i=i.parentNode;return s},prev(t,e){let s=t.previousElementSibling;for(;s;){if(s.matches(e))return[s];s=s.previousElementSibling}return[]},next(t,e){let s=t.nextElementSibling;for(;s;){if(s.matches(e))return[s];s=s.nextElementSibling}return[]}},n=t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t},o=t=>{let e=t.getAttribute(\"data-bs-target\");if(!e||\"#\"===e){let s=t.getAttribute(\"href\");if(!s||!s.includes(\"#\")&&!s.startsWith(\".\"))return null;s.includes(\"#\")&&!s.startsWith(\"#\")&&(s=\"#\"+s.split(\"#\")[1]),e=s&&\"#\"!==s?s.trim():null}return e},r=t=>{const e=o(t);return e&&document.querySelector(e)?e:null},a=t=>{const e=o(t);return e?document.querySelector(e):null},l=t=>{t.dispatchEvent(new Event(\"transitionend\"))},c=t=>!(!t||\"object\"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),h=t=>c(t)?t.jquery?t[0]:t:\"string\"==typeof t&&t.length>0?i.findOne(t):null,d=(t,e,s)=>{Object.keys(s).forEach(i=>{const n=s[i],o=e[i],r=o&&c(o)?\"element\":null==(a=o)?\"\"+a:{}.toString.call(a).match(/\\s([a-z]+)/i)[1].toLowerCase();var a;if(!new RegExp(n).test(r))throw new TypeError(`${t.toUpperCase()}: Option \"${i}\" provided type \"${r}\" but expected type \"${n}\".`)})},u=t=>!(!c(t)||0===t.getClientRects().length)&&\"visible\"===getComputedStyle(t).getPropertyValue(\"visibility\"),g=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains(\"disabled\")||(void 0!==t.disabled?t.disabled:t.hasAttribute(\"disabled\")&&\"false\"!==t.getAttribute(\"disabled\")),p=t=>{if(!document.documentElement.attachShadow)return null;if(\"function\"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?p(t.parentNode):null},f=()=>{},m=t=>t.offsetHeight,_=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute(\"data-bs-no-jquery\")?t:null},b=[],v=()=>\"rtl\"===document.documentElement.dir,y=t=>{var e;e=()=>{const e=_();if(e){const s=t.NAME,i=e.fn[s];e.fn[s]=t.jQueryInterface,e.fn[s].Constructor=t,e.fn[s].noConflict=()=>(e.fn[s]=i,t.jQueryInterface)}},\"loading\"===document.readyState?(b.length||document.addEventListener(\"DOMContentLoaded\",()=>{b.forEach(t=>t())}),b.push(e)):e()},w=t=>{\"function\"==typeof t&&t()},E=(t,e,s=!0)=>{if(!s)return void w(t);const i=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:s}=window.getComputedStyle(t);const i=Number.parseFloat(e),n=Number.parseFloat(s);return i||n?(e=e.split(\",\")[0],s=s.split(\",\")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(s))):0})(e)+5;let n=!1;const o=({target:s})=>{s===e&&(n=!0,e.removeEventListener(\"transitionend\",o),w(t))};e.addEventListener(\"transitionend\",o),setTimeout(()=>{n||l(e)},i)},A=(t,e,s,i)=>{let n=t.indexOf(e);if(-1===n)return t[!s&&i?t.length-1:0];const o=t.length;return n+=s?1:-1,i&&(n=(n+o)%o),t[Math.max(0,Math.min(n,o-1))]},T=/[^.]*(?=\\..*)\\.|.*/,C=/\\..*/,k=/::\\d+$/,L={};let O=1;const D={mouseenter:\"mouseover\",mouseleave:\"mouseout\"},I=/^(mouseenter|mouseleave)/i,N=new Set([\"click\",\"dblclick\",\"mouseup\",\"mousedown\",\"contextmenu\",\"mousewheel\",\"DOMMouseScroll\",\"mouseover\",\"mouseout\",\"mousemove\",\"selectstart\",\"selectend\",\"keydown\",\"keypress\",\"keyup\",\"orientationchange\",\"touchstart\",\"touchmove\",\"touchend\",\"touchcancel\",\"pointerdown\",\"pointermove\",\"pointerup\",\"pointerleave\",\"pointercancel\",\"gesturestart\",\"gesturechange\",\"gestureend\",\"focus\",\"blur\",\"change\",\"reset\",\"select\",\"submit\",\"focusin\",\"focusout\",\"load\",\"unload\",\"beforeunload\",\"resize\",\"move\",\"DOMContentLoaded\",\"readystatechange\",\"error\",\"abort\",\"scroll\"]);function S(t,e){return e&&`${e}::${O++}`||t.uidEvent||O++}function x(t){const e=S(t);return t.uidEvent=e,L[e]=L[e]||{},L[e]}function M(t,e,s=null){const i=Object.keys(t);for(let n=0,o=i.length;n<o;n++){const o=t[i[n]];if(o.originalHandler===e&&o.delegationSelector===s)return o}return null}function P(t,e,s){const i=\"string\"==typeof e,n=i?s:e;let o=R(t);return N.has(o)||(o=t),[i,n,o]}function j(t,e,s,i,n){if(\"string\"!=typeof e||!t)return;if(s||(s=i,i=null),I.test(e)){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};i?i=t(i):s=t(s)}const[o,r,a]=P(e,s,i),l=x(t),c=l[a]||(l[a]={}),h=M(c,r,o?s:null);if(h)return void(h.oneOff=h.oneOff&&n);const d=S(r,e.replace(T,\"\")),u=o?function(t,e,s){return function i(n){const o=t.querySelectorAll(e);for(let{target:r}=n;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return n.delegateTarget=r,i.oneOff&&B.off(t,n.type,e,s),s.apply(r,[n]);return null}}(t,s,i):function(t,e){return function s(i){return i.delegateTarget=t,s.oneOff&&B.off(t,i.type,e),e.apply(t,[i])}}(t,s);u.delegationSelector=o?s:null,u.originalHandler=r,u.oneOff=n,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function H(t,e,s,i,n){const o=M(e[s],i,n);o&&(t.removeEventListener(s,o,Boolean(n)),delete e[s][o.uidEvent])}function R(t){return t=t.replace(C,\"\"),D[t]||t}const B={on(t,e,s,i){j(t,e,s,i,!1)},one(t,e,s,i){j(t,e,s,i,!0)},off(t,e,s,i){if(\"string\"!=typeof e||!t)return;const[n,o,r]=P(e,s,i),a=r!==e,l=x(t),c=e.startsWith(\".\");if(void 0!==o){if(!l||!l[r])return;return void H(t,l,r,o,n?s:null)}c&&Object.keys(l).forEach(s=>{!function(t,e,s,i){const n=e[s]||{};Object.keys(n).forEach(o=>{if(o.includes(i)){const i=n[o];H(t,e,s,i.originalHandler,i.delegationSelector)}})}(t,l,s,e.slice(1))});const h=l[r]||{};Object.keys(h).forEach(s=>{const i=s.replace(k,\"\");if(!a||e.includes(i)){const e=h[s];H(t,l,r,e.originalHandler,e.delegationSelector)}})},trigger(t,e,s){if(\"string\"!=typeof e||!t)return null;const i=_(),n=R(e),o=e!==n,r=N.has(n);let a,l=!0,c=!0,h=!1,d=null;return o&&i&&(a=i.Event(e,s),i(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent(\"HTMLEvents\"),d.initEvent(n,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==s&&Object.keys(s).forEach(t=>{Object.defineProperty(d,t,{get:()=>s[t]})}),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},$=new Map;var W={set(t,e,s){$.has(t)||$.set(t,new Map);const i=$.get(t);i.has(e)||0===i.size?i.set(e,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(i.keys())[0]}.`)},get:(t,e)=>$.has(t)&&$.get(t).get(e)||null,remove(t,e){if(!$.has(t))return;const s=$.get(t);s.delete(e),0===s.size&&$.delete(t)}};class q{constructor(t){(t=h(t))&&(this._element=t,W.set(this._element,this.constructor.DATA_KEY,this))}dispose(){W.remove(this._element,this.constructor.DATA_KEY),B.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach(t=>{this[t]=null})}_queueCallback(t,e,s=!0){E(t,e,s)}static getInstance(t){return W.get(t,this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,\"object\"==typeof e?e:null)}static get VERSION(){return\"5.0.2\"}static get NAME(){throw new Error('You have to implement the static method \"NAME\", for each component!')}static get DATA_KEY(){return\"bs.\"+this.NAME}static get EVENT_KEY(){return\".\"+this.DATA_KEY}}class z extends q{static get NAME(){return\"alert\"}close(t){const e=t?this._getRootElement(t):this._element,s=this._triggerCloseEvent(e);null===s||s.defaultPrevented||this._removeElement(e)}_getRootElement(t){return a(t)||t.closest(\".alert\")}_triggerCloseEvent(t){return B.trigger(t,\"close.bs.alert\")}_removeElement(t){t.classList.remove(\"show\");const e=t.classList.contains(\"fade\");this._queueCallback(()=>this._destroyElement(t),t,e)}_destroyElement(t){t.remove(),B.trigger(t,\"closed.bs.alert\")}static jQueryInterface(t){return this.each((function(){const e=z.getOrCreateInstance(this);\"close\"===t&&e[t](this)}))}static handleDismiss(t){return function(e){e&&e.preventDefault(),t.close(this)}}}B.on(document,\"click.bs.alert.data-api\",'[data-bs-dismiss=\"alert\"]',z.handleDismiss(new z)),y(z);class F extends q{static get NAME(){return\"button\"}toggle(){this._element.setAttribute(\"aria-pressed\",this._element.classList.toggle(\"active\"))}static jQueryInterface(t){return this.each((function(){const e=F.getOrCreateInstance(this);\"toggle\"===t&&e[t]()}))}}function U(t){return\"true\"===t||\"false\"!==t&&(t===Number(t).toString()?Number(t):\"\"===t||\"null\"===t?null:t)}function K(t){return t.replace(/[A-Z]/g,t=>\"-\"+t.toLowerCase())}B.on(document,\"click.bs.button.data-api\",'[data-bs-toggle=\"button\"]',t=>{t.preventDefault();const e=t.target.closest('[data-bs-toggle=\"button\"]');F.getOrCreateInstance(e).toggle()}),y(F);const V={setDataAttribute(t,e,s){t.setAttribute(\"data-bs-\"+K(e),s)},removeDataAttribute(t,e){t.removeAttribute(\"data-bs-\"+K(e))},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter(t=>t.startsWith(\"bs\")).forEach(s=>{let i=s.replace(/^bs/,\"\");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=U(t.dataset[s])}),e},getDataAttribute:(t,e)=>U(t.getAttribute(\"data-bs-\"+K(e))),offset(t){const e=t.getBoundingClientRect();return{top:e.top+document.body.scrollTop,left:e.left+document.body.scrollLeft}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},Q={interval:5e3,keyboard:!0,slide:!1,pause:\"hover\",wrap:!0,touch:!0},X={interval:\"(number|boolean)\",keyboard:\"boolean\",slide:\"(boolean|string)\",pause:\"(string|boolean)\",wrap:\"boolean\",touch:\"boolean\"},Y=\"next\",G=\"prev\",Z=\"left\",J=\"right\",tt={ArrowLeft:J,ArrowRight:Z};class et extends q{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=i.findOne(\".carousel-indicators\",this._element),this._touchSupported=\"ontouchstart\"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return Q}static get NAME(){return\"carousel\"}next(){this._slide(Y)}nextWhenVisible(){!document.hidden&&u(this._element)&&this.next()}prev(){this._slide(G)}pause(t){t||(this._isPaused=!0),i.findOne(\".carousel-item-next, .carousel-item-prev\",this._element)&&(l(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=i.findOne(\".active.carousel-item\",this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void B.one(this._element,\"slid.bs.carousel\",()=>this.to(t));if(e===t)return this.pause(),void this.cycle();const s=t>e?Y:G;this._slide(s,this._items[t])}_getConfig(t){return t={...Q,...V.getDataAttributes(this._element),...\"object\"==typeof t?t:{}},d(\"carousel\",t,X),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?J:Z)}_addEventListeners(){this._config.keyboard&&B.on(this._element,\"keydown.bs.carousel\",t=>this._keydown(t)),\"hover\"===this._config.pause&&(B.on(this._element,\"mouseenter.bs.carousel\",t=>this.pause(t)),B.on(this._element,\"mouseleave.bs.carousel\",t=>this.cycle(t))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>{!this._pointerEvent||\"pen\"!==t.pointerType&&\"touch\"!==t.pointerType?this._pointerEvent||(this.touchStartX=t.touches[0].clientX):this.touchStartX=t.clientX},e=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},s=t=>{!this._pointerEvent||\"pen\"!==t.pointerType&&\"touch\"!==t.pointerType||(this.touchDeltaX=t.clientX-this.touchStartX),this._handleSwipe(),\"hover\"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(t=>this.cycle(t),500+this._config.interval))};i.find(\".carousel-item img\",this._element).forEach(t=>{B.on(t,\"dragstart.bs.carousel\",t=>t.preventDefault())}),this._pointerEvent?(B.on(this._element,\"pointerdown.bs.carousel\",e=>t(e)),B.on(this._element,\"pointerup.bs.carousel\",t=>s(t)),this._element.classList.add(\"pointer-event\")):(B.on(this._element,\"touchstart.bs.carousel\",e=>t(e)),B.on(this._element,\"touchmove.bs.carousel\",t=>e(t)),B.on(this._element,\"touchend.bs.carousel\",t=>s(t)))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=tt[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?i.find(\".carousel-item\",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const s=t===Y;return A(this._items,e,s,this._config.wrap)}_triggerSlideEvent(t,e){const s=this._getItemIndex(t),n=this._getItemIndex(i.findOne(\".active.carousel-item\",this._element));return B.trigger(this._element,\"slide.bs.carousel\",{relatedTarget:t,direction:e,from:n,to:s})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=i.findOne(\".active\",this._indicatorsElement);e.classList.remove(\"active\"),e.removeAttribute(\"aria-current\");const s=i.find(\"[data-bs-target]\",this._indicatorsElement);for(let e=0;e<s.length;e++)if(Number.parseInt(s[e].getAttribute(\"data-bs-slide-to\"),10)===this._getItemIndex(t)){s[e].classList.add(\"active\"),s[e].setAttribute(\"aria-current\",\"true\");break}}}_updateInterval(){const t=this._activeElement||i.findOne(\".active.carousel-item\",this._element);if(!t)return;const e=Number.parseInt(t.getAttribute(\"data-bs-interval\"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}_slide(t,e){const s=this._directionToOrder(t),n=i.findOne(\".active.carousel-item\",this._element),o=this._getItemIndex(n),r=e||this._getItemByOrder(s,n),a=this._getItemIndex(r),l=Boolean(this._interval),c=s===Y,h=c?\"carousel-item-start\":\"carousel-item-end\",d=c?\"carousel-item-next\":\"carousel-item-prev\",u=this._orderToDirection(s);if(r&&r.classList.contains(\"active\"))return void(this._isSliding=!1);if(this._isSliding)return;if(this._triggerSlideEvent(r,u).defaultPrevented)return;if(!n||!r)return;this._isSliding=!0,l&&this.pause(),this._setActiveIndicatorElement(r),this._activeElement=r;const g=()=>{B.trigger(this._element,\"slid.bs.carousel\",{relatedTarget:r,direction:u,from:o,to:a})};if(this._element.classList.contains(\"slide\")){r.classList.add(d),m(r),n.classList.add(h),r.classList.add(h);const t=()=>{r.classList.remove(h,d),r.classList.add(\"active\"),n.classList.remove(\"active\",d,h),this._isSliding=!1,setTimeout(g,0)};this._queueCallback(t,n,!0)}else n.classList.remove(\"active\"),r.classList.add(\"active\"),this._isSliding=!1,g();l&&this.cycle()}_directionToOrder(t){return[J,Z].includes(t)?v()?t===Z?G:Y:t===Z?Y:G:t}_orderToDirection(t){return[Y,G].includes(t)?v()?t===G?Z:J:t===G?J:Z:t}static carouselInterface(t,e){const s=et.getOrCreateInstance(t,e);let{_config:i}=s;\"object\"==typeof e&&(i={...i,...e});const n=\"string\"==typeof e?e:i.slide;if(\"number\"==typeof e)s.to(e);else if(\"string\"==typeof n){if(void 0===s[n])throw new TypeError(`No method named \"${n}\"`);s[n]()}else i.interval&&i.ride&&(s.pause(),s.cycle())}static jQueryInterface(t){return this.each((function(){et.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=a(this);if(!e||!e.classList.contains(\"carousel\"))return;const s={...V.getDataAttributes(e),...V.getDataAttributes(this)},i=this.getAttribute(\"data-bs-slide-to\");i&&(s.interval=!1),et.carouselInterface(e,s),i&&et.getInstance(e).to(i),t.preventDefault()}}B.on(document,\"click.bs.carousel.data-api\",\"[data-bs-slide], [data-bs-slide-to]\",et.dataApiClickHandler),B.on(window,\"load.bs.carousel.data-api\",()=>{const t=i.find('[data-bs-ride=\"carousel\"]');for(let e=0,s=t.length;e<s;e++)et.carouselInterface(t[e],et.getInstance(t[e]))}),y(et);const st={toggle:!0,parent:\"\"},it={toggle:\"boolean\",parent:\"(string|element)\"};class nt extends q{constructor(t,e){super(t),this._isTransitioning=!1,this._config=this._getConfig(e),this._triggerArray=i.find(`[data-bs-toggle=\"collapse\"][href=\"#${this._element.id}\"],[data-bs-toggle=\"collapse\"][data-bs-target=\"#${this._element.id}\"]`);const s=i.find('[data-bs-toggle=\"collapse\"]');for(let t=0,e=s.length;t<e;t++){const e=s[t],n=r(e),o=i.find(n).filter(t=>t===this._element);null!==n&&o.length&&(this._selector=n,this._triggerArray.push(e))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}static get Default(){return st}static get NAME(){return\"collapse\"}toggle(){this._element.classList.contains(\"show\")?this.hide():this.show()}show(){if(this._isTransitioning||this._element.classList.contains(\"show\"))return;let t,e;this._parent&&(t=i.find(\".show, .collapsing\",this._parent).filter(t=>\"string\"==typeof this._config.parent?t.getAttribute(\"data-bs-parent\")===this._config.parent:t.classList.contains(\"collapse\")),0===t.length&&(t=null));const s=i.findOne(this._selector);if(t){const i=t.find(t=>s!==t);if(e=i?nt.getInstance(i):null,e&&e._isTransitioning)return}if(B.trigger(this._element,\"show.bs.collapse\").defaultPrevented)return;t&&t.forEach(t=>{s!==t&&nt.collapseInterface(t,\"hide\"),e||W.set(t,\"bs.collapse\",null)});const n=this._getDimension();this._element.classList.remove(\"collapse\"),this._element.classList.add(\"collapsing\"),this._element.style[n]=0,this._triggerArray.length&&this._triggerArray.forEach(t=>{t.classList.remove(\"collapsed\"),t.setAttribute(\"aria-expanded\",!0)}),this.setTransitioning(!0);const o=\"scroll\"+(n[0].toUpperCase()+n.slice(1));this._queueCallback(()=>{this._element.classList.remove(\"collapsing\"),this._element.classList.add(\"collapse\",\"show\"),this._element.style[n]=\"\",this.setTransitioning(!1),B.trigger(this._element,\"shown.bs.collapse\")},this._element,!0),this._element.style[n]=this._element[o]+\"px\"}hide(){if(this._isTransitioning||!this._element.classList.contains(\"show\"))return;if(B.trigger(this._element,\"hide.bs.collapse\").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=this._element.getBoundingClientRect()[t]+\"px\",m(this._element),this._element.classList.add(\"collapsing\"),this._element.classList.remove(\"collapse\",\"show\");const e=this._triggerArray.length;if(e>0)for(let t=0;t<e;t++){const e=this._triggerArray[t],s=a(e);s&&!s.classList.contains(\"show\")&&(e.classList.add(\"collapsed\"),e.setAttribute(\"aria-expanded\",!1))}this.setTransitioning(!0),this._element.style[t]=\"\",this._queueCallback(()=>{this.setTransitioning(!1),this._element.classList.remove(\"collapsing\"),this._element.classList.add(\"collapse\"),B.trigger(this._element,\"hidden.bs.collapse\")},this._element,!0)}setTransitioning(t){this._isTransitioning=t}_getConfig(t){return(t={...st,...t}).toggle=Boolean(t.toggle),d(\"collapse\",t,it),t}_getDimension(){return this._element.classList.contains(\"width\")?\"width\":\"height\"}_getParent(){let{parent:t}=this._config;t=h(t);const e=`[data-bs-toggle=\"collapse\"][data-bs-parent=\"${t}\"]`;return i.find(e,t).forEach(t=>{const e=a(t);this._addAriaAndCollapsedClass(e,[t])}),t}_addAriaAndCollapsedClass(t,e){if(!t||!e.length)return;const s=t.classList.contains(\"show\");e.forEach(t=>{s?t.classList.remove(\"collapsed\"):t.classList.add(\"collapsed\"),t.setAttribute(\"aria-expanded\",s)})}static collapseInterface(t,e){let s=nt.getInstance(t);const i={...st,...V.getDataAttributes(t),...\"object\"==typeof e&&e?e:{}};if(!s&&i.toggle&&\"string\"==typeof e&&/show|hide/.test(e)&&(i.toggle=!1),s||(s=new nt(t,i)),\"string\"==typeof e){if(void 0===s[e])throw new TypeError(`No method named \"${e}\"`);s[e]()}}static jQueryInterface(t){return this.each((function(){nt.collapseInterface(this,t)}))}}B.on(document,\"click.bs.collapse.data-api\",'[data-bs-toggle=\"collapse\"]',(function(t){(\"A\"===t.target.tagName||t.delegateTarget&&\"A\"===t.delegateTarget.tagName)&&t.preventDefault();const e=V.getDataAttributes(this),s=r(this);i.find(s).forEach(t=>{const s=nt.getInstance(t);let i;s?(null===s._parent&&\"string\"==typeof e.parent&&(s._config.parent=e.parent,s._parent=s._getParent()),i=\"toggle\"):i=e,nt.collapseInterface(t,i)})})),y(nt);const ot=new RegExp(\"ArrowUp|ArrowDown|Escape\"),rt=v()?\"top-end\":\"top-start\",at=v()?\"top-start\":\"top-end\",lt=v()?\"bottom-end\":\"bottom-start\",ct=v()?\"bottom-start\":\"bottom-end\",ht=v()?\"left-start\":\"right-start\",dt=v()?\"right-start\":\"left-start\",ut={offset:[0,2],boundary:\"clippingParents\",reference:\"toggle\",display:\"dynamic\",popperConfig:null,autoClose:!0},gt={offset:\"(array|string|function)\",boundary:\"(string|element)\",reference:\"(string|element|object)\",display:\"string\",popperConfig:\"(null|object|function)\",autoClose:\"(boolean|string)\"};class pt extends q{constructor(t,e){super(t),this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}static get Default(){return ut}static get DefaultType(){return gt}static get NAME(){return\"dropdown\"}toggle(){g(this._element)||(this._element.classList.contains(\"show\")?this.hide():this.show())}show(){if(g(this._element)||this._menu.classList.contains(\"show\"))return;const t=pt.getParentFromElement(this._element),e={relatedTarget:this._element};if(!B.trigger(this._element,\"show.bs.dropdown\",e).defaultPrevented){if(this._inNavbar)V.setDataAttribute(this._menu,\"popper\",\"none\");else{if(void 0===s)throw new TypeError(\"Bootstrap's dropdowns require Popper (https://popper.js.org)\");let e=this._element;\"parent\"===this._config.reference?e=t:c(this._config.reference)?e=h(this._config.reference):\"object\"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find(t=>\"applyStyles\"===t.name&&!1===t.enabled);this._popper=s.createPopper(e,this._menu,i),n&&V.setDataAttribute(this._menu,\"popper\",\"static\")}\"ontouchstart\"in document.documentElement&&!t.closest(\".navbar-nav\")&&[].concat(...document.body.children).forEach(t=>B.on(t,\"mouseover\",f)),this._element.focus(),this._element.setAttribute(\"aria-expanded\",!0),this._menu.classList.toggle(\"show\"),this._element.classList.toggle(\"show\"),B.trigger(this._element,\"shown.bs.dropdown\",e)}}hide(){if(g(this._element)||!this._menu.classList.contains(\"show\"))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_addEventListeners(){B.on(this._element,\"click.bs.dropdown\",t=>{t.preventDefault(),this.toggle()})}_completeHide(t){B.trigger(this._element,\"hide.bs.dropdown\",t).defaultPrevented||(\"ontouchstart\"in document.documentElement&&[].concat(...document.body.children).forEach(t=>B.off(t,\"mouseover\",f)),this._popper&&this._popper.destroy(),this._menu.classList.remove(\"show\"),this._element.classList.remove(\"show\"),this._element.setAttribute(\"aria-expanded\",\"false\"),V.removeDataAttribute(this._menu,\"popper\"),B.trigger(this._element,\"hidden.bs.dropdown\",t))}_getConfig(t){if(t={...this.constructor.Default,...V.getDataAttributes(this._element),...t},d(\"dropdown\",t,this.constructor.DefaultType),\"object\"==typeof t.reference&&!c(t.reference)&&\"function\"!=typeof t.reference.getBoundingClientRect)throw new TypeError(\"dropdown\".toUpperCase()+': Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.');return t}_getMenuElement(){return i.next(this._element,\".dropdown-menu\")[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains(\"dropend\"))return ht;if(t.classList.contains(\"dropstart\"))return dt;const e=\"end\"===getComputedStyle(this._menu).getPropertyValue(\"--bs-position\").trim();return t.classList.contains(\"dropup\")?e?at:rt:e?ct:lt}_detectNavbar(){return null!==this._element.closest(\".navbar\")}_getOffset(){const{offset:t}=this._config;return\"string\"==typeof t?t.split(\",\").map(t=>Number.parseInt(t,10)):\"function\"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:\"preventOverflow\",options:{boundary:this._config.boundary}},{name:\"offset\",options:{offset:this._getOffset()}}]};return\"static\"===this._config.display&&(t.modifiers=[{name:\"applyStyles\",enabled:!1}]),{...t,...\"function\"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const s=i.find(\".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)\",this._menu).filter(u);s.length&&A(s,e,\"ArrowDown\"===t,!s.includes(e)).focus()}static dropdownInterface(t,e){const s=pt.getOrCreateInstance(t,e);if(\"string\"==typeof e){if(void 0===s[e])throw new TypeError(`No method named \"${e}\"`);s[e]()}}static jQueryInterface(t){return this.each((function(){pt.dropdownInterface(this,t)}))}static clearMenus(t){if(t&&(2===t.button||\"keyup\"===t.type&&\"Tab\"!==t.key))return;const e=i.find('[data-bs-toggle=\"dropdown\"]');for(let s=0,i=e.length;s<i;s++){const i=pt.getInstance(e[s]);if(!i||!1===i._config.autoClose)continue;if(!i._element.classList.contains(\"show\"))continue;const n={relatedTarget:i._element};if(t){const e=t.composedPath(),s=e.includes(i._menu);if(e.includes(i._element)||\"inside\"===i._config.autoClose&&!s||\"outside\"===i._config.autoClose&&s)continue;if(i._menu.contains(t.target)&&(\"keyup\"===t.type&&\"Tab\"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;\"click\"===t.type&&(n.clickEvent=t)}i._completeHide(n)}}static getParentFromElement(t){return a(t)||t.parentNode}static dataApiKeydownHandler(t){if(/input|textarea/i.test(t.target.tagName)?\"Space\"===t.key||\"Escape\"!==t.key&&(\"ArrowDown\"!==t.key&&\"ArrowUp\"!==t.key||t.target.closest(\".dropdown-menu\")):!ot.test(t.key))return;const e=this.classList.contains(\"show\");if(!e&&\"Escape\"===t.key)return;if(t.preventDefault(),t.stopPropagation(),g(this))return;const s=()=>this.matches('[data-bs-toggle=\"dropdown\"]')?this:i.prev(this,'[data-bs-toggle=\"dropdown\"]')[0];return\"Escape\"===t.key?(s().focus(),void pt.clearMenus()):\"ArrowUp\"===t.key||\"ArrowDown\"===t.key?(e||s().click(),void pt.getInstance(s())._selectMenuItem(t)):void(e&&\"Space\"!==t.key||pt.clearMenus())}}B.on(document,\"keydown.bs.dropdown.data-api\",'[data-bs-toggle=\"dropdown\"]',pt.dataApiKeydownHandler),B.on(document,\"keydown.bs.dropdown.data-api\",\".dropdown-menu\",pt.dataApiKeydownHandler),B.on(document,\"click.bs.dropdown.data-api\",pt.clearMenus),B.on(document,\"keyup.bs.dropdown.data-api\",pt.clearMenus),B.on(document,\"click.bs.dropdown.data-api\",'[data-bs-toggle=\"dropdown\"]',(function(t){t.preventDefault(),pt.dropdownInterface(this)})),y(pt);class ft{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,\"paddingRight\",e=>e+t),this._setElementAttributes(\".fixed-top, .fixed-bottom, .is-fixed, .sticky-top\",\"paddingRight\",e=>e+t),this._setElementAttributes(\".sticky-top\",\"marginRight\",e=>e-t)}_disableOverFlow(){this._saveInitialAttribute(this._element,\"overflow\"),this._element.style.overflow=\"hidden\"}_setElementAttributes(t,e,s){const i=this.getWidth();this._applyManipulationCallback(t,t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+i)return;this._saveInitialAttribute(t,e);const n=window.getComputedStyle(t)[e];t.style[e]=s(Number.parseFloat(n))+\"px\"})}reset(){this._resetElementAttributes(this._element,\"overflow\"),this._resetElementAttributes(this._element,\"paddingRight\"),this._resetElementAttributes(\".fixed-top, .fixed-bottom, .is-fixed, .sticky-top\",\"paddingRight\"),this._resetElementAttributes(\".sticky-top\",\"marginRight\")}_saveInitialAttribute(t,e){const s=t.style[e];s&&V.setDataAttribute(t,e,s)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,t=>{const s=V.getDataAttribute(t,e);void 0===s?t.style.removeProperty(e):(V.removeDataAttribute(t,e),t.style[e]=s)})}_applyManipulationCallback(t,e){c(t)?e(t):i.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const mt={isVisible:!0,isAnimated:!1,rootElement:\"body\",clickCallback:null},_t={isVisible:\"boolean\",isAnimated:\"boolean\",rootElement:\"(element|string)\",clickCallback:\"(function|null)\"};class bt{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&m(this._getElement()),this._getElement().classList.add(\"show\"),this._emulateAnimation(()=>{w(t)})):w(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove(\"show\"),this._emulateAnimation(()=>{this.dispose(),w(t)})):w(t)}_getElement(){if(!this._element){const t=document.createElement(\"div\");t.className=\"modal-backdrop\",this._config.isAnimated&&t.classList.add(\"fade\"),this._element=t}return this._element}_getConfig(t){return(t={...mt,...\"object\"==typeof t?t:{}}).rootElement=h(t.rootElement),d(\"backdrop\",t,_t),t}_append(){this._isAppended||(this._config.rootElement.appendChild(this._getElement()),B.on(this._getElement(),\"mousedown.bs.backdrop\",()=>{w(this._config.clickCallback)}),this._isAppended=!0)}dispose(){this._isAppended&&(B.off(this._element,\"mousedown.bs.backdrop\"),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){E(t,this._getElement(),this._config.isAnimated)}}const vt={backdrop:!0,keyboard:!0,focus:!0},yt={backdrop:\"(boolean|string)\",keyboard:\"boolean\",focus:\"boolean\"};class wt extends q{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=i.findOne(\".modal-dialog\",this._element),this._backdrop=this._initializeBackDrop(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new ft}static get Default(){return vt}static get NAME(){return\"modal\"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||B.trigger(this._element,\"show.bs.modal\",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(\"modal-open\"),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),B.on(this._element,\"click.dismiss.bs.modal\",'[data-bs-dismiss=\"modal\"]',t=>this.hide(t)),B.on(this._dialog,\"mousedown.dismiss.bs.modal\",()=>{B.one(this._element,\"mouseup.dismiss.bs.modal\",t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)})}),this._showBackdrop(()=>this._showElement(t)))}hide(t){if(t&&[\"A\",\"AREA\"].includes(t.target.tagName)&&t.preventDefault(),!this._isShown||this._isTransitioning)return;if(B.trigger(this._element,\"hide.bs.modal\").defaultPrevented)return;this._isShown=!1;const e=this._isAnimated();e&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),B.off(document,\"focusin.bs.modal\"),this._element.classList.remove(\"show\"),B.off(this._element,\"click.dismiss.bs.modal\"),B.off(this._dialog,\"mousedown.dismiss.bs.modal\"),this._queueCallback(()=>this._hideModal(),this._element,e)}dispose(){[window,this._dialog].forEach(t=>B.off(t,\".bs.modal\")),this._backdrop.dispose(),super.dispose(),B.off(document,\"focusin.bs.modal\")}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bt({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_getConfig(t){return t={...vt,...V.getDataAttributes(this._element),...\"object\"==typeof t?t:{}},d(\"modal\",t,yt),t}_showElement(t){const e=this._isAnimated(),s=i.findOne(\".modal-body\",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display=\"block\",this._element.removeAttribute(\"aria-hidden\"),this._element.setAttribute(\"aria-modal\",!0),this._element.setAttribute(\"role\",\"dialog\"),this._element.scrollTop=0,s&&(s.scrollTop=0),e&&m(this._element),this._element.classList.add(\"show\"),this._config.focus&&this._enforceFocus(),this._queueCallback(()=>{this._config.focus&&this._element.focus(),this._isTransitioning=!1,B.trigger(this._element,\"shown.bs.modal\",{relatedTarget:t})},this._dialog,e)}_enforceFocus(){B.off(document,\"focusin.bs.modal\"),B.on(document,\"focusin.bs.modal\",t=>{document===t.target||this._element===t.target||this._element.contains(t.target)||this._element.focus()})}_setEscapeEvent(){this._isShown?B.on(this._element,\"keydown.dismiss.bs.modal\",t=>{this._config.keyboard&&\"Escape\"===t.key?(t.preventDefault(),this.hide()):this._config.keyboard||\"Escape\"!==t.key||this._triggerBackdropTransition()}):B.off(this._element,\"keydown.dismiss.bs.modal\")}_setResizeEvent(){this._isShown?B.on(window,\"resize.bs.modal\",()=>this._adjustDialog()):B.off(window,\"resize.bs.modal\")}_hideModal(){this._element.style.display=\"none\",this._element.setAttribute(\"aria-hidden\",!0),this._element.removeAttribute(\"aria-modal\"),this._element.removeAttribute(\"role\"),this._isTransitioning=!1,this._backdrop.hide(()=>{document.body.classList.remove(\"modal-open\"),this._resetAdjustments(),this._scrollBar.reset(),B.trigger(this._element,\"hidden.bs.modal\")})}_showBackdrop(t){B.on(this._element,\"click.dismiss.bs.modal\",t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():\"static\"===this._config.backdrop&&this._triggerBackdropTransition())}),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains(\"fade\")}_triggerBackdropTransition(){if(B.trigger(this._element,\"hidePrevented.bs.modal\").defaultPrevented)return;const{classList:t,scrollHeight:e,style:s}=this._element,i=e>document.documentElement.clientHeight;!i&&\"hidden\"===s.overflowY||t.contains(\"modal-static\")||(i||(s.overflowY=\"hidden\"),t.add(\"modal-static\"),this._queueCallback(()=>{t.remove(\"modal-static\"),i||this._queueCallback(()=>{s.overflowY=\"\"},this._dialog)},this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),s=e>0;(!s&&t&&!v()||s&&!t&&v())&&(this._element.style.paddingLeft=e+\"px\"),(s&&!t&&!v()||!s&&t&&v())&&(this._element.style.paddingRight=e+\"px\")}_resetAdjustments(){this._element.style.paddingLeft=\"\",this._element.style.paddingRight=\"\"}static jQueryInterface(t,e){return this.each((function(){const s=wt.getOrCreateInstance(this,t);if(\"string\"==typeof t){if(void 0===s[t])throw new TypeError(`No method named \"${t}\"`);s[t](e)}}))}}B.on(document,\"click.bs.modal.data-api\",'[data-bs-toggle=\"modal\"]',(function(t){const e=a(this);[\"A\",\"AREA\"].includes(this.tagName)&&t.preventDefault(),B.one(e,\"show.bs.modal\",t=>{t.defaultPrevented||B.one(e,\"hidden.bs.modal\",()=>{u(this)&&this.focus()})}),wt.getOrCreateInstance(e).toggle(this)})),y(wt);const Et={backdrop:!0,keyboard:!0,scroll:!1},At={backdrop:\"boolean\",keyboard:\"boolean\",scroll:\"boolean\"};class Tt extends q{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._addEventListeners()}static get NAME(){return\"offcanvas\"}static get Default(){return Et}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||B.trigger(this._element,\"show.bs.offcanvas\",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility=\"visible\",this._backdrop.show(),this._config.scroll||((new ft).hide(),this._enforceFocusOnElement(this._element)),this._element.removeAttribute(\"aria-hidden\"),this._element.setAttribute(\"aria-modal\",!0),this._element.setAttribute(\"role\",\"dialog\"),this._element.classList.add(\"show\"),this._queueCallback(()=>{B.trigger(this._element,\"shown.bs.offcanvas\",{relatedTarget:t})},this._element,!0))}hide(){this._isShown&&(B.trigger(this._element,\"hide.bs.offcanvas\").defaultPrevented||(B.off(document,\"focusin.bs.offcanvas\"),this._element.blur(),this._isShown=!1,this._element.classList.remove(\"show\"),this._backdrop.hide(),this._queueCallback(()=>{this._element.setAttribute(\"aria-hidden\",!0),this._element.removeAttribute(\"aria-modal\"),this._element.removeAttribute(\"role\"),this._element.style.visibility=\"hidden\",this._config.scroll||(new ft).reset(),B.trigger(this._element,\"hidden.bs.offcanvas\")},this._element,!0)))}dispose(){this._backdrop.dispose(),super.dispose(),B.off(document,\"focusin.bs.offcanvas\")}_getConfig(t){return t={...Et,...V.getDataAttributes(this._element),...\"object\"==typeof t?t:{}},d(\"offcanvas\",t,At),t}_initializeBackDrop(){return new bt({isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_enforceFocusOnElement(t){B.off(document,\"focusin.bs.offcanvas\"),B.on(document,\"focusin.bs.offcanvas\",e=>{document===e.target||t===e.target||t.contains(e.target)||t.focus()}),t.focus()}_addEventListeners(){B.on(this._element,\"click.dismiss.bs.offcanvas\",'[data-bs-dismiss=\"offcanvas\"]',()=>this.hide()),B.on(this._element,\"keydown.dismiss.bs.offcanvas\",t=>{this._config.keyboard&&\"Escape\"===t.key&&this.hide()})}static jQueryInterface(t){return this.each((function(){const e=Tt.getOrCreateInstance(this,t);if(\"string\"==typeof t){if(void 0===e[t]||t.startsWith(\"_\")||\"constructor\"===t)throw new TypeError(`No method named \"${t}\"`);e[t](this)}}))}}B.on(document,\"click.bs.offcanvas.data-api\",'[data-bs-toggle=\"offcanvas\"]',(function(t){const e=a(this);if([\"A\",\"AREA\"].includes(this.tagName)&&t.preventDefault(),g(this))return;B.one(e,\"hidden.bs.offcanvas\",()=>{u(this)&&this.focus()});const s=i.findOne(\".offcanvas.show\");s&&s!==e&&Tt.getInstance(s).hide(),Tt.getOrCreateInstance(e).toggle(this)})),B.on(window,\"load.bs.offcanvas.data-api\",()=>i.find(\".offcanvas.show\").forEach(t=>Tt.getOrCreateInstance(t).show())),y(Tt);const Ct=new Set([\"background\",\"cite\",\"href\",\"itemtype\",\"longdesc\",\"poster\",\"src\",\"xlink:href\"]),kt=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i,Lt=/^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i,Ot=(t,e)=>{const s=t.nodeName.toLowerCase();if(e.includes(s))return!Ct.has(s)||Boolean(kt.test(t.nodeValue)||Lt.test(t.nodeValue));const i=e.filter(t=>t instanceof RegExp);for(let t=0,e=i.length;t<e;t++)if(i[t].test(s))return!0;return!1};function Dt(t,e,s){if(!t.length)return t;if(s&&\"function\"==typeof s)return s(t);const i=(new window.DOMParser).parseFromString(t,\"text/html\"),n=Object.keys(e),o=[].concat(...i.body.querySelectorAll(\"*\"));for(let t=0,s=o.length;t<s;t++){const s=o[t],i=s.nodeName.toLowerCase();if(!n.includes(i)){s.remove();continue}const r=[].concat(...s.attributes),a=[].concat(e[\"*\"]||[],e[i]||[]);r.forEach(t=>{Ot(t,a)||s.removeAttribute(t.nodeName)})}return i.body.innerHTML}const It=new RegExp(\"(^|\\\\s)bs-tooltip\\\\S+\",\"g\"),Nt=new Set([\"sanitize\",\"allowList\",\"sanitizeFn\"]),St={animation:\"boolean\",template:\"string\",title:\"(string|element|function)\",trigger:\"string\",delay:\"(number|object)\",html:\"boolean\",selector:\"(string|boolean)\",placement:\"(string|function)\",offset:\"(array|string|function)\",container:\"(string|element|boolean)\",fallbackPlacements:\"array\",boundary:\"(string|element)\",customClass:\"(string|function)\",sanitize:\"boolean\",sanitizeFn:\"(null|function)\",allowList:\"object\",popperConfig:\"(null|object|function)\"},xt={AUTO:\"auto\",TOP:\"top\",RIGHT:v()?\"left\":\"right\",BOTTOM:\"bottom\",LEFT:v()?\"right\":\"left\"},Mt={animation:!0,template:'<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>',trigger:\"hover focus\",title:\"\",delay:0,html:!1,selector:!1,placement:\"top\",offset:[0,0],container:!1,fallbackPlacements:[\"top\",\"right\",\"bottom\",\"left\"],boundary:\"clippingParents\",customClass:\"\",sanitize:!0,sanitizeFn:null,allowList:{\"*\":[\"class\",\"dir\",\"id\",\"lang\",\"role\",/^aria-[\\w-]*$/i],a:[\"target\",\"href\",\"title\",\"rel\"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:[\"src\",\"srcset\",\"alt\",\"title\",\"width\",\"height\"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Pt={HIDE:\"hide.bs.tooltip\",HIDDEN:\"hidden.bs.tooltip\",SHOW:\"show.bs.tooltip\",SHOWN:\"shown.bs.tooltip\",INSERTED:\"inserted.bs.tooltip\",CLICK:\"click.bs.tooltip\",FOCUSIN:\"focusin.bs.tooltip\",FOCUSOUT:\"focusout.bs.tooltip\",MOUSEENTER:\"mouseenter.bs.tooltip\",MOUSELEAVE:\"mouseleave.bs.tooltip\"};class jt extends q{constructor(t,e){if(void 0===s)throw new TypeError(\"Bootstrap's tooltips require Popper (https://popper.js.org)\");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState=\"\",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return Mt}static get NAME(){return\"tooltip\"}static get Event(){return Pt}static get DefaultType(){return St}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains(\"show\"))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),B.off(this._element.closest(\".modal\"),\"hide.bs.modal\",this._hideModalHandler),this.tip&&this.tip.remove(),this._popper&&this._popper.destroy(),super.dispose()}show(){if(\"none\"===this._element.style.display)throw new Error(\"Please use show on visible elements\");if(!this.isWithContent()||!this._isEnabled)return;const t=B.trigger(this._element,this.constructor.Event.SHOW),e=p(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;const o=this.getTipElement(),r=n(this.constructor.NAME);o.setAttribute(\"id\",r),this._element.setAttribute(\"aria-describedby\",r),this.setContent(),this._config.animation&&o.classList.add(\"fade\");const a=\"function\"==typeof this._config.placement?this._config.placement.call(this,o,this._element):this._config.placement,l=this._getAttachment(a);this._addAttachmentClass(l);const{container:c}=this._config;W.set(o,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(c.appendChild(o),B.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=s.createPopper(this._element,o,this._getPopperConfig(l)),o.classList.add(\"show\");const h=\"function\"==typeof this._config.customClass?this._config.customClass():this._config.customClass;h&&o.classList.add(...h.split(\" \")),\"ontouchstart\"in document.documentElement&&[].concat(...document.body.children).forEach(t=>{B.on(t,\"mouseover\",f)});const d=this.tip.classList.contains(\"fade\");this._queueCallback(()=>{const t=this._hoverState;this._hoverState=null,B.trigger(this._element,this.constructor.Event.SHOWN),\"out\"===t&&this._leave(null,this)},this.tip,d)}hide(){if(!this._popper)return;const t=this.getTipElement();if(B.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove(\"show\"),\"ontouchstart\"in document.documentElement&&[].concat(...document.body.children).forEach(t=>B.off(t,\"mouseover\",f)),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains(\"fade\");this._queueCallback(()=>{this._isWithActiveTrigger()||(\"show\"!==this._hoverState&&t.remove(),this._cleanTipClass(),this._element.removeAttribute(\"aria-describedby\"),B.trigger(this._element,this.constructor.Event.HIDDEN),this._popper&&(this._popper.destroy(),this._popper=null))},this.tip,e),this._hoverState=\"\"}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement(\"div\");return t.innerHTML=this._config.template,this.tip=t.children[0],this.tip}setContent(){const t=this.getTipElement();this.setElementContent(i.findOne(\".tooltip-inner\",t),this.getTitle()),t.classList.remove(\"fade\",\"show\")}setElementContent(t,e){if(null!==t)return c(e)?(e=h(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML=\"\",t.appendChild(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Dt(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){let t=this._element.getAttribute(\"data-bs-original-title\");return t||(t=\"function\"==typeof this._config.title?this._config.title.call(this._element):this._config.title),t}updateAttachment(t){return\"right\"===t?\"end\":\"left\"===t?\"start\":t}_initializeOnDelegatedTarget(t,e){const s=this.constructor.DATA_KEY;return(e=e||W.get(t.delegateTarget,s))||(e=new this.constructor(t.delegateTarget,this._getDelegateConfig()),W.set(t.delegateTarget,s,e)),e}_getOffset(){const{offset:t}=this._config;return\"string\"==typeof t?t.split(\",\").map(t=>Number.parseInt(t,10)):\"function\"==typeof t?e=>t(e,this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:\"flip\",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:\"offset\",options:{offset:this._getOffset()}},{name:\"preventOverflow\",options:{boundary:this._config.boundary}},{name:\"arrow\",options:{element:`.${this.constructor.NAME}-arrow`}},{name:\"onChange\",enabled:!0,phase:\"afterWrite\",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,...\"function\"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(\"bs-tooltip-\"+this.updateAttachment(t))}_getAttachment(t){return xt[t.toUpperCase()]}_setListeners(){this._config.trigger.split(\" \").forEach(t=>{if(\"click\"===t)B.on(this._element,this.constructor.Event.CLICK,this._config.selector,t=>this.toggle(t));else if(\"manual\"!==t){const e=\"hover\"===t?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,s=\"hover\"===t?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;B.on(this._element,e,this._config.selector,t=>this._enter(t)),B.on(this._element,s,this._config.selector,t=>this._leave(t))}}),this._hideModalHandler=()=>{this._element&&this.hide()},B.on(this._element.closest(\".modal\"),\"hide.bs.modal\",this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:\"manual\",selector:\"\"}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute(\"title\"),e=typeof this._element.getAttribute(\"data-bs-original-title\");(t||\"string\"!==e)&&(this._element.setAttribute(\"data-bs-original-title\",t||\"\"),!t||this._element.getAttribute(\"aria-label\")||this._element.textContent||this._element.setAttribute(\"aria-label\",t),this._element.setAttribute(\"title\",\"\"))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger[\"focusin\"===t.type?\"focus\":\"hover\"]=!0),e.getTipElement().classList.contains(\"show\")||\"show\"===e._hoverState?e._hoverState=\"show\":(clearTimeout(e._timeout),e._hoverState=\"show\",e._config.delay&&e._config.delay.show?e._timeout=setTimeout(()=>{\"show\"===e._hoverState&&e.show()},e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger[\"focusout\"===t.type?\"focus\":\"hover\"]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=\"out\",e._config.delay&&e._config.delay.hide?e._timeout=setTimeout(()=>{\"out\"===e._hoverState&&e.hide()},e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=V.getDataAttributes(this._element);return Object.keys(e).forEach(t=>{Nt.has(t)&&delete e[t]}),(t={...this.constructor.Default,...e,...\"object\"==typeof t&&t?t:{}}).container=!1===t.container?document.body:h(t.container),\"number\"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),\"number\"==typeof t.title&&(t.title=t.title.toString()),\"number\"==typeof t.content&&(t.content=t.content.toString()),d(\"tooltip\",t,this.constructor.DefaultType),t.sanitize&&(t.template=Dt(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};if(this._config)for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute(\"class\").match(It);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}static jQueryInterface(t){return this.each((function(){const e=jt.getOrCreateInstance(this,t);if(\"string\"==typeof t){if(void 0===e[t])throw new TypeError(`No method named \"${t}\"`);e[t]()}}))}}y(jt);const Ht=new RegExp(\"(^|\\\\s)bs-popover\\\\S+\",\"g\"),Rt={...jt.Default,placement:\"right\",offset:[0,8],trigger:\"click\",content:\"\",template:'<div class=\"popover\" role=\"tooltip\"><div class=\"popover-arrow\"></div><h3 class=\"popover-header\"></h3><div class=\"popover-body\"></div></div>'},Bt={...jt.DefaultType,content:\"(string|element|function)\"},$t={HIDE:\"hide.bs.popover\",HIDDEN:\"hidden.bs.popover\",SHOW:\"show.bs.popover\",SHOWN:\"shown.bs.popover\",INSERTED:\"inserted.bs.popover\",CLICK:\"click.bs.popover\",FOCUSIN:\"focusin.bs.popover\",FOCUSOUT:\"focusout.bs.popover\",MOUSEENTER:\"mouseenter.bs.popover\",MOUSELEAVE:\"mouseleave.bs.popover\"};class Wt extends jt{static get Default(){return Rt}static get NAME(){return\"popover\"}static get Event(){return $t}static get DefaultType(){return Bt}isWithContent(){return this.getTitle()||this._getContent()}getTipElement(){return this.tip||(this.tip=super.getTipElement(),this.getTitle()||i.findOne(\".popover-header\",this.tip).remove(),this._getContent()||i.findOne(\".popover-body\",this.tip).remove()),this.tip}setContent(){const t=this.getTipElement();this.setElementContent(i.findOne(\".popover-header\",t),this.getTitle());let e=this._getContent();\"function\"==typeof e&&(e=e.call(this._element)),this.setElementContent(i.findOne(\".popover-body\",t),e),t.classList.remove(\"fade\",\"show\")}_addAttachmentClass(t){this.getTipElement().classList.add(\"bs-popover-\"+this.updateAttachment(t))}_getContent(){return this._element.getAttribute(\"data-bs-content\")||this._config.content}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute(\"class\").match(Ht);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}static jQueryInterface(t){return this.each((function(){const e=Wt.getOrCreateInstance(this,t);if(\"string\"==typeof t){if(void 0===e[t])throw new TypeError(`No method named \"${t}\"`);e[t]()}}))}}y(Wt);const qt={offset:10,method:\"auto\",target:\"\"},zt={offset:\"number\",method:\"string\",target:\"(string|element)\"};class Ft extends q{constructor(t,e){super(t),this._scrollElement=\"BODY\"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._selector=`${this._config.target} .nav-link, ${this._config.target} .list-group-item, ${this._config.target} .dropdown-item`,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,B.on(this._scrollElement,\"scroll.bs.scrollspy\",()=>this._process()),this.refresh(),this._process()}static get Default(){return qt}static get NAME(){return\"scrollspy\"}refresh(){const t=this._scrollElement===this._scrollElement.window?\"offset\":\"position\",e=\"auto\"===this._config.method?t:this._config.method,s=\"position\"===e?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),i.find(this._selector).map(t=>{const n=r(t),o=n?i.findOne(n):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[V[e](o).top+s,n]}return null}).filter(t=>t).sort((t,e)=>t[0]-e[0]).forEach(t=>{this._offsets.push(t[0]),this._targets.push(t[1])})}dispose(){B.off(this._scrollElement,\".bs.scrollspy\"),super.dispose()}_getConfig(t){if(\"string\"!=typeof(t={...qt,...V.getDataAttributes(this._element),...\"object\"==typeof t&&t?t:{}}).target&&c(t.target)){let{id:e}=t.target;e||(e=n(\"scrollspy\"),t.target.id=e),t.target=\"#\"+e}return d(\"scrollspy\",t,zt),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),s=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=s){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t<this._offsets[e+1])&&this._activate(this._targets[e])}}_activate(t){this._activeTarget=t,this._clear();const e=this._selector.split(\",\").map(e=>`${e}[data-bs-target=\"${t}\"],${e}[href=\"${t}\"]`),s=i.findOne(e.join(\",\"));s.classList.contains(\"dropdown-item\")?(i.findOne(\".dropdown-toggle\",s.closest(\".dropdown\")).classList.add(\"active\"),s.classList.add(\"active\")):(s.classList.add(\"active\"),i.parents(s,\".nav, .list-group\").forEach(t=>{i.prev(t,\".nav-link, .list-group-item\").forEach(t=>t.classList.add(\"active\")),i.prev(t,\".nav-item\").forEach(t=>{i.children(t,\".nav-link\").forEach(t=>t.classList.add(\"active\"))})})),B.trigger(this._scrollElement,\"activate.bs.scrollspy\",{relatedTarget:t})}_clear(){i.find(this._selector).filter(t=>t.classList.contains(\"active\")).forEach(t=>t.classList.remove(\"active\"))}static jQueryInterface(t){return this.each((function(){const e=Ft.getOrCreateInstance(this,t);if(\"string\"==typeof t){if(void 0===e[t])throw new TypeError(`No method named \"${t}\"`);e[t]()}}))}}B.on(window,\"load.bs.scrollspy.data-api\",()=>{i.find('[data-bs-spy=\"scroll\"]').forEach(t=>new Ft(t))}),y(Ft);class Ut extends q{static get NAME(){return\"tab\"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(\"active\"))return;let t;const e=a(this._element),s=this._element.closest(\".nav, .list-group\");if(s){const e=\"UL\"===s.nodeName||\"OL\"===s.nodeName?\":scope > li > .active\":\".active\";t=i.find(e,s),t=t[t.length-1]}const n=t?B.trigger(t,\"hide.bs.tab\",{relatedTarget:this._element}):null;if(B.trigger(this._element,\"show.bs.tab\",{relatedTarget:t}).defaultPrevented||null!==n&&n.defaultPrevented)return;this._activate(this._element,s);const o=()=>{B.trigger(t,\"hidden.bs.tab\",{relatedTarget:this._element}),B.trigger(this._element,\"shown.bs.tab\",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,s){const n=(!e||\"UL\"!==e.nodeName&&\"OL\"!==e.nodeName?i.children(e,\".active\"):i.find(\":scope > li > .active\",e))[0],o=s&&n&&n.classList.contains(\"fade\"),r=()=>this._transitionComplete(t,n,s);n&&o?(n.classList.remove(\"show\"),this._queueCallback(r,t,!0)):r()}_transitionComplete(t,e,s){if(e){e.classList.remove(\"active\");const t=i.findOne(\":scope > .dropdown-menu .active\",e.parentNode);t&&t.classList.remove(\"active\"),\"tab\"===e.getAttribute(\"role\")&&e.setAttribute(\"aria-selected\",!1)}t.classList.add(\"active\"),\"tab\"===t.getAttribute(\"role\")&&t.setAttribute(\"aria-selected\",!0),m(t),t.classList.contains(\"fade\")&&t.classList.add(\"show\");let n=t.parentNode;if(n&&\"LI\"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains(\"dropdown-menu\")){const e=t.closest(\".dropdown\");e&&i.find(\".dropdown-toggle\",e).forEach(t=>t.classList.add(\"active\")),t.setAttribute(\"aria-expanded\",!0)}s&&s()}static jQueryInterface(t){return this.each((function(){const e=Ut.getOrCreateInstance(this);if(\"string\"==typeof t){if(void 0===e[t])throw new TypeError(`No method named \"${t}\"`);e[t]()}}))}}B.on(document,\"click.bs.tab.data-api\",'[data-bs-toggle=\"tab\"], [data-bs-toggle=\"pill\"], [data-bs-toggle=\"list\"]',(function(t){[\"A\",\"AREA\"].includes(this.tagName)&&t.preventDefault(),g(this)||Ut.getOrCreateInstance(this).show()})),y(Ut);const Kt={animation:\"boolean\",autohide:\"boolean\",delay:\"number\"},Vt={animation:!0,autohide:!0,delay:5e3};class Qt extends q{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Kt}static get Default(){return Vt}static get NAME(){return\"toast\"}show(){B.trigger(this._element,\"show.bs.toast\").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add(\"fade\"),this._element.classList.remove(\"hide\"),m(this._element),this._element.classList.add(\"showing\"),this._queueCallback(()=>{this._element.classList.remove(\"showing\"),this._element.classList.add(\"show\"),B.trigger(this._element,\"shown.bs.toast\"),this._maybeScheduleHide()},this._element,this._config.animation))}hide(){this._element.classList.contains(\"show\")&&(B.trigger(this._element,\"hide.bs.toast\").defaultPrevented||(this._element.classList.remove(\"show\"),this._queueCallback(()=>{this._element.classList.add(\"hide\"),B.trigger(this._element,\"hidden.bs.toast\")},this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains(\"show\")&&this._element.classList.remove(\"show\"),super.dispose()}_getConfig(t){return t={...Vt,...V.getDataAttributes(this._element),...\"object\"==typeof t&&t?t:{}},d(\"toast\",t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout(()=>{this.hide()},this._config.delay)))}_onInteraction(t,e){switch(t.type){case\"mouseover\":case\"mouseout\":this._hasMouseInteraction=e;break;case\"focusin\":case\"focusout\":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const s=t.relatedTarget;this._element===s||this._element.contains(s)||this._maybeScheduleHide()}_setListeners(){B.on(this._element,\"click.dismiss.bs.toast\",'[data-bs-dismiss=\"toast\"]',()=>this.hide()),B.on(this._element,\"mouseover.bs.toast\",t=>this._onInteraction(t,!0)),B.on(this._element,\"mouseout.bs.toast\",t=>this._onInteraction(t,!1)),B.on(this._element,\"focusin.bs.toast\",t=>this._onInteraction(t,!0)),B.on(this._element,\"focusout.bs.toast\",t=>this._onInteraction(t,!1))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Qt.getOrCreateInstance(this,t);if(\"string\"==typeof t){if(void 0===e[t])throw new TypeError(`No method named \"${t}\"`);e[t](this)}}))}}return y(Qt),{Alert:z,Button:F,Carousel:et,Collapse:nt,Dropdown:pt,Modal:wt,Offcanvas:Tt,Popover:Wt,ScrollSpy:Ft,Tab:Ut,Toast:Qt,Tooltip:jt}}));\n//# sourceMappingURL=bootstrap.min.js.map\n","Mageplaza_Core/js/jquery.ui.touch-punch.min.js":"/*!\r\n * jQuery UI Touch Punch 0.2.3\r\n *\r\n * Copyright 2011\u20132014, Dave Furfero\r\n * Dual licensed under the MIT or GPL Version 2 licenses.\r\n *\r\n * Depends:\r\n *  jquery.ui.widget.js\r\n *  jquery.ui.mouse.js\r\n */\r\n!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent(\"MouseEvents\");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch=\"ontouchend\"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,\"mouseover\"),f(a,\"mousemove\"),f(a,\"mousedown\"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,\"mousemove\"))},b._touchEnd=function(a){e&&(f(a,\"mouseup\"),f(a,\"mouseout\"),this._touchMoved||f(a,\"click\"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,\"_touchStart\"),touchmove:a.proxy(b,\"_touchMove\"),touchend:a.proxy(b,\"_touchEnd\")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,\"_touchStart\"),touchmove:a.proxy(b,\"_touchMove\"),touchend:a.proxy(b,\"_touchEnd\")}),d.call(b)}}}(jQuery);\r\n","Mageplaza_Core/js/ion.rangeSlider.min.js":"// Ion.RangeSlider | version 2.1.6 | https://github.com/IonDen/ion.rangeSlider\r\n;(function(f){\"function\"===typeof define&&define.amd?define([\"jquery\"],function(p){return f(p,document,window,navigator)}):\"object\"===typeof exports?f(require(\"jquery\"),document,window,navigator):f(jQuery,document,window,navigator)})(function(f,p,h,t,q){var u=0,m=function(){var a=t.userAgent,b=/msie\\s\\d+/i;return 0<a.search(b)&&(a=b.exec(a).toString(),a=a.split(\" \")[1],9>a)?(f(\"html\").addClass(\"lt-ie9\"),!0):!1}();Function.prototype.bind||(Function.prototype.bind=function(a){var b=this,d=[].slice;if(\"function\"!=\r\n    typeof b)throw new TypeError;var c=d.call(arguments,1),e=function(){if(this instanceof e){var g=function(){};g.prototype=b.prototype;var g=new g,l=b.apply(g,c.concat(d.call(arguments)));return Object(l)===l?l:g}return b.apply(a,c.concat(d.call(arguments)))};return e});Array.prototype.indexOf||(Array.prototype.indexOf=function(a,b){var d;if(null==this)throw new TypeError('\"this\" is null or not defined');var c=Object(this),e=c.length>>>0;if(0===e)return-1;d=+b||0;Infinity===Math.abs(d)&&(d=0);if(d>=\r\n    e)return-1;for(d=Math.max(0<=d?d:e-Math.abs(d),0);d<e;){if(d in c&&c[d]===a)return d;d++}return-1});var r=function(a,b,d){this.VERSION=\"2.1.6\";this.input=a;this.plugin_count=d;this.old_to=this.old_from=this.update_tm=this.calc_count=this.current_plugin=0;this.raf_id=this.old_min_interval=null;this.is_update=this.is_key=this.no_diapason=this.force_redraw=this.dragging=!1;this.is_start=this.is_first_update=!0;this.is_click=this.is_resize=this.is_active=this.is_finish=!1;b=b||{};this.$cache={win:f(h),\r\n    body:f(p.body),input:f(a),cont:null,rs:null,min:null,max:null,from:null,to:null,single:null,bar:null,line:null,s_single:null,s_from:null,s_to:null,shad_single:null,shad_from:null,shad_to:null,edge:null,grid:null,grid_labels:[]};this.coords={x_gap:0,x_pointer:0,w_rs:0,w_rs_old:0,w_handle:0,p_gap:0,p_gap_left:0,p_gap_right:0,p_step:0,p_pointer:0,p_handle:0,p_single_fake:0,p_single_real:0,p_from_fake:0,p_from_real:0,p_to_fake:0,p_to_real:0,p_bar_x:0,p_bar_w:0,grid_gap:0,big_num:0,big:[],big_w:[],big_p:[],\r\n    big_x:[]};this.labels={w_min:0,w_max:0,w_from:0,w_to:0,w_single:0,p_min:0,p_max:0,p_from_fake:0,p_from_left:0,p_to_fake:0,p_to_left:0,p_single_fake:0,p_single_left:0};var c=this.$cache.input;a=c.prop(\"value\");var e;d={type:\"single\",min:10,max:100,from:null,to:null,step:1,min_interval:0,max_interval:0,drag_interval:!1,values:[],p_values:[],from_fixed:!1,from_min:null,from_max:null,from_shadow:!1,to_fixed:!1,to_min:null,to_max:null,to_shadow:!1,prettify_enabled:!0,prettify_separator:\" \",prettify:null,\r\n    force_edges:!1,keyboard:!1,keyboard_step:5,grid:!1,grid_margin:!0,grid_num:4,grid_snap:!1,hide_min_max:!1,hide_from_to:!1,prefix:\"\",postfix:\"\",max_postfix:\"\",decorate_both:!0,values_separator:\" \\u2014 \",input_values_separator:\";\",disable:!1,onStart:null,onChange:null,onFinish:null,onUpdate:null};\"INPUT\"!==c[0].nodeName&&console&&console.warn&&console.warn(\"Base element should be <input>!\",c[0]);c={type:c.data(\"type\"),min:c.data(\"min\"),max:c.data(\"max\"),from:c.data(\"from\"),to:c.data(\"to\"),step:c.data(\"step\"),\r\n    min_interval:c.data(\"minInterval\"),max_interval:c.data(\"maxInterval\"),drag_interval:c.data(\"dragInterval\"),values:c.data(\"values\"),from_fixed:c.data(\"fromFixed\"),from_min:c.data(\"fromMin\"),from_max:c.data(\"fromMax\"),from_shadow:c.data(\"fromShadow\"),to_fixed:c.data(\"toFixed\"),to_min:c.data(\"toMin\"),to_max:c.data(\"toMax\"),to_shadow:c.data(\"toShadow\"),prettify_enabled:c.data(\"prettifyEnabled\"),prettify_separator:c.data(\"prettifySeparator\"),force_edges:c.data(\"forceEdges\"),keyboard:c.data(\"keyboard\"),\r\n    keyboard_step:c.data(\"keyboardStep\"),grid:c.data(\"grid\"),grid_margin:c.data(\"gridMargin\"),grid_num:c.data(\"gridNum\"),grid_snap:c.data(\"gridSnap\"),hide_min_max:c.data(\"hideMinMax\"),hide_from_to:c.data(\"hideFromTo\"),prefix:c.data(\"prefix\"),postfix:c.data(\"postfix\"),max_postfix:c.data(\"maxPostfix\"),decorate_both:c.data(\"decorateBoth\"),values_separator:c.data(\"valuesSeparator\"),input_values_separator:c.data(\"inputValuesSeparator\"),disable:c.data(\"disable\")};c.values=c.values&&c.values.split(\",\");for(e in c)c.hasOwnProperty(e)&&\r\n(c[e]!==q&&\"\"!==c[e]||delete c[e]);a!==q&&\"\"!==a&&(a=a.split(c.input_values_separator||b.input_values_separator||\";\"),a[0]&&a[0]==+a[0]&&(a[0]=+a[0]),a[1]&&a[1]==+a[1]&&(a[1]=+a[1]),b&&b.values&&b.values.length?(d.from=a[0]&&b.values.indexOf(a[0]),d.to=a[1]&&b.values.indexOf(a[1])):(d.from=a[0]&&+a[0],d.to=a[1]&&+a[1]));f.extend(d,b);f.extend(d,c);this.options=d;this.update_check={};this.validate();this.result={input:this.$cache.input,slider:null,min:this.options.min,max:this.options.max,from:this.options.from,\r\n    from_percent:0,from_value:null,to:this.options.to,to_percent:0,to_value:null};this.init()};r.prototype={init:function(a){this.no_diapason=!1;this.coords.p_step=this.convertToPercent(this.options.step,!0);this.target=\"base\";this.toggleInput();this.append();this.setMinMax();a?(this.force_redraw=!0,this.calc(!0),this.callOnUpdate()):(this.force_redraw=!0,this.calc(!0),this.callOnStart());this.updateScene()},append:function(){this.$cache.input.before('<span class=\"irs js-irs-'+this.plugin_count+'\"></span>');\r\n        this.$cache.input.prop(\"readonly\",!0);this.$cache.cont=this.$cache.input.prev();this.result.slider=this.$cache.cont;this.$cache.cont.html('<span class=\"irs\"><span class=\"irs-line\" tabindex=\"-1\"><span class=\"irs-line-left\"></span><span class=\"irs-line-mid\"></span><span class=\"irs-line-right\"></span></span><span class=\"irs-min\">0</span><span class=\"irs-max\">1</span><span class=\"irs-from\">0</span><span class=\"irs-to\">0</span><span class=\"irs-single\">0</span></span><span class=\"irs-grid\"></span><span class=\"irs-bar\"></span>');\r\n        this.$cache.rs=this.$cache.cont.find(\".irs\");this.$cache.min=this.$cache.cont.find(\".irs-min\");this.$cache.max=this.$cache.cont.find(\".irs-max\");this.$cache.from=this.$cache.cont.find(\".irs-from\");this.$cache.to=this.$cache.cont.find(\".irs-to\");this.$cache.single=this.$cache.cont.find(\".irs-single\");this.$cache.bar=this.$cache.cont.find(\".irs-bar\");this.$cache.line=this.$cache.cont.find(\".irs-line\");this.$cache.grid=this.$cache.cont.find(\".irs-grid\");\"single\"===this.options.type?(this.$cache.cont.append('<span class=\"irs-bar-edge\"></span><span class=\"irs-shadow shadow-single\"></span><span class=\"irs-slider single\"></span>'),\r\n            this.$cache.edge=this.$cache.cont.find(\".irs-bar-edge\"),this.$cache.s_single=this.$cache.cont.find(\".single\"),this.$cache.from[0].style.visibility=\"hidden\",this.$cache.to[0].style.visibility=\"hidden\",this.$cache.shad_single=this.$cache.cont.find(\".shadow-single\")):(this.$cache.cont.append('<span class=\"irs-shadow shadow-from\"></span><span class=\"irs-shadow shadow-to\"></span><span class=\"irs-slider from\"></span><span class=\"irs-slider to\"></span>'),this.$cache.s_from=this.$cache.cont.find(\".from\"),\r\n            this.$cache.s_to=this.$cache.cont.find(\".to\"),this.$cache.shad_from=this.$cache.cont.find(\".shadow-from\"),this.$cache.shad_to=this.$cache.cont.find(\".shadow-to\"),this.setTopHandler());this.options.hide_from_to&&(this.$cache.from[0].style.display=\"none\",this.$cache.to[0].style.display=\"none\",this.$cache.single[0].style.display=\"none\");this.appendGrid();this.options.disable?(this.appendDisableMask(),this.$cache.input[0].disabled=!0):(this.$cache.cont.removeClass(\"irs-disabled\"),this.$cache.input[0].disabled=\r\n            !1,this.bindEvents());this.options.drag_interval&&(this.$cache.bar[0].style.cursor=\"ew-resize\")},setTopHandler:function(){var a=this.options.max,b=this.options.to;this.options.from>this.options.min&&b===a?this.$cache.s_from.addClass(\"type_last\"):b<a&&this.$cache.s_to.addClass(\"type_last\")},changeLevel:function(a){switch(a){case \"single\":this.coords.p_gap=this.toFixed(this.coords.p_pointer-this.coords.p_single_fake);break;case \"from\":this.coords.p_gap=this.toFixed(this.coords.p_pointer-this.coords.p_from_fake);\r\n        this.$cache.s_from.addClass(\"state_hover\");this.$cache.s_from.addClass(\"type_last\");this.$cache.s_to.removeClass(\"type_last\");break;case \"to\":this.coords.p_gap=this.toFixed(this.coords.p_pointer-this.coords.p_to_fake);this.$cache.s_to.addClass(\"state_hover\");this.$cache.s_to.addClass(\"type_last\");this.$cache.s_from.removeClass(\"type_last\");break;case \"both\":this.coords.p_gap_left=this.toFixed(this.coords.p_pointer-this.coords.p_from_fake),this.coords.p_gap_right=this.toFixed(this.coords.p_to_fake-\r\n        this.coords.p_pointer),this.$cache.s_to.removeClass(\"type_last\"),this.$cache.s_from.removeClass(\"type_last\")}},appendDisableMask:function(){this.$cache.cont.append('<span class=\"irs-disable-mask\"></span>');this.$cache.cont.addClass(\"irs-disabled\")},remove:function(){this.$cache.cont.remove();this.$cache.cont=null;this.$cache.line.off(\"keydown.irs_\"+this.plugin_count);this.$cache.body.off(\"touchmove.irs_\"+this.plugin_count);this.$cache.body.off(\"mousemove.irs_\"+this.plugin_count);this.$cache.win.off(\"touchend.irs_\"+\r\n        this.plugin_count);this.$cache.win.off(\"mouseup.irs_\"+this.plugin_count);m&&(this.$cache.body.off(\"mouseup.irs_\"+this.plugin_count),this.$cache.body.off(\"mouseleave.irs_\"+this.plugin_count));this.$cache.grid_labels=[];this.coords.big=[];this.coords.big_w=[];this.coords.big_p=[];this.coords.big_x=[];cancelAnimationFrame(this.raf_id)},bindEvents:function(){if(!this.no_diapason){this.$cache.body.on(\"touchmove.irs_\"+this.plugin_count,this.pointerMove.bind(this));this.$cache.body.on(\"mousemove.irs_\"+this.plugin_count,\r\n        this.pointerMove.bind(this));this.$cache.win.on(\"touchend.irs_\"+this.plugin_count,this.pointerUp.bind(this));this.$cache.win.on(\"mouseup.irs_\"+this.plugin_count,this.pointerUp.bind(this));this.$cache.line.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\"));this.$cache.line.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\"));this.options.drag_interval&&\"double\"===this.options.type?(this.$cache.bar.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\r\n        \"both\")),this.$cache.bar.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"both\"))):(this.$cache.bar.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.bar.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")));\"single\"===this.options.type?(this.$cache.single.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"single\")),this.$cache.s_single.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"single\")),\r\n        this.$cache.shad_single.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.single.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"single\")),this.$cache.s_single.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"single\")),this.$cache.edge.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.shad_single.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\"))):(this.$cache.single.on(\"touchstart.irs_\"+\r\n        this.plugin_count,this.pointerDown.bind(this,null)),this.$cache.single.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,null)),this.$cache.from.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"from\")),this.$cache.s_from.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"from\")),this.$cache.to.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"to\")),this.$cache.s_to.on(\"touchstart.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"to\")),\r\n        this.$cache.shad_from.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.shad_to.on(\"touchstart.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.from.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"from\")),this.$cache.s_from.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"from\")),this.$cache.to.on(\"mousedown.irs_\"+this.plugin_count,this.pointerDown.bind(this,\"to\")),this.$cache.s_to.on(\"mousedown.irs_\"+\r\n        this.plugin_count,this.pointerDown.bind(this,\"to\")),this.$cache.shad_from.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")),this.$cache.shad_to.on(\"mousedown.irs_\"+this.plugin_count,this.pointerClick.bind(this,\"click\")));if(this.options.keyboard)this.$cache.line.on(\"keydown.irs_\"+this.plugin_count,this.key.bind(this,\"keyboard\"));m&&(this.$cache.body.on(\"mouseup.irs_\"+this.plugin_count,this.pointerUp.bind(this)),this.$cache.body.on(\"mouseleave.irs_\"+this.plugin_count,this.pointerUp.bind(this)))}},\r\n    pointerMove:function(a){this.dragging&&(this.coords.x_pointer=(a.pageX||a.originalEvent.touches&&a.originalEvent.touches[0].pageX)-this.coords.x_gap,this.calc())},pointerUp:function(a){this.current_plugin===this.plugin_count&&this.is_active&&(this.is_active=!1,this.$cache.cont.find(\".state_hover\").removeClass(\"state_hover\"),this.force_redraw=!0,m&&f(\"*\").prop(\"unselectable\",!1),this.updateScene(),this.restoreOriginalMinInterval(),(f.contains(this.$cache.cont[0],a.target)||this.dragging)&&this.callOnFinish(),\r\n        this.dragging=!1)},pointerDown:function(a,b){b.preventDefault();var d=b.pageX||b.originalEvent.touches&&b.originalEvent.touches[0].pageX;2!==b.button&&(\"both\"===a&&this.setTempMinInterval(),a||(a=this.target||\"from\"),this.current_plugin=this.plugin_count,this.target=a,this.dragging=this.is_active=!0,this.coords.x_gap=this.$cache.rs.offset().left,this.coords.x_pointer=d-this.coords.x_gap,this.calcPointerPercent(),this.changeLevel(a),m&&f(\"*\").prop(\"unselectable\",!0),this.$cache.line.trigger(\"focus\"),\r\n        this.updateScene())},pointerClick:function(a,b){b.preventDefault();var d=b.pageX||b.originalEvent.touches&&b.originalEvent.touches[0].pageX;2!==b.button&&(this.current_plugin=this.plugin_count,this.target=a,this.is_click=!0,this.coords.x_gap=this.$cache.rs.offset().left,this.coords.x_pointer=+(d-this.coords.x_gap).toFixed(),this.force_redraw=!0,this.calc(),this.$cache.line.trigger(\"focus\"))},key:function(a,b){if(!(this.current_plugin!==this.plugin_count||b.altKey||b.ctrlKey||b.shiftKey||b.metaKey)){switch(b.which){case 83:case 65:case 40:case 37:b.preventDefault();\r\n        this.moveByKey(!1);break;case 87:case 68:case 38:case 39:b.preventDefault(),this.moveByKey(!0)}return!0}},moveByKey:function(a){var b=this.coords.p_pointer,b=a?b+this.options.keyboard_step:b-this.options.keyboard_step;this.coords.x_pointer=this.toFixed(this.coords.w_rs/100*b);this.is_key=!0;this.calc()},setMinMax:function(){this.options&&(this.options.hide_min_max?(this.$cache.min[0].style.display=\"none\",this.$cache.max[0].style.display=\"none\"):(this.options.values.length?(this.$cache.min.html(this.decorate(this.options.p_values[this.options.min])),\r\n        this.$cache.max.html(this.decorate(this.options.p_values[this.options.max]))):(this.$cache.min.html(this.decorate(this._prettify(this.options.min),this.options.min)),this.$cache.max.html(this.decorate(this._prettify(this.options.max),this.options.max))),this.labels.w_min=this.$cache.min.outerWidth(!1),this.labels.w_max=this.$cache.max.outerWidth(!1)))},setTempMinInterval:function(){var a=this.result.to-this.result.from;null===this.old_min_interval&&(this.old_min_interval=this.options.min_interval);\r\n        this.options.min_interval=a},restoreOriginalMinInterval:function(){null!==this.old_min_interval&&(this.options.min_interval=this.old_min_interval,this.old_min_interval=null)},calc:function(a){if(this.options){this.calc_count++;if(10===this.calc_count||a)this.calc_count=0,this.coords.w_rs=this.$cache.rs.outerWidth(!1),this.calcHandlePercent();if(this.coords.w_rs){this.calcPointerPercent();a=this.getHandleX();\"both\"===this.target&&(this.coords.p_gap=0,a=this.getHandleX());\"click\"===this.target&&(this.coords.p_gap=\r\n        this.coords.p_handle/2,a=this.getHandleX(),this.target=this.options.drag_interval?\"both_one\":this.chooseHandle(a));switch(this.target){case \"base\":var b=(this.options.max-this.options.min)/100;a=(this.result.from-this.options.min)/b;b=(this.result.to-this.options.min)/b;this.coords.p_single_real=this.toFixed(a);this.coords.p_from_real=this.toFixed(a);this.coords.p_to_real=this.toFixed(b);this.coords.p_single_real=this.checkDiapason(this.coords.p_single_real,this.options.from_min,this.options.from_max);\r\n        this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max);this.coords.p_to_real=this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max);this.coords.p_single_fake=this.convertToFakePercent(this.coords.p_single_real);this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real);this.target=null;break;case \"single\":if(this.options.from_fixed)break;\r\n        this.coords.p_single_real=this.convertToRealPercent(a);this.coords.p_single_real=this.calcWithStep(this.coords.p_single_real);this.coords.p_single_real=this.checkDiapason(this.coords.p_single_real,this.options.from_min,this.options.from_max);this.coords.p_single_fake=this.convertToFakePercent(this.coords.p_single_real);break;case \"from\":if(this.options.from_fixed)break;this.coords.p_from_real=this.convertToRealPercent(a);this.coords.p_from_real=this.calcWithStep(this.coords.p_from_real);this.coords.p_from_real>\r\n    this.coords.p_to_real&&(this.coords.p_from_real=this.coords.p_to_real);this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max);this.coords.p_from_real=this.checkMinInterval(this.coords.p_from_real,this.coords.p_to_real,\"from\");this.coords.p_from_real=this.checkMaxInterval(this.coords.p_from_real,this.coords.p_to_real,\"from\");this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);break;case \"to\":if(this.options.to_fixed)break;\r\n        this.coords.p_to_real=this.convertToRealPercent(a);this.coords.p_to_real=this.calcWithStep(this.coords.p_to_real);this.coords.p_to_real<this.coords.p_from_real&&(this.coords.p_to_real=this.coords.p_from_real);this.coords.p_to_real=this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max);this.coords.p_to_real=this.checkMinInterval(this.coords.p_to_real,this.coords.p_from_real,\"to\");this.coords.p_to_real=this.checkMaxInterval(this.coords.p_to_real,this.coords.p_from_real,\"to\");\r\n        this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real);break;case \"both\":if(this.options.from_fixed||this.options.to_fixed)break;a=this.toFixed(a+.001*this.coords.p_handle);this.coords.p_from_real=this.convertToRealPercent(a)-this.coords.p_gap_left;this.coords.p_from_real=this.calcWithStep(this.coords.p_from_real);this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max);this.coords.p_from_real=this.checkMinInterval(this.coords.p_from_real,\r\n        this.coords.p_to_real,\"from\");this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);this.coords.p_to_real=this.convertToRealPercent(a)+this.coords.p_gap_right;this.coords.p_to_real=this.calcWithStep(this.coords.p_to_real);this.coords.p_to_real=this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max);this.coords.p_to_real=this.checkMinInterval(this.coords.p_to_real,this.coords.p_from_real,\"to\");this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real);\r\n        break;case \"both_one\":if(!this.options.from_fixed&&!this.options.to_fixed){var d=this.convertToRealPercent(a);a=this.result.to_percent-this.result.from_percent;var c=a/2,b=d-c,d=d+c;0>b&&(b=0,d=b+a);100<d&&(d=100,b=d-a);this.coords.p_from_real=this.calcWithStep(b);this.coords.p_from_real=this.checkDiapason(this.coords.p_from_real,this.options.from_min,this.options.from_max);this.coords.p_from_fake=this.convertToFakePercent(this.coords.p_from_real);this.coords.p_to_real=this.calcWithStep(d);this.coords.p_to_real=\r\n        this.checkDiapason(this.coords.p_to_real,this.options.to_min,this.options.to_max);this.coords.p_to_fake=this.convertToFakePercent(this.coords.p_to_real)}}\"single\"===this.options.type?(this.coords.p_bar_x=this.coords.p_handle/2,this.coords.p_bar_w=this.coords.p_single_fake,this.result.from_percent=this.coords.p_single_real,this.result.from=this.convertToValue(this.coords.p_single_real),this.options.values.length&&(this.result.from_value=this.options.values[this.result.from])):(this.coords.p_bar_x=\r\n        this.toFixed(this.coords.p_from_fake+this.coords.p_handle/2),this.coords.p_bar_w=this.toFixed(this.coords.p_to_fake-this.coords.p_from_fake),this.result.from_percent=this.coords.p_from_real,this.result.from=this.convertToValue(this.coords.p_from_real),this.result.to_percent=this.coords.p_to_real,this.result.to=this.convertToValue(this.coords.p_to_real),this.options.values.length&&(this.result.from_value=this.options.values[this.result.from],this.result.to_value=this.options.values[this.result.to]));\r\n        this.calcMinMax();this.calcLabels()}}},calcPointerPercent:function(){this.coords.w_rs?(0>this.coords.x_pointer||isNaN(this.coords.x_pointer)?this.coords.x_pointer=0:this.coords.x_pointer>this.coords.w_rs&&(this.coords.x_pointer=this.coords.w_rs),this.coords.p_pointer=this.toFixed(this.coords.x_pointer/this.coords.w_rs*100)):this.coords.p_pointer=0},convertToRealPercent:function(a){return a/(100-this.coords.p_handle)*100},convertToFakePercent:function(a){return a/100*(100-this.coords.p_handle)},getHandleX:function(){var a=\r\n        100-this.coords.p_handle,b=this.toFixed(this.coords.p_pointer-this.coords.p_gap);0>b?b=0:b>a&&(b=a);return b},calcHandlePercent:function(){this.coords.w_handle=\"single\"===this.options.type?this.$cache.s_single.outerWidth(!1):this.$cache.s_from.outerWidth(!1);this.coords.p_handle=this.toFixed(this.coords.w_handle/this.coords.w_rs*100)},chooseHandle:function(a){return\"single\"===this.options.type?\"single\":a>=this.coords.p_from_real+(this.coords.p_to_real-this.coords.p_from_real)/2?this.options.to_fixed?\r\n        \"from\":\"to\":this.options.from_fixed?\"to\":\"from\"},calcMinMax:function(){this.coords.w_rs&&(this.labels.p_min=this.labels.w_min/this.coords.w_rs*100,this.labels.p_max=this.labels.w_max/this.coords.w_rs*100)},calcLabels:function(){this.coords.w_rs&&!this.options.hide_from_to&&(\"single\"===this.options.type?(this.labels.w_single=this.$cache.single.outerWidth(!1),this.labels.p_single_fake=this.labels.w_single/this.coords.w_rs*100,this.labels.p_single_left=this.coords.p_single_fake+this.coords.p_handle/\r\n        2-this.labels.p_single_fake/2):(this.labels.w_from=this.$cache.from.outerWidth(!1),this.labels.p_from_fake=this.labels.w_from/this.coords.w_rs*100,this.labels.p_from_left=this.coords.p_from_fake+this.coords.p_handle/2-this.labels.p_from_fake/2,this.labels.p_from_left=this.toFixed(this.labels.p_from_left),this.labels.p_from_left=this.checkEdges(this.labels.p_from_left,this.labels.p_from_fake),this.labels.w_to=this.$cache.to.outerWidth(!1),this.labels.p_to_fake=this.labels.w_to/this.coords.w_rs*100,\r\n        this.labels.p_to_left=this.coords.p_to_fake+this.coords.p_handle/2-this.labels.p_to_fake/2,this.labels.p_to_left=this.toFixed(this.labels.p_to_left),this.labels.p_to_left=this.checkEdges(this.labels.p_to_left,this.labels.p_to_fake),this.labels.w_single=this.$cache.single.outerWidth(!1),this.labels.p_single_fake=this.labels.w_single/this.coords.w_rs*100,this.labels.p_single_left=(this.labels.p_from_left+this.labels.p_to_left+this.labels.p_to_fake)/2-this.labels.p_single_fake/2,this.labels.p_single_left=\r\n        this.toFixed(this.labels.p_single_left)),this.labels.p_single_left=this.checkEdges(this.labels.p_single_left,this.labels.p_single_fake))},updateScene:function(){this.raf_id&&(cancelAnimationFrame(this.raf_id),this.raf_id=null);clearTimeout(this.update_tm);this.update_tm=null;this.options&&(this.drawHandles(),this.is_active?this.raf_id=requestAnimationFrame(this.updateScene.bind(this)):this.update_tm=setTimeout(this.updateScene.bind(this),300))},drawHandles:function(){this.coords.w_rs=this.$cache.rs.outerWidth(!1);\r\n        if(this.coords.w_rs){this.coords.w_rs!==this.coords.w_rs_old&&(this.target=\"base\",this.is_resize=!0);if(this.coords.w_rs!==this.coords.w_rs_old||this.force_redraw)this.setMinMax(),this.calc(!0),this.drawLabels(),this.options.grid&&(this.calcGridMargin(),this.calcGridLabels()),this.force_redraw=!0,this.coords.w_rs_old=this.coords.w_rs,this.drawShadow();if(this.coords.w_rs&&(this.dragging||this.force_redraw||this.is_key)){if(this.old_from!==this.result.from||this.old_to!==this.result.to||this.force_redraw||\r\n            this.is_key){this.drawLabels();this.$cache.bar[0].style.left=this.coords.p_bar_x+\"%\";this.$cache.bar[0].style.width=this.coords.p_bar_w+\"%\";if(\"single\"===this.options.type)this.$cache.s_single[0].style.left=this.coords.p_single_fake+\"%\";else{this.$cache.s_from[0].style.left=this.coords.p_from_fake+\"%\";this.$cache.s_to[0].style.left=this.coords.p_to_fake+\"%\";if(this.old_from!==this.result.from||this.force_redraw)this.$cache.from[0].style.left=this.labels.p_from_left+\"%\";if(this.old_to!==this.result.to||\r\n            this.force_redraw)this.$cache.to[0].style.left=this.labels.p_to_left+\"%\"}this.$cache.single[0].style.left=this.labels.p_single_left+\"%\";this.writeToInput();this.old_from===this.result.from&&this.old_to===this.result.to||this.is_start||(this.$cache.input.trigger(\"change\"),this.$cache.input.trigger(\"input\"));this.old_from=this.result.from;this.old_to=this.result.to;this.is_resize||this.is_update||this.is_start||this.is_finish||this.callOnChange();if(this.is_key||this.is_click||this.is_first_update)this.is_first_update=\r\n            this.is_click=this.is_key=!1,this.callOnFinish();this.is_finish=this.is_resize=this.is_update=!1}this.force_redraw=this.is_click=this.is_key=this.is_start=!1}}},drawLabels:function(){if(this.options){var a=this.options.values.length,b=this.options.p_values,d;if(!this.options.hide_from_to)if(\"single\"===this.options.type)a=a?this.decorate(b[this.result.from]):this.decorate(this._prettify(this.result.from),this.result.from),this.$cache.single.html(a),this.calcLabels(),this.$cache.min[0].style.visibility=\r\n        this.labels.p_single_left<this.labels.p_min+1?\"hidden\":\"visible\",this.$cache.max[0].style.visibility=this.labels.p_single_left+this.labels.p_single_fake>100-this.labels.p_max-1?\"hidden\":\"visible\";else{a?(this.options.decorate_both?(a=this.decorate(b[this.result.from]),a+=this.options.values_separator,a+=this.decorate(b[this.result.to])):a=this.decorate(b[this.result.from]+this.options.values_separator+b[this.result.to]),d=this.decorate(b[this.result.from]),b=this.decorate(b[this.result.to])):(this.options.decorate_both?\r\n        (a=this.decorate(this._prettify(this.result.from),this.result.from),a+=this.options.values_separator,a+=this.decorate(this._prettify(this.result.to),this.result.to)):a=this.decorate(this._prettify(this.result.from)+this.options.values_separator+this._prettify(this.result.to),this.result.to),d=this.decorate(this._prettify(this.result.from),this.result.from),b=this.decorate(this._prettify(this.result.to),this.result.to));this.$cache.single.html(a);this.$cache.from.html(d);this.$cache.to.html(b);this.calcLabels();\r\n        b=Math.min(this.labels.p_single_left,this.labels.p_from_left);a=this.labels.p_single_left+this.labels.p_single_fake;d=this.labels.p_to_left+this.labels.p_to_fake;var c=Math.max(a,d);this.labels.p_from_left+this.labels.p_from_fake>=this.labels.p_to_left?(this.$cache.from[0].style.visibility=\"hidden\",this.$cache.to[0].style.visibility=\"hidden\",this.$cache.single[0].style.visibility=\"visible\",this.result.from===this.result.to?(\"from\"===this.target?this.$cache.from[0].style.visibility=\"visible\":\"to\"===\r\n        this.target?this.$cache.to[0].style.visibility=\"visible\":this.target||(this.$cache.from[0].style.visibility=\"visible\"),this.$cache.single[0].style.visibility=\"hidden\",c=d):(this.$cache.from[0].style.visibility=\"hidden\",this.$cache.to[0].style.visibility=\"hidden\",this.$cache.single[0].style.visibility=\"visible\",c=Math.max(a,d))):(this.$cache.from[0].style.visibility=\"visible\",this.$cache.to[0].style.visibility=\"visible\",this.$cache.single[0].style.visibility=\"hidden\");this.$cache.min[0].style.visibility=\r\n            b<this.labels.p_min+1?\"hidden\":\"visible\";this.$cache.max[0].style.visibility=c>100-this.labels.p_max-1?\"hidden\":\"visible\"}}},drawShadow:function(){var a=this.options,b=this.$cache,d=\"number\"===typeof a.from_min&&!isNaN(a.from_min),c=\"number\"===typeof a.from_max&&!isNaN(a.from_max),e=\"number\"===typeof a.to_min&&!isNaN(a.to_min),g=\"number\"===typeof a.to_max&&!isNaN(a.to_max);\"single\"===a.type?a.from_shadow&&(d||c)?(d=this.convertToPercent(d?a.from_min:a.min),c=this.convertToPercent(c?a.from_max:a.max)-\r\n        d,d=this.toFixed(d-this.coords.p_handle/100*d),c=this.toFixed(c-this.coords.p_handle/100*c),d+=this.coords.p_handle/2,b.shad_single[0].style.display=\"block\",b.shad_single[0].style.left=d+\"%\",b.shad_single[0].style.width=c+\"%\"):b.shad_single[0].style.display=\"none\":(a.from_shadow&&(d||c)?(d=this.convertToPercent(d?a.from_min:a.min),c=this.convertToPercent(c?a.from_max:a.max)-d,d=this.toFixed(d-this.coords.p_handle/100*d),c=this.toFixed(c-this.coords.p_handle/100*c),d+=this.coords.p_handle/2,b.shad_from[0].style.display=\r\n        \"block\",b.shad_from[0].style.left=d+\"%\",b.shad_from[0].style.width=c+\"%\"):b.shad_from[0].style.display=\"none\",a.to_shadow&&(e||g)?(e=this.convertToPercent(e?a.to_min:a.min),a=this.convertToPercent(g?a.to_max:a.max)-e,e=this.toFixed(e-this.coords.p_handle/100*e),a=this.toFixed(a-this.coords.p_handle/100*a),e+=this.coords.p_handle/2,b.shad_to[0].style.display=\"block\",b.shad_to[0].style.left=e+\"%\",b.shad_to[0].style.width=a+\"%\"):b.shad_to[0].style.display=\"none\")},writeToInput:function(){\"single\"===\r\n    this.options.type?(this.options.values.length?this.$cache.input.prop(\"value\",this.result.from_value):this.$cache.input.prop(\"value\",this.result.from),this.$cache.input.data(\"from\",this.result.from)):(this.options.values.length?this.$cache.input.prop(\"value\",this.result.from_value+this.options.input_values_separator+this.result.to_value):this.$cache.input.prop(\"value\",this.result.from+this.options.input_values_separator+this.result.to),this.$cache.input.data(\"from\",this.result.from),this.$cache.input.data(\"to\",\r\n        this.result.to))},callOnStart:function(){this.writeToInput();if(this.options.onStart&&\"function\"===typeof this.options.onStart)this.options.onStart(this.result)},callOnChange:function(){this.writeToInput();if(this.options.onChange&&\"function\"===typeof this.options.onChange)this.options.onChange(this.result)},callOnFinish:function(){this.writeToInput();if(this.options.onFinish&&\"function\"===typeof this.options.onFinish)this.options.onFinish(this.result)},callOnUpdate:function(){this.writeToInput();\r\n        if(this.options.onUpdate&&\"function\"===typeof this.options.onUpdate)this.options.onUpdate(this.result)},toggleInput:function(){this.$cache.input.toggleClass(\"irs-hidden-input\")},convertToPercent:function(a,b){var d=this.options.max-this.options.min;return d?this.toFixed((b?a:a-this.options.min)/(d/100)):(this.no_diapason=!0,0)},convertToValue:function(a){var b=this.options.min,d=this.options.max,c=b.toString().split(\".\")[1],e=d.toString().split(\".\")[1],g,l,f=0,k=0;if(0===a)return this.options.min;\r\n        if(100===a)return this.options.max;c&&(f=g=c.length);e&&(f=l=e.length);g&&l&&(f=g>=l?g:l);0>b&&(k=Math.abs(b),b=+(b+k).toFixed(f),d=+(d+k).toFixed(f));a=(d-b)/100*a+b;(b=this.options.step.toString().split(\".\")[1])?a=+a.toFixed(b.length):(a/=this.options.step,a*=this.options.step,a=+a.toFixed(0));k&&(a-=k);k=b?+a.toFixed(b.length):this.toFixed(a);k<this.options.min?k=this.options.min:k>this.options.max&&(k=this.options.max);return k},calcWithStep:function(a){var b=Math.round(a/this.coords.p_step)*\r\n        this.coords.p_step;100<b&&(b=100);100===a&&(b=100);return this.toFixed(b)},checkMinInterval:function(a,b,d){var c=this.options;if(!c.min_interval)return a;a=this.convertToValue(a);b=this.convertToValue(b);\"from\"===d?b-a<c.min_interval&&(a=b-c.min_interval):a-b<c.min_interval&&(a=b+c.min_interval);return this.convertToPercent(a)},checkMaxInterval:function(a,b,d){var c=this.options;if(!c.max_interval)return a;a=this.convertToValue(a);b=this.convertToValue(b);\"from\"===d?b-a>c.max_interval&&(a=b-c.max_interval):\r\n        a-b>c.max_interval&&(a=b+c.max_interval);return this.convertToPercent(a)},checkDiapason:function(a,b,d){a=this.convertToValue(a);var c=this.options;\"number\"!==typeof b&&(b=c.min);\"number\"!==typeof d&&(d=c.max);a<b&&(a=b);a>d&&(a=d);return this.convertToPercent(a)},toFixed:function(a){a=a.toFixed(20);return+a},_prettify:function(a){return this.options.prettify_enabled?this.options.prettify&&\"function\"===typeof this.options.prettify?this.options.prettify(a):this.prettify(a):a},prettify:function(a){return a.toString().replace(/(\\d{1,3}(?=(?:\\d\\d\\d)+(?!\\d)))/g,\r\n        \"$1\"+this.options.prettify_separator)},checkEdges:function(a,b){if(!this.options.force_edges)return this.toFixed(a);0>a?a=0:a>100-b&&(a=100-b);return this.toFixed(a)},validate:function(){var a=this.options,b=this.result,d=a.values,c=d.length,e,g;\"string\"===typeof a.min&&(a.min=+a.min);\"string\"===typeof a.max&&(a.max=+a.max);\"string\"===typeof a.from&&(a.from=+a.from);\"string\"===typeof a.to&&(a.to=+a.to);\"string\"===typeof a.step&&(a.step=+a.step);\"string\"===typeof a.from_min&&(a.from_min=+a.from_min);\r\n        \"string\"===typeof a.from_max&&(a.from_max=+a.from_max);\"string\"===typeof a.to_min&&(a.to_min=+a.to_min);\"string\"===typeof a.to_max&&(a.to_max=+a.to_max);\"string\"===typeof a.keyboard_step&&(a.keyboard_step=+a.keyboard_step);\"string\"===typeof a.grid_num&&(a.grid_num=+a.grid_num);a.max<a.min&&(a.max=a.min);if(c)for(a.p_values=[],a.min=0,a.max=c-1,a.step=1,a.grid_num=a.max,a.grid_snap=!0,g=0;g<c;g++)e=+d[g],isNaN(e)?e=d[g]:(d[g]=e,e=this._prettify(e)),a.p_values.push(e);if(\"number\"!==typeof a.from||isNaN(a.from))a.from=\r\n            a.min;if(\"number\"!==typeof a.to||isNaN(a.to))a.to=a.max;\"single\"===a.type?(a.from<a.min&&(a.from=a.min),a.from>a.max&&(a.from=a.max)):(a.from<a.min&&(a.from=a.min),a.from>a.max&&(a.from=a.max),a.to<a.min&&(a.to=a.min),a.to>a.max&&(a.to=a.max),this.update_check.from&&(this.update_check.from!==a.from&&a.from>a.to&&(a.from=a.to),this.update_check.to!==a.to&&a.to<a.from&&(a.to=a.from)),a.from>a.to&&(a.from=a.to),a.to<a.from&&(a.to=a.from));if(\"number\"!==typeof a.step||isNaN(a.step)||!a.step||0>a.step)a.step=\r\n            1;if(\"number\"!==typeof a.keyboard_step||isNaN(a.keyboard_step)||!a.keyboard_step||0>a.keyboard_step)a.keyboard_step=5;\"number\"===typeof a.from_min&&a.from<a.from_min&&(a.from=a.from_min);\"number\"===typeof a.from_max&&a.from>a.from_max&&(a.from=a.from_max);\"number\"===typeof a.to_min&&a.to<a.to_min&&(a.to=a.to_min);\"number\"===typeof a.to_max&&a.from>a.to_max&&(a.to=a.to_max);if(b){b.min!==a.min&&(b.min=a.min);b.max!==a.max&&(b.max=a.max);if(b.from<b.min||b.from>b.max)b.from=a.from;if(b.to<b.min||b.to>\r\n            b.max)b.to=a.to}if(\"number\"!==typeof a.min_interval||isNaN(a.min_interval)||!a.min_interval||0>a.min_interval)a.min_interval=0;if(\"number\"!==typeof a.max_interval||isNaN(a.max_interval)||!a.max_interval||0>a.max_interval)a.max_interval=0;a.min_interval&&a.min_interval>a.max-a.min&&(a.min_interval=a.max-a.min);a.max_interval&&a.max_interval>a.max-a.min&&(a.max_interval=a.max-a.min)},decorate:function(a,b){var d=\"\",c=this.options;c.prefix&&(d+=c.prefix);d+=a;c.max_postfix&&(c.values.length&&a===c.p_values[c.max]?\r\n        (d+=c.max_postfix,c.postfix&&(d+=\" \")):b===c.max&&(d+=c.max_postfix,c.postfix&&(d+=\" \")));c.postfix&&(d+=c.postfix);return d},updateFrom:function(){this.result.from=this.options.from;this.result.from_percent=this.convertToPercent(this.result.from);this.options.values&&(this.result.from_value=this.options.values[this.result.from])},updateTo:function(){this.result.to=this.options.to;this.result.to_percent=this.convertToPercent(this.result.to);this.options.values&&(this.result.to_value=this.options.values[this.result.to])},\r\n    updateResult:function(){this.result.min=this.options.min;this.result.max=this.options.max;this.updateFrom();this.updateTo()},appendGrid:function(){if(this.options.grid){var a=this.options,b,d;b=a.max-a.min;var c=a.grid_num,e,g,f=4,h,k,m,n=\"\";this.calcGridMargin();a.grid_snap?(c=b/a.step,e=this.toFixed(a.step/(b/100))):e=this.toFixed(100/c);4<c&&(f=3);7<c&&(f=2);14<c&&(f=1);28<c&&(f=0);for(b=0;b<c+1;b++){h=f;g=this.toFixed(e*b);100<g&&(g=100,h-=2,0>h&&(h=0));this.coords.big[b]=g;k=(g-e*(b-1))/(h+1);\r\n        for(d=1;d<=h&&0!==g;d++)m=this.toFixed(g-k*d),n+='<span class=\"irs-grid-pol small\" style=\"left: '+m+'%\"></span>';n+='<span class=\"irs-grid-pol\" style=\"left: '+g+'%\"></span>';d=this.convertToValue(g);d=a.values.length?a.p_values[d]:this._prettify(d);n+='<span class=\"irs-grid-text js-grid-text-'+b+'\" style=\"left: '+g+'%\">'+d+\"</span>\"}this.coords.big_num=Math.ceil(c+1);this.$cache.cont.addClass(\"irs-with-grid\");this.$cache.grid.html(n);this.cacheGridLabels()}},cacheGridLabels:function(){var a,b,d=this.coords.big_num;\r\n        for(b=0;b<d;b++)a=this.$cache.grid.find(\".js-grid-text-\"+b),this.$cache.grid_labels.push(a);this.calcGridLabels()},calcGridLabels:function(){var a,b;b=[];var d=[],c=this.coords.big_num;for(a=0;a<c;a++)this.coords.big_w[a]=this.$cache.grid_labels[a].outerWidth(!1),this.coords.big_p[a]=this.toFixed(this.coords.big_w[a]/this.coords.w_rs*100),this.coords.big_x[a]=this.toFixed(this.coords.big_p[a]/2),b[a]=this.toFixed(this.coords.big[a]-this.coords.big_x[a]),d[a]=this.toFixed(b[a]+this.coords.big_p[a]);\r\n        this.options.force_edges&&(b[0]<-this.coords.grid_gap&&(b[0]=-this.coords.grid_gap,d[0]=this.toFixed(b[0]+this.coords.big_p[0]),this.coords.big_x[0]=this.coords.grid_gap),d[c-1]>100+this.coords.grid_gap&&(d[c-1]=100+this.coords.grid_gap,b[c-1]=this.toFixed(d[c-1]-this.coords.big_p[c-1]),this.coords.big_x[c-1]=this.toFixed(this.coords.big_p[c-1]-this.coords.grid_gap)));this.calcGridCollision(2,b,d);this.calcGridCollision(4,b,d);for(a=0;a<c;a++)b=this.$cache.grid_labels[a][0],this.coords.big_x[a]!==\r\n        Number.POSITIVE_INFINITY&&(b.style.marginLeft=-this.coords.big_x[a]+\"%\")},calcGridCollision:function(a,b,d){var c,e,g,f=this.coords.big_num;for(c=0;c<f;c+=a){e=c+a/2;if(e>=f)break;g=this.$cache.grid_labels[e][0];g.style.visibility=d[c]<=b[e]?\"visible\":\"hidden\"}},calcGridMargin:function(){this.options.grid_margin&&(this.coords.w_rs=this.$cache.rs.outerWidth(!1),this.coords.w_rs&&(this.coords.w_handle=\"single\"===this.options.type?this.$cache.s_single.outerWidth(!1):this.$cache.s_from.outerWidth(!1),\r\n        this.coords.p_handle=this.toFixed(this.coords.w_handle/this.coords.w_rs*100),this.coords.grid_gap=this.toFixed(this.coords.p_handle/2-.1),this.$cache.grid[0].style.width=this.toFixed(100-this.coords.p_handle)+\"%\",this.$cache.grid[0].style.left=this.coords.grid_gap+\"%\"))},update:function(a){this.input&&(this.is_update=!0,this.options.from=this.result.from,this.options.to=this.result.to,this.update_check.from=this.result.from,this.update_check.to=this.result.to,this.options=f.extend(this.options,a),\r\n        this.validate(),this.updateResult(a),this.toggleInput(),this.remove(),this.init(!0))},reset:function(){this.input&&(this.updateResult(),this.update())},destroy:function(){this.input&&(this.toggleInput(),this.$cache.input.prop(\"readonly\",!1),f.data(this.input,\"ionRangeSlider\",null),this.remove(),this.options=this.input=null)}};f.fn.ionRangeSlider=function(a){return this.each(function(){f.data(this,\"ionRangeSlider\")||f.data(this,\"ionRangeSlider\",new r(this,a,u++))})};(function(){for(var a=0,b=[\"ms\",\r\n    \"moz\",\"webkit\",\"o\"],d=0;d<b.length&&!h.requestAnimationFrame;++d)h.requestAnimationFrame=h[b[d]+\"RequestAnimationFrame\"],h.cancelAnimationFrame=h[b[d]+\"CancelAnimationFrame\"]||h[b[d]+\"CancelRequestAnimationFrame\"];h.requestAnimationFrame||(h.requestAnimationFrame=function(b,d){var c=(new Date).getTime(),e=Math.max(0,16-(c-a)),f=h.setTimeout(function(){b(c+e)},e);a=c+e;return f});h.cancelAnimationFrame||(h.cancelAnimationFrame=function(a){clearTimeout(a)})})()});\r\n","Mageplaza_Core/js/jquery.magnific-popup.min.js":"// Magnific Popup v1.1.0 by Dmitry Semenov\r\n// http://bit.ly/magnific-popup#build=inline+image+ajax+iframe+gallery+retina+imagezoom\r\n(function(a){typeof define==\"function\"&&define.amd?define([\"jquery\"],a):typeof exports==\"object\"?a(require(\"jquery\")):a(window.jQuery||window.Zepto)})(function(a){var b=\"Close\",c=\"BeforeClose\",d=\"AfterClose\",e=\"BeforeAppend\",f=\"MarkupParse\",g=\"Open\",h=\"Change\",i=\"mfp\",j=\".\"+i,k=\"mfp-ready\",l=\"mfp-removing\",m=\"mfp-prevent-close\",n,o=function(){},p=!!window.jQuery,q,r=a(window),s,t,u,v,w=function(a,b){n.ev.on(i+a+j,b)},x=function(b,c,d,e){var f=document.createElement(\"div\");return f.className=\"mfp-\"+b,d&&(f.innerHTML=d),e?c&&c.appendChild(f):(f=a(f),c&&f.appendTo(c)),f},y=function(b,c){n.ev.triggerHandler(i+b,c),n.st.callbacks&&(b=b.charAt(0).toLowerCase()+b.slice(1),n.st.callbacks[b]&&n.st.callbacks[b].apply(n,a.isArray(c)?c:[c]))},z=function(b){if(b!==v||!n.currTemplate.closeBtn)n.currTemplate.closeBtn=a(n.st.closeMarkup.replace(\"%title%\",n.st.tClose)),v=b;return n.currTemplate.closeBtn},A=function(){a.magnificPopup.instance||(n=new o,n.init(),a.magnificPopup.instance=n)},B=function(){var a=document.createElement(\"p\").style,b=[\"ms\",\"O\",\"Moz\",\"Webkit\"];if(a.transition!==undefined)return!0;while(b.length)if(b.pop()+\"Transition\"in a)return!0;return!1};o.prototype={constructor:o,init:function(){var b=navigator.appVersion;n.isLowIE=n.isIE8=document.all&&!document.addEventListener,n.isAndroid=/android/gi.test(b),n.isIOS=/iphone|ipad|ipod/gi.test(b),n.supportsTransition=B(),n.probablyMobile=n.isAndroid||n.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),s=a(document),n.popupsCache={}},open:function(b){var c;if(b.isObj===!1){n.items=b.items.toArray(),n.index=0;var d=b.items,e;for(c=0;c<d.length;c++){e=d[c],e.parsed&&(e=e.el[0]);if(e===b.el[0]){n.index=c;break}}}else n.items=a.isArray(b.items)?b.items:[b.items],n.index=b.index||0;if(n.isOpen){n.updateItemHTML();return}n.types=[],u=\"\",b.mainEl&&b.mainEl.length?n.ev=b.mainEl.eq(0):n.ev=s,b.key?(n.popupsCache[b.key]||(n.popupsCache[b.key]={}),n.currTemplate=n.popupsCache[b.key]):n.currTemplate={},n.st=a.extend(!0,{},a.magnificPopup.defaults,b),n.fixedContentPos=n.st.fixedContentPos===\"auto\"?!n.probablyMobile:n.st.fixedContentPos,n.st.modal&&(n.st.closeOnContentClick=!1,n.st.closeOnBgClick=!1,n.st.showCloseBtn=!1,n.st.enableEscapeKey=!1),n.bgOverlay||(n.bgOverlay=x(\"bg\").on(\"click\"+j,function(){n.close()}),n.wrap=x(\"wrap\").attr(\"tabindex\",-1).on(\"click\"+j,function(a){n._checkIfClose(a.target)&&n.close()}),n.container=x(\"container\",n.wrap)),n.contentContainer=x(\"content\"),n.st.preloader&&(n.preloader=x(\"preloader\",n.container,n.st.tLoading));var h=a.magnificPopup.modules;for(c=0;c<h.length;c++){var i=h[c];i=i.charAt(0).toUpperCase()+i.slice(1),n[\"init\"+i].call(n)}y(\"BeforeOpen\"),n.st.showCloseBtn&&(n.st.closeBtnInside?(w(f,function(a,b,c,d){c.close_replaceWith=z(d.type)}),u+=\" mfp-close-btn-in\"):n.wrap.append(z())),n.st.alignTop&&(u+=\" mfp-align-top\"),n.fixedContentPos?n.wrap.css({overflow:n.st.overflowY,overflowX:\"hidden\",overflowY:n.st.overflowY}):n.wrap.css({top:r.scrollTop(),position:\"absolute\"}),(n.st.fixedBgPos===!1||n.st.fixedBgPos===\"auto\"&&!n.fixedContentPos)&&n.bgOverlay.css({height:s.height(),position:\"absolute\"}),n.st.enableEscapeKey&&s.on(\"keyup\"+j,function(a){a.keyCode===27&&n.close()}),r.on(\"resize\"+j,function(){n.updateSize()}),n.st.closeOnContentClick||(u+=\" mfp-auto-cursor\"),u&&n.wrap.addClass(u);var l=n.wH=r.height(),m={};if(n.fixedContentPos&&n._hasScrollBar(l)){var o=n._getScrollbarSize();o&&(m.marginRight=o)}n.fixedContentPos&&(n.isIE7?a(\"body, html\").css(\"overflow\",\"hidden\"):m.overflow=\"hidden\");var p=n.st.mainClass;return n.isIE7&&(p+=\" mfp-ie7\"),p&&n._addClassToMFP(p),n.updateItemHTML(),y(\"BuildControls\"),a(\"html\").css(m),n.bgOverlay.add(n.wrap).prependTo(n.st.prependTo||a(document.body)),n._lastFocusedEl=document.activeElement,setTimeout(function(){n.content?(n._addClassToMFP(k),n._setFocus()):n.bgOverlay.addClass(k),s.on(\"focusin\"+j,n._onFocusIn)},16),n.isOpen=!0,n.updateSize(l),y(g),b},close:function(){if(!n.isOpen)return;y(c),n.isOpen=!1,n.st.removalDelay&&!n.isLowIE&&n.supportsTransition?(n._addClassToMFP(l),setTimeout(function(){n._close()},n.st.removalDelay)):n._close()},_close:function(){y(b);var c=l+\" \"+k+\" \";n.bgOverlay.detach(),n.wrap.detach(),n.container.empty(),n.st.mainClass&&(c+=n.st.mainClass+\" \"),n._removeClassFromMFP(c);if(n.fixedContentPos){var e={marginRight:\"\"};n.isIE7?a(\"body, html\").css(\"overflow\",\"\"):e.overflow=\"\",a(\"html\").css(e)}s.off(\"keyup\"+j+\" focusin\"+j),n.ev.off(j),n.wrap.attr(\"class\",\"mfp-wrap\").removeAttr(\"style\"),n.bgOverlay.attr(\"class\",\"mfp-bg\"),n.container.attr(\"class\",\"mfp-container\"),n.st.showCloseBtn&&(!n.st.closeBtnInside||n.currTemplate[n.currItem.type]===!0)&&n.currTemplate.closeBtn&&n.currTemplate.closeBtn.detach(),n.st.autoFocusLast&&n._lastFocusedEl&&a(n._lastFocusedEl).focus(),n.currItem=null,n.content=null,n.currTemplate=null,n.prevHeight=0,y(d)},updateSize:function(a){if(n.isIOS){var b=document.documentElement.clientWidth/window.innerWidth,c=window.innerHeight*b;n.wrap.css(\"height\",c),n.wH=c}else n.wH=a||r.height();n.fixedContentPos||n.wrap.css(\"height\",n.wH),y(\"Resize\")},updateItemHTML:function(){var b=n.items[n.index];n.contentContainer.detach(),n.content&&n.content.detach(),b.parsed||(b=n.parseEl(n.index));var c=b.type;y(\"BeforeChange\",[n.currItem?n.currItem.type:\"\",c]),n.currItem=b;if(!n.currTemplate[c]){var d=n.st[c]?n.st[c].markup:!1;y(\"FirstMarkupParse\",d),d?n.currTemplate[c]=a(d):n.currTemplate[c]=!0}t&&t!==b.type&&n.container.removeClass(\"mfp-\"+t+\"-holder\");var e=n[\"get\"+c.charAt(0).toUpperCase()+c.slice(1)](b,n.currTemplate[c]);n.appendContent(e,c),b.preloaded=!0,y(h,b),t=b.type,n.container.prepend(n.contentContainer),y(\"AfterChange\")},appendContent:function(a,b){n.content=a,a?n.st.showCloseBtn&&n.st.closeBtnInside&&n.currTemplate[b]===!0?n.content.find(\".mfp-close\").length||n.content.append(z()):n.content=a:n.content=\"\",y(e),n.container.addClass(\"mfp-\"+b+\"-holder\"),n.contentContainer.append(n.content)},parseEl:function(b){var c=n.items[b],d;c.tagName?c={el:a(c)}:(d=c.type,c={data:c,src:c.src});if(c.el){var e=n.types;for(var f=0;f<e.length;f++)if(c.el.hasClass(\"mfp-\"+e[f])){d=e[f];break}c.src=c.el.attr(\"data-mfp-src\"),c.src||(c.src=c.el.attr(\"href\"))}return c.type=d||n.st.type||\"inline\",c.index=b,c.parsed=!0,n.items[b]=c,y(\"ElementParse\",c),n.items[b]},addGroup:function(a,b){var c=function(c){c.mfpEl=this,n._openClick(c,a,b)};b||(b={});var d=\"click.magnificPopup\";b.mainEl=a,b.items?(b.isObj=!0,a.off(d).on(d,c)):(b.isObj=!1,b.delegate?a.off(d).on(d,b.delegate,c):(b.items=a,a.off(d).on(d,c)))},_openClick:function(b,c,d){var e=d.midClick!==undefined?d.midClick:a.magnificPopup.defaults.midClick;if(!e&&(b.which===2||b.ctrlKey||b.metaKey||b.altKey||b.shiftKey))return;var f=d.disableOn!==undefined?d.disableOn:a.magnificPopup.defaults.disableOn;if(f)if(a.isFunction(f)){if(!f.call(n))return!0}else if(r.width()<f)return!0;b.type&&(b.preventDefault(),n.isOpen&&b.stopPropagation()),d.el=a(b.mfpEl),d.delegate&&(d.items=c.find(d.delegate)),n.open(d)},updateStatus:function(a,b){if(n.preloader){q!==a&&n.container.removeClass(\"mfp-s-\"+q),!b&&a===\"loading\"&&(b=n.st.tLoading);var c={status:a,text:b};y(\"UpdateStatus\",c),a=c.status,b=c.text,n.preloader.html(b),n.preloader.find(\"a\").on(\"click\",function(a){a.stopImmediatePropagation()}),n.container.addClass(\"mfp-s-\"+a),q=a}},_checkIfClose:function(b){if(a(b).hasClass(m))return;var c=n.st.closeOnContentClick,d=n.st.closeOnBgClick;if(c&&d)return!0;if(!n.content||a(b).hasClass(\"mfp-close\")||n.preloader&&b===n.preloader[0])return!0;if(b!==n.content[0]&&!a.contains(n.content[0],b)){if(d&&a.contains(document,b))return!0}else if(c)return!0;return!1},_addClassToMFP:function(a){n.bgOverlay.addClass(a),n.wrap.addClass(a)},_removeClassFromMFP:function(a){this.bgOverlay.removeClass(a),n.wrap.removeClass(a)},_hasScrollBar:function(a){return(n.isIE7?s.height():document.body.scrollHeight)>(a||r.height())},_setFocus:function(){(n.st.focus?n.content.find(n.st.focus).eq(0):n.wrap).focus()},_onFocusIn:function(b){if(b.target!==n.wrap[0]&&!a.contains(n.wrap[0],b.target))return n._setFocus(),!1},_parseMarkup:function(b,c,d){var e;d.data&&(c=a.extend(d.data,c)),y(f,[b,c,d]),a.each(c,function(c,d){if(d===undefined||d===!1)return!0;e=c.split(\"_\");if(e.length>1){var f=b.find(j+\"-\"+e[0]);if(f.length>0){var g=e[1];g===\"replaceWith\"?f[0]!==d[0]&&f.replaceWith(d):g===\"img\"?f.is(\"img\")?f.attr(\"src\",d):f.replaceWith(a(\"<img>\").attr(\"src\",d).attr(\"class\",f.attr(\"class\"))):f.attr(e[1],d)}}else b.find(j+\"-\"+c).html(d)})},_getScrollbarSize:function(){if(n.scrollbarSize===undefined){var a=document.createElement(\"div\");a.style.cssText=\"width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;\",document.body.appendChild(a),n.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return n.scrollbarSize}},a.magnificPopup={instance:null,proto:o.prototype,modules:[],open:function(b,c){return A(),b?b=a.extend(!0,{},b):b={},b.isObj=!0,b.index=c||0,this.instance.open(b)},close:function(){return a.magnificPopup.instance&&a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:\"\",preloader:!0,focus:\"\",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:\"auto\",fixedBgPos:\"auto\",overflowY:\"auto\",closeMarkup:'<button title=\"%title%\" type=\"button\" class=\"mfp-close\">&#215;</button>',tClose:\"Close (Esc)\",tLoading:\"Loading...\",autoFocusLast:!0}},a.fn.magnificPopup=function(b){A();var c=a(this);if(typeof b==\"string\")if(b===\"open\"){var d,e=p?c.data(\"magnificPopup\"):c[0].magnificPopup,f=parseInt(arguments[1],10)||0;e.items?d=e.items[f]:(d=c,e.delegate&&(d=d.find(e.delegate)),d=d.eq(f)),n._openClick({mfpEl:d},c,e)}else n.isOpen&&n[b].apply(n,Array.prototype.slice.call(arguments,1));else b=a.extend(!0,{},b),p?c.data(\"magnificPopup\",b):c[0].magnificPopup=b,n.addGroup(c,b);return c};var C=\"inline\",D,E,F,G=function(){F&&(E.after(F.addClass(D)).detach(),F=null)};a.magnificPopup.registerModule(C,{options:{hiddenClass:\"hide\",markup:\"\",tNotFound:\"Content not found\"},proto:{initInline:function(){n.types.push(C),w(b+\".\"+C,function(){G()})},getInline:function(b,c){G();if(b.src){var d=n.st.inline,e=a(b.src);if(e.length){var f=e[0].parentNode;f&&f.tagName&&(E||(D=d.hiddenClass,E=x(D),D=\"mfp-\"+D),F=e.after(E).detach().removeClass(D)),n.updateStatus(\"ready\")}else n.updateStatus(\"error\",d.tNotFound),e=a(\"<div>\");return b.inlineElement=e,e}return n.updateStatus(\"ready\"),n._parseMarkup(c,{},b),c}}});var H=\"ajax\",I,J=function(){I&&a(document.body).removeClass(I)},K=function(){J(),n.req&&n.req.abort()};a.magnificPopup.registerModule(H,{options:{settings:null,cursor:\"mfp-ajax-cur\",tError:'<a href=\"%url%\">The content</a> could not be loaded.'},proto:{initAjax:function(){n.types.push(H),I=n.st.ajax.cursor,w(b+\".\"+H,K),w(\"BeforeChange.\"+H,K)},getAjax:function(b){I&&a(document.body).addClass(I),n.updateStatus(\"loading\");var c=a.extend({url:b.src,success:function(c,d,e){var f={data:c,xhr:e};y(\"ParseAjax\",f),n.appendContent(a(f.data),H),b.finished=!0,J(),n._setFocus(),setTimeout(function(){n.wrap.addClass(k)},16),n.updateStatus(\"ready\"),y(\"AjaxContentAdded\")},error:function(){J(),b.finished=b.loadError=!0,n.updateStatus(\"error\",n.st.ajax.tError.replace(\"%url%\",b.src))}},n.st.ajax.settings);return n.req=a.ajax(c),\"\"}}});var L,M=function(b){if(b.data&&b.data.title!==undefined)return b.data.title;var c=n.st.image.titleSrc;if(c){if(a.isFunction(c))return c.call(n,b);if(b.el)return b.el.attr(c)||\"\"}return\"\"};a.magnificPopup.registerModule(\"image\",{options:{markup:'<div class=\"mfp-figure\"><div class=\"mfp-close\"></div><figure><div class=\"mfp-img\"></div><figcaption><div class=\"mfp-bottom-bar\"><div class=\"mfp-title\"></div><div class=\"mfp-counter\"></div></div></figcaption></figure></div>',cursor:\"mfp-zoom-out-cur\",titleSrc:\"title\",verticalFit:!0,tError:'<a href=\"%url%\">The image</a> could not be loaded.'},proto:{initImage:function(){var c=n.st.image,d=\".image\";n.types.push(\"image\"),w(g+d,function(){n.currItem.type===\"image\"&&c.cursor&&a(document.body).addClass(c.cursor)}),w(b+d,function(){c.cursor&&a(document.body).removeClass(c.cursor),r.off(\"resize\"+j)}),w(\"Resize\"+d,n.resizeImage),n.isLowIE&&w(\"AfterChange\",n.resizeImage)},resizeImage:function(){var a=n.currItem;if(!a||!a.img)return;if(n.st.image.verticalFit){var b=0;n.isLowIE&&(b=parseInt(a.img.css(\"padding-top\"),10)+parseInt(a.img.css(\"padding-bottom\"),10)),a.img.css(\"max-height\",n.wH-b)}},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,L&&clearInterval(L),a.isCheckingImgSize=!1,y(\"ImageHasSize\",a),a.imgHidden&&(n.content&&n.content.removeClass(\"mfp-loading\"),a.imgHidden=!1))},findImageSize:function(a){var b=0,c=a.img[0],d=function(e){L&&clearInterval(L),L=setInterval(function(){if(c.naturalWidth>0){n._onImageHasSize(a);return}b>200&&clearInterval(L),b++,b===3?d(10):b===40?d(50):b===100&&d(500)},e)};d(1)},getImage:function(b,c){var d=0,e=function(){b&&(b.img[0].complete?(b.img.off(\".mfploader\"),b===n.currItem&&(n._onImageHasSize(b),n.updateStatus(\"ready\")),b.hasSize=!0,b.loaded=!0,y(\"ImageLoadComplete\")):(d++,d<200?setTimeout(e,100):f()))},f=function(){b&&(b.img.off(\".mfploader\"),b===n.currItem&&(n._onImageHasSize(b),n.updateStatus(\"error\",g.tError.replace(\"%url%\",b.src))),b.hasSize=!0,b.loaded=!0,b.loadError=!0)},g=n.st.image,h=c.find(\".mfp-img\");if(h.length){var i=document.createElement(\"img\");i.className=\"mfp-img\",b.el&&b.el.find(\"img\").length&&(i.alt=b.el.find(\"img\").attr(\"alt\")),b.img=a(i).on(\"load.mfploader\",e).on(\"error.mfploader\",f),i.src=b.src,h.is(\"img\")&&(b.img=b.img.clone()),i=b.img[0],i.naturalWidth>0?b.hasSize=!0:i.width||(b.hasSize=!1)}return n._parseMarkup(c,{title:M(b),img_replaceWith:b.img},b),n.resizeImage(),b.hasSize?(L&&clearInterval(L),b.loadError?(c.addClass(\"mfp-loading\"),n.updateStatus(\"error\",g.tError.replace(\"%url%\",b.src))):(c.removeClass(\"mfp-loading\"),n.updateStatus(\"ready\")),c):(n.updateStatus(\"loading\"),b.loading=!0,b.hasSize||(b.imgHidden=!0,c.addClass(\"mfp-loading\"),n.findImageSize(b)),c)}}});var N,O=function(){return N===undefined&&(N=document.createElement(\"p\").style.MozTransform!==undefined),N};a.magnificPopup.registerModule(\"zoom\",{options:{enabled:!1,easing:\"ease-in-out\",duration:300,opener:function(a){return a.is(\"img\")?a:a.find(\"img\")}},proto:{initZoom:function(){var a=n.st.zoom,d=\".zoom\",e;if(!a.enabled||!n.supportsTransition)return;var f=a.duration,g=function(b){var c=b.clone().removeAttr(\"style\").removeAttr(\"class\").addClass(\"mfp-animated-image\"),d=\"all \"+a.duration/1e3+\"s \"+a.easing,e={position:\"fixed\",zIndex:9999,left:0,top:0,\"-webkit-backface-visibility\":\"hidden\"},f=\"transition\";return e[\"-webkit-\"+f]=e[\"-moz-\"+f]=e[\"-o-\"+f]=e[f]=d,c.css(e),c},h=function(){n.content.css(\"visibility\",\"visible\")},i,j;w(\"BuildControls\"+d,function(){if(n._allowZoom()){clearTimeout(i),n.content.css(\"visibility\",\"hidden\"),e=n._getItemToZoom();if(!e){h();return}j=g(e),j.css(n._getOffset()),n.wrap.append(j),i=setTimeout(function(){j.css(n._getOffset(!0)),i=setTimeout(function(){h(),setTimeout(function(){j.remove(),e=j=null,y(\"ZoomAnimationEnded\")},16)},f)},16)}}),w(c+d,function(){if(n._allowZoom()){clearTimeout(i),n.st.removalDelay=f;if(!e){e=n._getItemToZoom();if(!e)return;j=g(e)}j.css(n._getOffset(!0)),n.wrap.append(j),n.content.css(\"visibility\",\"hidden\"),setTimeout(function(){j.css(n._getOffset())},16)}}),w(b+d,function(){n._allowZoom()&&(h(),j&&j.remove(),e=null)})},_allowZoom:function(){return n.currItem.type===\"image\"},_getItemToZoom:function(){return n.currItem.hasSize?n.currItem.img:!1},_getOffset:function(b){var c;b?c=n.currItem.img:c=n.st.zoom.opener(n.currItem.el||n.currItem);var d=c.offset(),e=parseInt(c.css(\"padding-top\"),10),f=parseInt(c.css(\"padding-bottom\"),10);d.top-=a(window).scrollTop()-e;var g={width:c.width(),height:(p?c.innerHeight():c[0].offsetHeight)-f-e};return O()?g[\"-moz-transform\"]=g.transform=\"translate(\"+d.left+\"px,\"+d.top+\"px)\":(g.left=d.left,g.top=d.top),g}}});var P=\"iframe\",Q=\"//about:blank\",R=function(a){if(n.currTemplate[P]){var b=n.currTemplate[P].find(\"iframe\");b.length&&(a||(b[0].src=Q),n.isIE8&&b.css(\"display\",a?\"block\":\"none\"))}};a.magnificPopup.registerModule(P,{options:{markup:'<div class=\"mfp-iframe-scaler\"><div class=\"mfp-close\"></div><iframe class=\"mfp-iframe\" src=\"//about:blank\" frameborder=\"0\" allowfullscreen></iframe></div>',srcAction:\"iframe_src\",patterns:{youtube:{index:\"youtube.com\",id:\"v=\",src:\"//www.youtube.com/embed/%id%?autoplay=1\"},vimeo:{index:\"vimeo.com/\",id:\"/\",src:\"//player.vimeo.com/video/%id%?autoplay=1\"},gmaps:{index:\"//maps.google.\",src:\"%id%&output=embed\"}}},proto:{initIframe:function(){n.types.push(P),w(\"BeforeChange\",function(a,b,c){b!==c&&(b===P?R():c===P&&R(!0))}),w(b+\".\"+P,function(){R()})},getIframe:function(b,c){var d=b.src,e=n.st.iframe;a.each(e.patterns,function(){if(d.indexOf(this.index)>-1)return this.id&&(typeof this.id==\"string\"?d=d.substr(d.lastIndexOf(this.id)+this.id.length,d.length):d=this.id.call(this,d)),d=this.src.replace(\"%id%\",d),!1});var f={};return e.srcAction&&(f[e.srcAction]=d),n._parseMarkup(c,f,b),n.updateStatus(\"ready\"),c}}});var S=function(a){var b=n.items.length;return a>b-1?a-b:a<0?b+a:a},T=function(a,b,c){return a.replace(/%curr%/gi,b+1).replace(/%total%/gi,c)};a.magnificPopup.registerModule(\"gallery\",{options:{enabled:!1,arrowMarkup:'<button title=\"%title%\" type=\"button\" class=\"mfp-arrow mfp-arrow-%dir%\"></button>',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:\"Previous (Left arrow key)\",tNext:\"Next (Right arrow key)\",tCounter:\"%curr% of %total%\"},proto:{initGallery:function(){var c=n.st.gallery,d=\".mfp-gallery\";n.direction=!0;if(!c||!c.enabled)return!1;u+=\" mfp-gallery\",w(g+d,function(){c.navigateByImgClick&&n.wrap.on(\"click\"+d,\".mfp-img\",function(){if(n.items.length>1)return n.next(),!1}),s.on(\"keydown\"+d,function(a){a.keyCode===37?n.prev():a.keyCode===39&&n.next()})}),w(\"UpdateStatus\"+d,function(a,b){b.text&&(b.text=T(b.text,n.currItem.index,n.items.length))}),w(f+d,function(a,b,d,e){var f=n.items.length;d.counter=f>1?T(c.tCounter,e.index,f):\"\"}),w(\"BuildControls\"+d,function(){if(n.items.length>1&&c.arrows&&!n.arrowLeft){var b=c.arrowMarkup,d=n.arrowLeft=a(b.replace(/%title%/gi,c.tPrev).replace(/%dir%/gi,\"left\")).addClass(m),e=n.arrowRight=a(b.replace(/%title%/gi,c.tNext).replace(/%dir%/gi,\"right\")).addClass(m);d.click(function(){n.prev()}),e.click(function(){n.next()}),n.container.append(d.add(e))}}),w(h+d,function(){n._preloadTimeout&&clearTimeout(n._preloadTimeout),n._preloadTimeout=setTimeout(function(){n.preloadNearbyImages(),n._preloadTimeout=null},16)}),w(b+d,function(){s.off(d),n.wrap.off(\"click\"+d),n.arrowRight=n.arrowLeft=null})},next:function(){n.direction=!0,n.index=S(n.index+1),n.updateItemHTML()},prev:function(){n.direction=!1,n.index=S(n.index-1),n.updateItemHTML()},goTo:function(a){n.direction=a>=n.index,n.index=a,n.updateItemHTML()},preloadNearbyImages:function(){var a=n.st.gallery.preload,b=Math.min(a[0],n.items.length),c=Math.min(a[1],n.items.length),d;for(d=1;d<=(n.direction?c:b);d++)n._preloadItem(n.index+d);for(d=1;d<=(n.direction?b:c);d++)n._preloadItem(n.index-d)},_preloadItem:function(b){b=S(b);if(n.items[b].preloaded)return;var c=n.items[b];c.parsed||(c=n.parseEl(b)),y(\"LazyLoad\",c),c.type===\"image\"&&(c.img=a('<img class=\"mfp-img\" />').on(\"load.mfploader\",function(){c.hasSize=!0}).on(\"error.mfploader\",function(){c.hasSize=!0,c.loadError=!0,y(\"LazyLoadError\",c)}).attr(\"src\",c.src)),c.preloaded=!0}}});var U=\"retina\";a.magnificPopup.registerModule(U,{options:{replaceSrc:function(a){return a.src.replace(/\\.\\w+$/,function(a){return\"@2x\"+a})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var a=n.st.retina,b=a.ratio;b=isNaN(b)?b():b,b>1&&(w(\"ImageHasSize.\"+U,function(a,c){c.img.css({\"max-width\":c.img[0].naturalWidth/b,width:\"100%\"})}),w(\"ElementParse.\"+U,function(c,d){d.src=a.replaceSrc(d,b)}))}}}}),A()})","Mageplaza_Core/js/jquery.autocomplete.min.js":"/**\r\n *  Ajax Autocomplete for jQuery, version 1.3.0\r\n *  (c) 2017 Tomas Kirda\r\n *\r\n *  Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.\r\n *  For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete\r\n */\r\n!function(a){\"use strict\";\"function\"==typeof define&&define.amd?define([\"jquery\"],a):a(\"object\"==typeof exports&&\"function\"==typeof require?require(\"jquery\"):jQuery)}(function(a){\"use strict\";function b(c,d){var e=a.noop,f=this,g={ajaxSettings:{},autoSelectFirst:!1,appendTo:document.body,serviceUrl:null,lookup:null,onSelect:null,width:\"auto\",minChars:1,maxHeight:300,deferRequestBy:0,params:{},formatResult:b.formatResult,formatGroup:b.formatGroup,delimiter:null,zIndex:9999,type:\"GET\",noCache:!1,onSearchStart:e,onSearchComplete:e,onSearchError:e,preserveInput:!1,containerClass:\"autocomplete-suggestions\",tabDisabled:!1,dataType:\"text\",currentRequest:null,triggerSelectOnValidInput:!0,preventBadQueries:!0,lookupFilter:function(a,b,c){return-1!==a.value.toLowerCase().indexOf(c)},paramName:\"query\",transformResult:function(b){return\"string\"==typeof b?a.parseJSON(b):b},showNoSuggestionNotice:!1,noSuggestionNotice:\"No results\",orientation:\"bottom\",forceFixPosition:!1};f.element=c,f.el=a(c),f.suggestions=[],f.badQueries=[],f.selectedIndex=-1,f.currentValue=f.element.value,f.intervalId=0,f.cachedResponse={},f.onChangeInterval=null,f.onChange=null,f.isLocal=!1,f.suggestionsContainer=null,f.noSuggestionsContainer=null,f.options=a.extend({},g,d),f.classes={selected:\"autocomplete-selected\",suggestion:\"autocomplete-suggestion\"},f.hint=null,f.hintValue=\"\",f.selection=null,f.initialize(),f.setOptions(d)}var c=function(){return{escapeRegExChars:function(a){return a.replace(/[|\\\\{}()[\\]^$+*?.]/g,\"\\\\$&\")},createNode:function(a){var b=document.createElement(\"div\");return b.className=a,b.style.position=\"absolute\",b.style.display=\"none\",b}}}(),d={ESC:27,TAB:9,RETURN:13,LEFT:37,UP:38,RIGHT:39,DOWN:40};b.utils=c,a.Autocomplete=b,b.formatResult=function(a,b){if(!b)return a.value;var d=\"(\"+c.escapeRegExChars(b)+\")\";return a.value.replace(new RegExp(d,\"gi\"),\"<strong>$1</strong>\").replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\").replace(/&lt;(\\/?strong)&gt;/g,\"<$1>\")},b.formatGroup=function(a,b){return'<div class=\"autocomplete-group\"><strong>'+b+\"</strong></div>\"},b.prototype={killerFn:null,initialize:function(){var c,d=this,e=\".\"+d.classes.suggestion,f=d.classes.selected,g=d.options;d.element.setAttribute(\"autocomplete\",\"off\"),d.killerFn=function(b){a(b.target).closest(\".\"+d.options.containerClass).length||(d.killSuggestions(),d.disableKillerFn())},d.noSuggestionsContainer=a('<div class=\"autocomplete-no-suggestion\"></div>').html(this.options.noSuggestionNotice).get(0),d.suggestionsContainer=b.utils.createNode(g.containerClass),c=a(d.suggestionsContainer),c.appendTo(g.appendTo),\"auto\"!==g.width&&c.css(\"width\",g.width),c.on(\"mouseover.autocomplete\",e,function(){d.activate(a(this).data(\"index\"))}),c.on(\"mouseout.autocomplete\",function(){d.selectedIndex=-1,c.children(\".\"+f).removeClass(f)}),c.on(\"click.autocomplete\",e,function(){return d.select(a(this).data(\"index\")),!1}),d.fixPositionCapture=function(){d.visible&&d.fixPosition()},a(window).on(\"resize.autocomplete\",d.fixPositionCapture),d.el.on(\"keydown.autocomplete\",function(a){d.onKeyPress(a)}),d.el.on(\"keyup.autocomplete\",function(a){d.onKeyUp(a)}),d.el.on(\"blur.autocomplete\",function(){d.onBlur()}),d.el.on(\"focus.autocomplete\",function(){d.onFocus()}),d.el.on(\"change.autocomplete\",function(a){d.onKeyUp(a)}),d.el.on(\"input.autocomplete\",function(a){d.onKeyUp(a)})},onFocus:function(){var a=this;a.fixPosition(),a.el.val().length>=a.options.minChars&&a.onValueChange()},onBlur:function(){this.enableKillerFn()},abortAjax:function(){var a=this;a.currentRequest&&(a.currentRequest.abort(),a.currentRequest=null)},setOptions:function(b){var c=this,d=c.options;a.extend(d,b),c.isLocal=a.isArray(d.lookup),c.isLocal&&(d.lookup=c.verifySuggestionsFormat(d.lookup)),d.orientation=c.validateOrientation(d.orientation,\"bottom\"),a(c.suggestionsContainer).css({\"max-height\":d.maxHeight+\"px\",width:d.width+\"px\",\"z-index\":d.zIndex})},clearCache:function(){this.cachedResponse={},this.badQueries=[]},clear:function(){this.clearCache(),this.currentValue=\"\",this.suggestions=[]},disable:function(){var a=this;a.disabled=!0,clearInterval(a.onChangeInterval),a.abortAjax()},enable:function(){this.disabled=!1},fixPosition:function(){var b=this,c=a(b.suggestionsContainer),d=c.parent().get(0);if(d===document.body||b.options.forceFixPosition){var e=b.options.orientation,f=c.outerHeight(),g=b.el.outerHeight(),h=b.el.offset(),i={top:h.top,left:h.left};if(\"auto\"===e){var j=a(window).height(),k=a(window).scrollTop(),l=-k+h.top-f,m=k+j-(h.top+g+f);e=Math.max(l,m)===l?\"top\":\"bottom\"}if(\"top\"===e?i.top+=-f:i.top+=g,d!==document.body){var n,o=c.css(\"opacity\");b.visible||c.css(\"opacity\",0).show(),n=c.offsetParent().offset(),i.top-=n.top,i.left-=n.left,b.visible||c.css(\"opacity\",o).hide()}\"auto\"===b.options.width&&(i.width=b.el.outerWidth()+\"px\"),c.css(i)}},enableKillerFn:function(){var b=this;a(document).on(\"click.autocomplete\",b.killerFn)},disableKillerFn:function(){var b=this;a(document).off(\"click.autocomplete\",b.killerFn)},killSuggestions:function(){var a=this;a.stopKillSuggestions(),a.intervalId=window.setInterval(function(){a.visible&&(a.options.preserveInput||a.el.val(a.currentValue),a.hide()),a.stopKillSuggestions()},50)},stopKillSuggestions:function(){window.clearInterval(this.intervalId)},isCursorAtEnd:function(){var a,b=this,c=b.el.val().length,d=b.element.selectionStart;return\"number\"==typeof d?d===c:document.selection?(a=document.selection.createRange(),a.moveStart(\"character\",-c),c===a.text.length):!0},onKeyPress:function(a){var b=this;if(!b.disabled&&!b.visible&&a.which===d.DOWN&&b.currentValue)return void b.suggest();if(!b.disabled&&b.visible){switch(a.which){case d.ESC:b.el.val(b.currentValue),b.hide();break;case d.RIGHT:if(b.hint&&b.options.onHint&&b.isCursorAtEnd()){b.selectHint();break}return;case d.TAB:if(b.hint&&b.options.onHint)return void b.selectHint();if(-1===b.selectedIndex)return void b.hide();if(b.select(b.selectedIndex),b.options.tabDisabled===!1)return;break;case d.RETURN:if(-1===b.selectedIndex)return void b.hide();b.select(b.selectedIndex);break;case d.UP:b.moveUp();break;case d.DOWN:b.moveDown();break;default:return}a.stopImmediatePropagation(),a.preventDefault()}},onKeyUp:function(a){var b=this;if(!b.disabled){switch(a.which){case d.UP:case d.DOWN:return}clearInterval(b.onChangeInterval),b.currentValue!==b.el.val()&&(b.findBestHint(),b.options.deferRequestBy>0?b.onChangeInterval=setInterval(function(){b.onValueChange()},b.options.deferRequestBy):b.onValueChange())}},onValueChange:function(){var b=this,c=b.options,d=b.el.val(),e=b.getQuery(d);return b.selection&&b.currentValue!==e&&(b.selection=null,(c.onInvalidateSelection||a.noop).call(b.element)),clearInterval(b.onChangeInterval),b.currentValue=d,b.selectedIndex=-1,c.triggerSelectOnValidInput&&b.isExactMatch(e)?void b.select(0):void(e.length<c.minChars?b.hide():b.getSuggestions(e))},isExactMatch:function(a){var b=this.suggestions;return 1===b.length&&b[0].value.toLowerCase()===a.toLowerCase()},getQuery:function(b){var c,d=this.options.delimiter;return d?(c=b.split(d),a.trim(c[c.length-1])):b},getSuggestionsLocal:function(b){var c,d=this,e=d.options,f=b.toLowerCase(),g=e.lookupFilter,h=parseInt(e.lookupLimit,10);return c={suggestions:a.grep(e.lookup,function(a){return g(a,b,f)})},h&&c.suggestions.length>h&&(c.suggestions=c.suggestions.slice(0,h)),c},getSuggestions:function(b){var c,d,e,f,g=this,h=g.options,i=h.serviceUrl;if(h.params[h.paramName]=b,d=h.ignoreParams?null:h.params,h.onSearchStart.call(g.element,h.params)!==!1){if(a.isFunction(h.lookup))return void h.lookup(b,function(a){g.suggestions=a.suggestions,g.suggest(),h.onSearchComplete.call(g.element,b,a.suggestions)});g.isLocal?c=g.getSuggestionsLocal(b):(a.isFunction(i)&&(i=i.call(g.element,b)),e=i+\"?\"+a.param(d||{}),c=g.cachedResponse[e]),c&&a.isArray(c.suggestions)?(g.suggestions=c.suggestions,g.suggest(),h.onSearchComplete.call(g.element,b,c.suggestions)):g.isBadQuery(b)?h.onSearchComplete.call(g.element,b,[]):(g.abortAjax(),f={url:i,data:d,type:h.type,dataType:h.dataType},a.extend(f,h.ajaxSettings),g.currentRequest=a.ajax(f).done(function(a){var c;g.currentRequest=null,c=h.transformResult(a,b),g.processResponse(c,b,e),h.onSearchComplete.call(g.element,b,c.suggestions)}).fail(function(a,c,d){h.onSearchError.call(g.element,b,a,c,d)}))}},isBadQuery:function(a){if(!this.options.preventBadQueries)return!1;for(var b=this.badQueries,c=b.length;c--;)if(0===a.indexOf(b[c]))return!0;return!1},hide:function(){var b=this,c=a(b.suggestionsContainer);a.isFunction(b.options.onHide)&&b.visible&&b.options.onHide.call(b.element,c),b.visible=!1,b.selectedIndex=-1,clearInterval(b.onChangeInterval),a(b.suggestionsContainer).hide(),b.signalHint(null)},suggest:function(){if(!this.suggestions.length)return void(this.options.showNoSuggestionNotice?this.noSuggestions():this.hide());var b,c=this,d=c.options,e=d.groupBy,f=d.formatResult,g=c.getQuery(c.currentValue),h=c.classes.suggestion,i=c.classes.selected,j=a(c.suggestionsContainer),k=a(c.noSuggestionsContainer),l=d.beforeRender,m=\"\",n=function(a,c){var f=a.data[e];return b===f?\"\":(b=f,d.formatGroup(a,b))};return d.triggerSelectOnValidInput&&c.isExactMatch(g)?void c.select(0):(a.each(c.suggestions,function(a,b){e&&(m+=n(b,g,a)),m+='<div class=\"'+h+'\" data-index=\"'+a+'\">'+f(b,g,a)+\"</div>\"}),this.adjustContainerWidth(),k.detach(),j.html(m),a.isFunction(l)&&l.call(c.element,j,c.suggestions),c.fixPosition(),j.show(),d.autoSelectFirst&&(c.selectedIndex=0,j.scrollTop(0),j.children(\".\"+h).first().addClass(i)),c.visible=!0,void c.findBestHint())},noSuggestions:function(){var b=this,c=a(b.suggestionsContainer),d=a(b.noSuggestionsContainer);this.adjustContainerWidth(),d.detach(),c.empty(),c.append(d),b.fixPosition(),c.show(),b.visible=!0},adjustContainerWidth:function(){var b,c=this,d=c.options,e=a(c.suggestionsContainer);\"auto\"===d.width?(b=c.el.outerWidth(),e.css(\"width\",b>0?b:300)):\"flex\"===d.width&&e.css(\"width\",\"\")},findBestHint:function(){var b=this,c=b.el.val().toLowerCase(),d=null;c&&(a.each(b.suggestions,function(a,b){var e=0===b.value.toLowerCase().indexOf(c);return e&&(d=b),!e}),b.signalHint(d))},signalHint:function(b){var c=\"\",d=this;b&&(c=d.currentValue+b.value.substr(d.currentValue.length)),d.hintValue!==c&&(d.hintValue=c,d.hint=b,(this.options.onHint||a.noop)(c))},verifySuggestionsFormat:function(b){return b.length&&\"string\"==typeof b[0]?a.map(b,function(a){return{value:a,data:null}}):b},validateOrientation:function(b,c){return b=a.trim(b||\"\").toLowerCase(),-1===a.inArray(b,[\"auto\",\"bottom\",\"top\"])&&(b=c),b},processResponse:function(a,b,c){var d=this,e=d.options;a.suggestions=d.verifySuggestionsFormat(a.suggestions),e.noCache||(d.cachedResponse[c]=a,e.preventBadQueries&&!a.suggestions.length&&d.badQueries.push(b)),b===d.getQuery(d.currentValue)&&(d.suggestions=a.suggestions,d.suggest())},activate:function(b){var c,d=this,e=d.classes.selected,f=a(d.suggestionsContainer),g=f.find(\".\"+d.classes.suggestion);return f.find(\".\"+e).removeClass(e),d.selectedIndex=b,-1!==d.selectedIndex&&g.length>d.selectedIndex?(c=g.get(d.selectedIndex),a(c).addClass(e),c):null},selectHint:function(){var b=this,c=a.inArray(b.hint,b.suggestions);b.select(c)},select:function(a){var b=this;b.hide(),b.onSelect(a),b.disableKillerFn()},moveUp:function(){var b=this;if(-1!==b.selectedIndex)return 0===b.selectedIndex?(a(b.suggestionsContainer).children().first().removeClass(b.classes.selected),b.selectedIndex=-1,b.el.val(b.currentValue),void b.findBestHint()):void b.adjustScroll(b.selectedIndex-1)},moveDown:function(){var a=this;a.selectedIndex!==a.suggestions.length-1&&a.adjustScroll(a.selectedIndex+1)},adjustScroll:function(b){var c=this,d=c.activate(b);if(d){var e,f,g,h=a(d).outerHeight();e=d.offsetTop,f=a(c.suggestionsContainer).scrollTop(),g=f+c.options.maxHeight-h,f>e?a(c.suggestionsContainer).scrollTop(e):e>g&&a(c.suggestionsContainer).scrollTop(e-c.options.maxHeight+h),c.options.preserveInput||c.el.val(c.getValue(c.suggestions[b].value)),c.signalHint(null)}},onSelect:function(b){var c=this,d=c.options.onSelect,e=c.suggestions[b];c.currentValue=c.getValue(e.value),c.currentValue===c.el.val()||c.options.preserveInput||c.el.val(c.currentValue),c.signalHint(null),c.suggestions=[],c.selection=e,a.isFunction(d)&&d.call(c.element,e)},getValue:function(a){var b,c,d=this,e=d.options.delimiter;return e?(b=d.currentValue,c=b.split(e),1===c.length?a:b.substr(0,b.length-c[c.length-1].length)+a):a},dispose:function(){var b=this;b.el.off(\".autocomplete\").removeData(\"autocomplete\"),b.disableKillerFn(),a(window).off(\"resize.autocomplete\",b.fixPositionCapture),a(b.suggestionsContainer).remove()}},a.fn.autocomplete=a.fn.devbridgeAutocomplete=function(c,d){var e=\"autocomplete\";return arguments.length?this.each(function(){var f=a(this),g=f.data(e);\"string\"==typeof c?g&&\"function\"==typeof g[c]&&g[c](d):(g&&g.dispose&&g.dispose(),g=new b(this,c),f.data(e,g))}):this.first().data(e)}});","Mageplaza_Core/js/owl.carousel.min.js":"/**\r\n * Owl Carousel v2.3.4\r\n * Copyright 2013-2018 David Deutsch\r\n * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE\r\n */\r\n!function(a,b,c,d){function e(b,c){this.settings=null,this.options=a.extend({},e.Defaults,c),this.$element=a(b),this._handlers={},this._plugins={},this._supress={},this._current=null,this._speed=null,this._coordinates=[],this._breakpoint=null,this._width=null,this._items=[],this._clones=[],this._mergers=[],this._widths=[],this._invalidated={},this._pipe=[],this._drag={time:null,target:null,pointer:null,stage:{start:null,current:null},direction:null},this._states={current:{},tags:{initializing:[\"busy\"],animating:[\"busy\"],dragging:[\"interacting\"]}},a.each([\"onResize\",\"onThrottledResize\"],a.proxy(function(b,c){this._handlers[c]=a.proxy(this[c],this)},this)),a.each(e.Plugins,a.proxy(function(a,b){this._plugins[a.charAt(0).toLowerCase()+a.slice(1)]=new b(this)},this)),a.each(e.Workers,a.proxy(function(b,c){this._pipe.push({filter:c.filter,run:a.proxy(c.run,this)})},this)),this.setup(),this.initialize()}e.Defaults={items:3,loop:!1,center:!1,rewind:!1,checkVisibility:!0,mouseDrag:!0,touchDrag:!0,pullDrag:!0,freeDrag:!1,margin:0,stagePadding:0,merge:!1,mergeFit:!0,autoWidth:!1,startPosition:0,rtl:!1,smartSpeed:250,fluidSpeed:!1,dragEndSpeed:!1,responsive:{},responsiveRefreshRate:200,responsiveBaseElement:b,fallbackEasing:\"swing\",slideTransition:\"\",info:!1,nestedItemSelector:!1,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\"},e.Width={Default:\"default\",Inner:\"inner\",Outer:\"outer\"},e.Type={Event:\"event\",State:\"state\"},e.Plugins={},e.Workers=[{filter:[\"width\",\"settings\"],run:function(){this._width=this.$element.width()}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){a.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(a){var b=this.settings.margin||\"\",c=!this.settings.autoWidth,d=this.settings.rtl,e={width:\"auto\",\"margin-left\":d?b:\"\",\"margin-right\":d?\"\":b};!c&&this.$stage.children().css(e),a.css=e}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){var b=(this.width()/this.settings.items).toFixed(3)-this.settings.margin,c=null,d=this._items.length,e=!this.settings.autoWidth,f=[];for(a.items={merge:!1,width:b};d--;)c=this._mergers[d],c=this.settings.mergeFit&&Math.min(c,this.settings.items)||c,a.items.merge=c>1||a.items.merge,f[d]=e?b*c:this._items[d].width();this._widths=f}},{filter:[\"items\",\"settings\"],run:function(){var b=[],c=this._items,d=this.settings,e=Math.max(2*d.items,4),f=2*Math.ceil(c.length/2),g=d.loop&&c.length?d.rewind?e:Math.max(e,f):0,h=\"\",i=\"\";for(g/=2;g>0;)b.push(this.normalize(b.length/2,!0)),h+=c[b[b.length-1]][0].outerHTML,b.push(this.normalize(c.length-1-(b.length-1)/2,!0)),i=c[b[b.length-1]][0].outerHTML+i,g-=1;this._clones=b,a(h).addClass(\"cloned\").appendTo(this.$stage),a(i).addClass(\"cloned\").prependTo(this.$stage)}},{filter:[\"width\",\"items\",\"settings\"],run:function(){for(var a=this.settings.rtl?1:-1,b=this._clones.length+this._items.length,c=-1,d=0,e=0,f=[];++c<b;)d=f[c-1]||0,e=this._widths[this.relative(c)]+this.settings.margin,f.push(d+e*a);this._coordinates=f}},{filter:[\"width\",\"items\",\"settings\"],run:function(){var a=this.settings.stagePadding,b=this._coordinates,c={width:Math.ceil(Math.abs(b[b.length-1]))+2*a,\"padding-left\":a||\"\",\"padding-right\":a||\"\"};this.$stage.css(c)}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){var b=this._coordinates.length,c=!this.settings.autoWidth,d=this.$stage.children();if(c&&a.items.merge)for(;b--;)a.css.width=this._widths[this.relative(b)],d.eq(b).css(a.css);else c&&(a.css.width=a.items.width,d.css(a.css))}},{filter:[\"items\"],run:function(){this._coordinates.length<1&&this.$stage.removeAttr(\"style\")}},{filter:[\"width\",\"items\",\"settings\"],run:function(a){a.current=a.current?this.$stage.children().index(a.current):0,a.current=Math.max(this.minimum(),Math.min(this.maximum(),a.current)),this.reset(a.current)}},{filter:[\"position\"],run:function(){this.animate(this.coordinates(this._current))}},{filter:[\"width\",\"position\",\"items\",\"settings\"],run:function(){var a,b,c,d,e=this.settings.rtl?1:-1,f=2*this.settings.stagePadding,g=this.coordinates(this.current())+f,h=g+this.width()*e,i=[];for(c=0,d=this._coordinates.length;c<d;c++)a=this._coordinates[c-1]||0,b=Math.abs(this._coordinates[c])+f*e,(this.op(a,\"<=\",g)&&this.op(a,\">\",h)||this.op(b,\"<\",g)&&this.op(b,\">\",h))&&i.push(c);this.$stage.children(\".active\").removeClass(\"active\"),this.$stage.children(\":eq(\"+i.join(\"), :eq(\")+\")\").addClass(\"active\"),this.$stage.children(\".center\").removeClass(\"center\"),this.settings.center&&this.$stage.children().eq(this.current()).addClass(\"center\")}}],e.prototype.initializeStage=function(){this.$stage=this.$element.find(\".\"+this.settings.stageClass),this.$stage.length||(this.$element.addClass(this.options.loadingClass),this.$stage=a(\"<\"+this.settings.stageElement+\">\",{class:this.settings.stageClass}).wrap(a(\"<div/>\",{class:this.settings.stageOuterClass})),this.$element.append(this.$stage.parent()))},e.prototype.initializeItems=function(){var b=this.$element.find(\".owl-item\");if(b.length)return this._items=b.get().map(function(b){return a(b)}),this._mergers=this._items.map(function(){return 1}),void this.refresh();this.replace(this.$element.children().not(this.$stage.parent())),this.isVisible()?this.refresh():this.invalidate(\"width\"),this.$element.removeClass(this.options.loadingClass).addClass(this.options.loadedClass)},e.prototype.initialize=function(){if(this.enter(\"initializing\"),this.trigger(\"initialize\"),this.$element.toggleClass(this.settings.rtlClass,this.settings.rtl),this.settings.autoWidth&&!this.is(\"pre-loading\")){var a,b,c;a=this.$element.find(\"img\"),b=this.settings.nestedItemSelector?\".\"+this.settings.nestedItemSelector:d,c=this.$element.children(b).width(),a.length&&c<=0&&this.preloadAutoWidthImages(a)}this.initializeStage(),this.initializeItems(),this.registerEventHandlers(),this.leave(\"initializing\"),this.trigger(\"initialized\")},e.prototype.isVisible=function(){return!this.settings.checkVisibility||this.$element.is(\":visible\")},e.prototype.setup=function(){var b=this.viewport(),c=this.options.responsive,d=-1,e=null;c?(a.each(c,function(a){a<=b&&a>d&&(d=Number(a))}),e=a.extend({},this.options,c[d]),\"function\"==typeof e.stagePadding&&(e.stagePadding=e.stagePadding()),delete e.responsive,e.responsiveClass&&this.$element.attr(\"class\",this.$element.attr(\"class\").replace(new RegExp(\"(\"+this.options.responsiveClass+\"-)\\\\S+\\\\s\",\"g\"),\"$1\"+d))):e=a.extend({},this.options),this.trigger(\"change\",{property:{name:\"settings\",value:e}}),this._breakpoint=d,this.settings=e,this.invalidate(\"settings\"),this.trigger(\"changed\",{property:{name:\"settings\",value:this.settings}})},e.prototype.optionsLogic=function(){this.settings.autoWidth&&(this.settings.stagePadding=!1,this.settings.merge=!1)},e.prototype.prepare=function(b){var c=this.trigger(\"prepare\",{content:b});return c.data||(c.data=a(\"<\"+this.settings.itemElement+\"/>\").addClass(this.options.itemClass).append(b)),this.trigger(\"prepared\",{content:c.data}),c.data},e.prototype.update=function(){for(var b=0,c=this._pipe.length,d=a.proxy(function(a){return this[a]},this._invalidated),e={};b<c;)(this._invalidated.all||a.grep(this._pipe[b].filter,d).length>0)&&this._pipe[b].run(e),b++;this._invalidated={},!this.is(\"valid\")&&this.enter(\"valid\")},e.prototype.width=function(a){switch(a=a||e.Width.Default){case e.Width.Inner:case e.Width.Outer:return this._width;default:return this._width-2*this.settings.stagePadding+this.settings.margin}},e.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\")},e.prototype.onThrottledResize=function(){b.clearTimeout(this.resizeTimer),this.resizeTimer=b.setTimeout(this._handlers.onResize,this.settings.responsiveRefreshRate)},e.prototype.onResize=function(){return!!this._items.length&&(this._width!==this.$element.width()&&(!!this.isVisible()&&(this.enter(\"resizing\"),this.trigger(\"resize\").isDefaultPrevented()?(this.leave(\"resizing\"),!1):(this.invalidate(\"width\"),this.refresh(),this.leave(\"resizing\"),void this.trigger(\"resized\")))))},e.prototype.registerEventHandlers=function(){a.support.transition&&this.$stage.on(a.support.transition.end+\".owl.core\",a.proxy(this.onTransitionEnd,this)),!1!==this.settings.responsive&&this.on(b,\"resize\",this._handlers.onThrottledResize),this.settings.mouseDrag&&(this.$element.addClass(this.options.dragClass),this.$stage.on(\"mousedown.owl.core\",a.proxy(this.onDragStart,this)),this.$stage.on(\"dragstart.owl.core selectstart.owl.core\",function(){return!1})),this.settings.touchDrag&&(this.$stage.on(\"touchstart.owl.core\",a.proxy(this.onDragStart,this)),this.$stage.on(\"touchcancel.owl.core\",a.proxy(this.onDragEnd,this)))},e.prototype.onDragStart=function(b){var d=null;3!==b.which&&(a.support.transform?(d=this.$stage.css(\"transform\").replace(/.*\\(|\\)| /g,\"\").split(\",\"),d={x:d[16===d.length?12:4],y:d[16===d.length?13:5]}):(d=this.$stage.position(),d={x:this.settings.rtl?d.left+this.$stage.width()-this.width()+this.settings.margin:d.left,y:d.top}),this.is(\"animating\")&&(a.support.transform?this.animate(d.x):this.$stage.stop(),this.invalidate(\"position\")),this.$element.toggleClass(this.options.grabClass,\"mousedown\"===b.type),this.speed(0),this._drag.time=(new Date).getTime(),this._drag.target=a(b.target),this._drag.stage.start=d,this._drag.stage.current=d,this._drag.pointer=this.pointer(b),a(c).on(\"mouseup.owl.core touchend.owl.core\",a.proxy(this.onDragEnd,this)),a(c).one(\"mousemove.owl.core touchmove.owl.core\",a.proxy(function(b){var d=this.difference(this._drag.pointer,this.pointer(b));a(c).on(\"mousemove.owl.core touchmove.owl.core\",a.proxy(this.onDragMove,this)),Math.abs(d.x)<Math.abs(d.y)&&this.is(\"valid\")||(b.preventDefault(),this.enter(\"dragging\"),this.trigger(\"drag\"))},this)))},e.prototype.onDragMove=function(a){var b=null,c=null,d=null,e=this.difference(this._drag.pointer,this.pointer(a)),f=this.difference(this._drag.stage.start,e);this.is(\"dragging\")&&(a.preventDefault(),this.settings.loop?(b=this.coordinates(this.minimum()),c=this.coordinates(this.maximum()+1)-b,f.x=((f.x-b)%c+c)%c+b):(b=this.settings.rtl?this.coordinates(this.maximum()):this.coordinates(this.minimum()),c=this.settings.rtl?this.coordinates(this.minimum()):this.coordinates(this.maximum()),d=this.settings.pullDrag?-1*e.x/5:0,f.x=Math.max(Math.min(f.x,b+d),c+d)),this._drag.stage.current=f,this.animate(f.x))},e.prototype.onDragEnd=function(b){var d=this.difference(this._drag.pointer,this.pointer(b)),e=this._drag.stage.current,f=d.x>0^this.settings.rtl?\"left\":\"right\";a(c).off(\".owl.core\"),this.$element.removeClass(this.options.grabClass),(0!==d.x&&this.is(\"dragging\")||!this.is(\"valid\"))&&(this.speed(this.settings.dragEndSpeed||this.settings.smartSpeed),this.current(this.closest(e.x,0!==d.x?f:this._drag.direction)),this.invalidate(\"position\"),this.update(),this._drag.direction=f,(Math.abs(d.x)>3||(new Date).getTime()-this._drag.time>300)&&this._drag.target.one(\"click.owl.core\",function(){return!1})),this.is(\"dragging\")&&(this.leave(\"dragging\"),this.trigger(\"dragged\"))},e.prototype.closest=function(b,c){var e=-1,f=30,g=this.width(),h=this.coordinates();return this.settings.freeDrag||a.each(h,a.proxy(function(a,i){return\"left\"===c&&b>i-f&&b<i+f?e=a:\"right\"===c&&b>i-g-f&&b<i-g+f?e=a+1:this.op(b,\"<\",i)&&this.op(b,\">\",h[a+1]!==d?h[a+1]:i-g)&&(e=\"left\"===c?a+1:a),-1===e},this)),this.settings.loop||(this.op(b,\">\",h[this.minimum()])?e=b=this.minimum():this.op(b,\"<\",h[this.maximum()])&&(e=b=this.maximum())),e},e.prototype.animate=function(b){var c=this.speed()>0;this.is(\"animating\")&&this.onTransitionEnd(),c&&(this.enter(\"animating\"),this.trigger(\"translate\")),a.support.transform3d&&a.support.transition?this.$stage.css({transform:\"translate3d(\"+b+\"px,0px,0px)\",transition:this.speed()/1e3+\"s\"+(this.settings.slideTransition?\" \"+this.settings.slideTransition:\"\")}):c?this.$stage.animate({left:b+\"px\"},this.speed(),this.settings.fallbackEasing,a.proxy(this.onTransitionEnd,this)):this.$stage.css({left:b+\"px\"})},e.prototype.is=function(a){return this._states.current[a]&&this._states.current[a]>0},e.prototype.current=function(a){if(a===d)return this._current;if(0===this._items.length)return d;if(a=this.normalize(a),this._current!==a){var b=this.trigger(\"change\",{property:{name:\"position\",value:a}});b.data!==d&&(a=this.normalize(b.data)),this._current=a,this.invalidate(\"position\"),this.trigger(\"changed\",{property:{name:\"position\",value:this._current}})}return this._current},e.prototype.invalidate=function(b){return\"string\"===a.type(b)&&(this._invalidated[b]=!0,this.is(\"valid\")&&this.leave(\"valid\")),a.map(this._invalidated,function(a,b){return b})},e.prototype.reset=function(a){(a=this.normalize(a))!==d&&(this._speed=0,this._current=a,this.suppress([\"translate\",\"translated\"]),this.animate(this.coordinates(a)),this.release([\"translate\",\"translated\"]))},e.prototype.normalize=function(a,b){var c=this._items.length,e=b?0:this._clones.length;return!this.isNumeric(a)||c<1?a=d:(a<0||a>=c+e)&&(a=((a-e/2)%c+c)%c+e/2),a},e.prototype.relative=function(a){return a-=this._clones.length/2,this.normalize(a,!0)},e.prototype.maximum=function(a){var b,c,d,e=this.settings,f=this._coordinates.length;if(e.loop)f=this._clones.length/2+this._items.length-1;else if(e.autoWidth||e.merge){if(b=this._items.length)for(c=this._items[--b].width(),d=this.$element.width();b--&&!((c+=this._items[b].width()+this.settings.margin)>d););f=b+1}else f=e.center?this._items.length-1:this._items.length-e.items;return a&&(f-=this._clones.length/2),Math.max(f,0)},e.prototype.minimum=function(a){return a?0:this._clones.length/2},e.prototype.items=function(a){return a===d?this._items.slice():(a=this.normalize(a,!0),this._items[a])},e.prototype.mergers=function(a){return a===d?this._mergers.slice():(a=this.normalize(a,!0),this._mergers[a])},e.prototype.clones=function(b){var c=this._clones.length/2,e=c+this._items.length,f=function(a){return a%2==0?e+a/2:c-(a+1)/2};return b===d?a.map(this._clones,function(a,b){return f(b)}):a.map(this._clones,function(a,c){return a===b?f(c):null})},e.prototype.speed=function(a){return a!==d&&(this._speed=a),this._speed},e.prototype.coordinates=function(b){var c,e=1,f=b-1;return b===d?a.map(this._coordinates,a.proxy(function(a,b){return this.coordinates(b)},this)):(this.settings.center?(this.settings.rtl&&(e=-1,f=b+1),c=this._coordinates[b],c+=(this.width()-c+(this._coordinates[f]||0))/2*e):c=this._coordinates[f]||0,c=Math.ceil(c))},e.prototype.duration=function(a,b,c){return 0===c?0:Math.min(Math.max(Math.abs(b-a),1),6)*Math.abs(c||this.settings.smartSpeed)},e.prototype.to=function(a,b){var c=this.current(),d=null,e=a-this.relative(c),f=(e>0)-(e<0),g=this._items.length,h=this.minimum(),i=this.maximum();this.settings.loop?(!this.settings.rewind&&Math.abs(e)>g/2&&(e+=-1*f*g),a=c+e,(d=((a-h)%g+g)%g+h)!==a&&d-e<=i&&d-e>0&&(c=d-e,a=d,this.reset(c))):this.settings.rewind?(i+=1,a=(a%i+i)%i):a=Math.max(h,Math.min(i,a)),this.speed(this.duration(c,a,b)),this.current(a),this.isVisible()&&this.update()},e.prototype.next=function(a){a=a||!1,this.to(this.relative(this.current())+1,a)},e.prototype.prev=function(a){a=a||!1,this.to(this.relative(this.current())-1,a)},e.prototype.onTransitionEnd=function(a){if(a!==d&&(a.stopPropagation(),(a.target||a.srcElement||a.originalTarget)!==this.$stage.get(0)))return!1;this.leave(\"animating\"),this.trigger(\"translated\")},e.prototype.viewport=function(){var d;return this.options.responsiveBaseElement!==b?d=a(this.options.responsiveBaseElement).width():b.innerWidth?d=b.innerWidth:c.documentElement&&c.documentElement.clientWidth?d=c.documentElement.clientWidth:console.warn(\"Can not detect viewport width.\"),d},e.prototype.replace=function(b){this.$stage.empty(),this._items=[],b&&(b=b instanceof jQuery?b:a(b)),this.settings.nestedItemSelector&&(b=b.find(\".\"+this.settings.nestedItemSelector)),b.filter(function(){return 1===this.nodeType}).each(a.proxy(function(a,b){b=this.prepare(b),this.$stage.append(b),this._items.push(b),this._mergers.push(1*b.find(\"[data-merge]\").addBack(\"[data-merge]\").attr(\"data-merge\")||1)},this)),this.reset(this.isNumeric(this.settings.startPosition)?this.settings.startPosition:0),this.invalidate(\"items\")},e.prototype.add=function(b,c){var e=this.relative(this._current);c=c===d?this._items.length:this.normalize(c,!0),b=b instanceof jQuery?b:a(b),this.trigger(\"add\",{content:b,position:c}),b=this.prepare(b),0===this._items.length||c===this._items.length?(0===this._items.length&&this.$stage.append(b),0!==this._items.length&&this._items[c-1].after(b),this._items.push(b),this._mergers.push(1*b.find(\"[data-merge]\").addBack(\"[data-merge]\").attr(\"data-merge\")||1)):(this._items[c].before(b),this._items.splice(c,0,b),this._mergers.splice(c,0,1*b.find(\"[data-merge]\").addBack(\"[data-merge]\").attr(\"data-merge\")||1)),this._items[e]&&this.reset(this._items[e].index()),this.invalidate(\"items\"),this.trigger(\"added\",{content:b,position:c})},e.prototype.remove=function(a){(a=this.normalize(a,!0))!==d&&(this.trigger(\"remove\",{content:this._items[a],position:a}),this._items[a].remove(),this._items.splice(a,1),this._mergers.splice(a,1),this.invalidate(\"items\"),this.trigger(\"removed\",{content:null,position:a}))},e.prototype.preloadAutoWidthImages=function(b){b.each(a.proxy(function(b,c){this.enter(\"pre-loading\"),c=a(c),a(new Image).one(\"load\",a.proxy(function(a){c.attr(\"src\",a.target.src),c.css(\"opacity\",1),this.leave(\"pre-loading\"),!this.is(\"pre-loading\")&&!this.is(\"initializing\")&&this.refresh()},this)).attr(\"src\",c.attr(\"src\")||c.attr(\"data-src\")||c.attr(\"data-src-retina\"))},this))},e.prototype.destroy=function(){this.$element.off(\".owl.core\"),this.$stage.off(\".owl.core\"),a(c).off(\".owl.core\"),!1!==this.settings.responsive&&(b.clearTimeout(this.resizeTimer),this.off(b,\"resize\",this._handlers.onThrottledResize));for(var d in this._plugins)this._plugins[d].destroy();this.$stage.children(\".cloned\").remove(),this.$stage.unwrap(),this.$stage.children().contents().unwrap(),this.$stage.children().unwrap(),this.$stage.remove(),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\")},e.prototype.op=function(a,b,c){var d=this.settings.rtl;switch(b){case\"<\":return d?a>c:a<c;case\">\":return d?a<c:a>c;case\">=\":return d?a<=c:a>=c;case\"<=\":return d?a>=c:a<=c}},e.prototype.on=function(a,b,c,d){a.addEventListener?a.addEventListener(b,c,d):a.attachEvent&&a.attachEvent(\"on\"+b,c)},e.prototype.off=function(a,b,c,d){a.removeEventListener?a.removeEventListener(b,c,d):a.detachEvent&&a.detachEvent(\"on\"+b,c)},e.prototype.trigger=function(b,c,d,f,g){var h={item:{count:this._items.length,index:this.current()}},i=a.camelCase(a.grep([\"on\",b,d],function(a){return a}).join(\"-\").toLowerCase()),j=a.Event([b,\"owl\",d||\"carousel\"].join(\".\").toLowerCase(),a.extend({relatedTarget:this},h,c));return this._supress[b]||(a.each(this._plugins,function(a,b){b.onTrigger&&b.onTrigger(j)}),this.register({type:e.Type.Event,name:b}),this.$element.trigger(j),this.settings&&\"function\"==typeof this.settings[i]&&this.settings[i].call(this,j)),j},e.prototype.enter=function(b){a.each([b].concat(this._states.tags[b]||[]),a.proxy(function(a,b){this._states.current[b]===d&&(this._states.current[b]=0),this._states.current[b]++},this))},e.prototype.leave=function(b){a.each([b].concat(this._states.tags[b]||[]),a.proxy(function(a,b){this._states.current[b]--},this))},e.prototype.register=function(b){if(b.type===e.Type.Event){if(a.event.special[b.name]||(a.event.special[b.name]={}),!a.event.special[b.name].owl){var c=a.event.special[b.name]._default;a.event.special[b.name]._default=function(a){return!c||!c.apply||a.namespace&&-1!==a.namespace.indexOf(\"owl\")?a.namespace&&a.namespace.indexOf(\"owl\")>-1:c.apply(this,arguments)},a.event.special[b.name].owl=!0}}else b.type===e.Type.State&&(this._states.tags[b.name]?this._states.tags[b.name]=this._states.tags[b.name].concat(b.tags):this._states.tags[b.name]=b.tags,this._states.tags[b.name]=a.grep(this._states.tags[b.name],a.proxy(function(c,d){return a.inArray(c,this._states.tags[b.name])===d},this)))},e.prototype.suppress=function(b){a.each(b,a.proxy(function(a,b){this._supress[b]=!0},this))},e.prototype.release=function(b){a.each(b,a.proxy(function(a,b){delete this._supress[b]},this))},e.prototype.pointer=function(a){var c={x:null,y:null};return a=a.originalEvent||a||b.event,a=a.touches&&a.touches.length?a.touches[0]:a.changedTouches&&a.changedTouches.length?a.changedTouches[0]:a,a.pageX?(c.x=a.pageX,c.y=a.pageY):(c.x=a.clientX,c.y=a.clientY),c},e.prototype.isNumeric=function(a){return!isNaN(parseFloat(a))},e.prototype.difference=function(a,b){return{x:a.x-b.x,y:a.y-b.y}},a.fn.owlCarousel=function(b){var c=Array.prototype.slice.call(arguments,1);return this.each(function(){var d=a(this),f=d.data(\"owl.carousel\");f||(f=new e(this,\"object\"==typeof b&&b),d.data(\"owl.carousel\",f),a.each([\"next\",\"prev\",\"to\",\"destroy\",\"refresh\",\"replace\",\"add\",\"remove\"],function(b,c){f.register({type:e.Type.Event,name:c}),f.$element.on(c+\".owl.carousel.core\",a.proxy(function(a){a.namespace&&a.relatedTarget!==this&&(this.suppress([c]),f[c].apply(this,[].slice.call(arguments,1)),this.release([c]))},f))})),\"string\"==typeof b&&\"_\"!==b.charAt(0)&&f[b].apply(f,c)})},a.fn.owlCarousel.Constructor=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this._core=b,this._interval=null,this._visible=null,this._handlers={\"initialized.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.autoRefresh&&this.watch()},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this._core.$element.on(this._handlers)};e.Defaults={autoRefresh:!0,autoRefreshInterval:500},e.prototype.watch=function(){this._interval||(this._visible=this._core.isVisible(),this._interval=b.setInterval(a.proxy(this.refresh,this),this._core.settings.autoRefreshInterval))},e.prototype.refresh=function(){this._core.isVisible()!==this._visible&&(this._visible=!this._visible,this._core.$element.toggleClass(\"owl-hidden\",!this._visible),this._visible&&this._core.invalidate(\"width\")&&this._core.refresh())},e.prototype.destroy=function(){var a,c;b.clearInterval(this._interval);for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(c in Object.getOwnPropertyNames(this))\"function\"!=typeof this[c]&&(this[c]=null)},a.fn.owlCarousel.Constructor.Plugins.AutoRefresh=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this._core=b,this._loaded=[],this._handlers={\"initialized.owl.carousel change.owl.carousel resized.owl.carousel\":a.proxy(function(b){if(b.namespace&&this._core.settings&&this._core.settings.lazyLoad&&(b.property&&\"position\"==b.property.name||\"initialized\"==b.type)){var c=this._core.settings,e=c.center&&Math.ceil(c.items/2)||c.items,f=c.center&&-1*e||0,g=(b.property&&b.property.value!==d?b.property.value:this._core.current())+f,h=this._core.clones().length,i=a.proxy(function(a,b){this.load(b)},this);for(c.lazyLoadEager>0&&(e+=c.lazyLoadEager,c.loop&&(g-=c.lazyLoadEager,e++));f++<e;)this.load(h/2+this._core.relative(g)),h&&a.each(this._core.clones(this._core.relative(g)),i),g++}},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this._core.$element.on(this._handlers)};e.Defaults={lazyLoad:!1,lazyLoadEager:0},e.prototype.load=function(c){var d=this._core.$stage.children().eq(c),e=d&&d.find(\".owl-lazy\");!e||a.inArray(d.get(0),this._loaded)>-1||(e.each(a.proxy(function(c,d){var e,f=a(d),g=b.devicePixelRatio>1&&f.attr(\"data-src-retina\")||f.attr(\"data-src\")||f.attr(\"data-srcset\");this._core.trigger(\"load\",{element:f,url:g},\"lazy\"),f.is(\"img\")?f.one(\"load.owl.lazy\",a.proxy(function(){f.css(\"opacity\",1),this._core.trigger(\"loaded\",{element:f,url:g},\"lazy\")},this)).attr(\"src\",g):f.is(\"source\")?f.one(\"load.owl.lazy\",a.proxy(function(){this._core.trigger(\"loaded\",{element:f,url:g},\"lazy\")},this)).attr(\"srcset\",g):(e=new Image,e.onload=a.proxy(function(){f.css({\"background-image\":'url(\"'+g+'\")',opacity:\"1\"}),this._core.trigger(\"loaded\",{element:f,url:g},\"lazy\")},this),e.src=g)},this)),this._loaded.push(d.get(0)))},e.prototype.destroy=function(){var a,b;for(a in this.handlers)this._core.$element.off(a,this.handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Lazy=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(c){this._core=c,this._previousHeight=null,this._handlers={\"initialized.owl.carousel refreshed.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.autoHeight&&this.update()},this),\"changed.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.autoHeight&&\"position\"===a.property.name&&this.update()},this),\"loaded.owl.lazy\":a.proxy(function(a){a.namespace&&this._core.settings.autoHeight&&a.element.closest(\".\"+this._core.settings.itemClass).index()===this._core.current()&&this.update()},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this._core.$element.on(this._handlers),this._intervalId=null;var d=this;a(b).on(\"load\",function(){d._core.settings.autoHeight&&d.update()}),a(b).resize(function(){d._core.settings.autoHeight&&(null!=d._intervalId&&clearTimeout(d._intervalId),d._intervalId=setTimeout(function(){d.update()},250))})};e.Defaults={autoHeight:!1,autoHeightClass:\"owl-height\"},e.prototype.update=function(){var b=this._core._current,c=b+this._core.settings.items,d=this._core.settings.lazyLoad,e=this._core.$stage.children().toArray().slice(b,c),f=[],g=0;a.each(e,function(b,c){f.push(a(c).height())}),g=Math.max.apply(null,f),g<=1&&d&&this._previousHeight&&(g=this._previousHeight),this._previousHeight=g,this._core.$stage.parent().height(g).addClass(this._core.settings.autoHeightClass)},e.prototype.destroy=function(){var a,b;for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.AutoHeight=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this._core=b,this._videos={},this._playing=null,this._handlers={\"initialized.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.register({type:\"state\",name:\"playing\",tags:[\"interacting\"]})},this),\"resize.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.video&&this.isInFullScreen()&&a.preventDefault()},this),\"refreshed.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.is(\"resizing\")&&this._core.$stage.find(\".cloned .owl-video-frame\").remove()},this),\"changed.owl.carousel\":a.proxy(function(a){a.namespace&&\"position\"===a.property.name&&this._playing&&this.stop()},this),\"prepared.owl.carousel\":a.proxy(function(b){if(b.namespace){var c=a(b.content).find(\".owl-video\");c.length&&(c.css(\"display\",\"none\"),this.fetch(c,a(b.content)))}},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this._core.$element.on(this._handlers),this._core.$element.on(\"click.owl.video\",\".owl-video-play-icon\",a.proxy(function(a){this.play(a)},this))};e.Defaults={video:!1,videoHeight:!1,videoWidth:!1},e.prototype.fetch=function(a,b){var c=function(){return a.attr(\"data-vimeo-id\")?\"vimeo\":a.attr(\"data-vzaar-id\")?\"vzaar\":\"youtube\"}(),d=a.attr(\"data-vimeo-id\")||a.attr(\"data-youtube-id\")||a.attr(\"data-vzaar-id\"),e=a.attr(\"data-width\")||this._core.settings.videoWidth,f=a.attr(\"data-height\")||this._core.settings.videoHeight,g=a.attr(\"href\");if(!g)throw new Error(\"Missing video URL.\");if(d=g.match(/(http:|https:|)\\/\\/(player.|www.|app.)?(vimeo\\.com|youtu(be\\.com|\\.be|be\\.googleapis\\.com|be\\-nocookie\\.com)|vzaar\\.com)\\/(video\\/|videos\\/|embed\\/|channels\\/.+\\/|groups\\/.+\\/|watch\\?v=|v\\/)?([A-Za-z0-9._%-]*)(\\&\\S+)?/),d[3].indexOf(\"youtu\")>-1)c=\"youtube\";else if(d[3].indexOf(\"vimeo\")>-1)c=\"vimeo\";else{if(!(d[3].indexOf(\"vzaar\")>-1))throw new Error(\"Video URL not supported.\");c=\"vzaar\"}d=d[6],this._videos[g]={type:c,id:d,width:e,height:f},b.attr(\"data-video\",g),this.thumbnail(a,this._videos[g])},e.prototype.thumbnail=function(b,c){var d,e,f,g=c.width&&c.height?\"width:\"+c.width+\"px;height:\"+c.height+\"px;\":\"\",h=b.find(\"img\"),i=\"src\",j=\"\",k=this._core.settings,l=function(c){e='<div class=\"owl-video-play-icon\"></div>',d=k.lazyLoad?a(\"<div/>\",{class:\"owl-video-tn \"+j,srcType:c}):a(\"<div/>\",{class:\"owl-video-tn\",style:\"opacity:1;background-image:url(\"+c+\")\"}),b.after(d),b.after(e)};if(b.wrap(a(\"<div/>\",{class:\"owl-video-wrapper\",style:g})),this._core.settings.lazyLoad&&(i=\"data-src\",j=\"owl-lazy\"),h.length)return l(h.attr(i)),h.remove(),!1;\"youtube\"===c.type?(f=\"//img.youtube.com/vi/\"+c.id+\"/hqdefault.jpg\",l(f)):\"vimeo\"===c.type?a.ajax({type:\"GET\",url:\"//vimeo.com/api/v2/video/\"+c.id+\".json\",jsonp:\"callback\",dataType:\"jsonp\",success:function(a){f=a[0].thumbnail_large,l(f)}}):\"vzaar\"===c.type&&a.ajax({type:\"GET\",url:\"//vzaar.com/api/videos/\"+c.id+\".json\",jsonp:\"callback\",dataType:\"jsonp\",success:function(a){f=a.framegrab_url,l(f)}})},e.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\")},e.prototype.play=function(b){var c,d=a(b.target),e=d.closest(\".\"+this._core.settings.itemClass),f=this._videos[e.attr(\"data-video\")],g=f.width||\"100%\",h=f.height||this._core.$stage.height();this._playing||(this._core.enter(\"playing\"),this._core.trigger(\"play\",null,\"video\"),e=this._core.items(this._core.relative(e.index())),this._core.reset(e.index()),c=a('<iframe frameborder=\"0\" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>'),c.attr(\"height\",h),c.attr(\"width\",g),\"youtube\"===f.type?c.attr(\"src\",\"//www.youtube.com/embed/\"+f.id+\"?autoplay=1&rel=0&v=\"+f.id):\"vimeo\"===f.type?c.attr(\"src\",\"//player.vimeo.com/video/\"+f.id+\"?autoplay=1\"):\"vzaar\"===f.type&&c.attr(\"src\",\"//view.vzaar.com/\"+f.id+\"/player?autoplay=true\"),a(c).wrap('<div class=\"owl-video-frame\" />').insertAfter(e.find(\".owl-video\")),this._playing=e.addClass(\"owl-video-playing\"))},e.prototype.isInFullScreen=function(){var b=c.fullscreenElement||c.mozFullScreenElement||c.webkitFullscreenElement;return b&&a(b).parent().hasClass(\"owl-video-frame\")},e.prototype.destroy=function(){var a,b;this._core.$element.off(\"click.owl.video\");for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Video=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this.core=b,this.core.options=a.extend({},e.Defaults,this.core.options),this.swapping=!0,this.previous=d,this.next=d,this.handlers={\"change.owl.carousel\":a.proxy(function(a){a.namespace&&\"position\"==a.property.name&&(this.previous=this.core.current(),this.next=a.property.value)},this),\"drag.owl.carousel dragged.owl.carousel translated.owl.carousel\":a.proxy(function(a){a.namespace&&(this.swapping=\"translated\"==a.type)},this),\"translate.owl.carousel\":a.proxy(function(a){a.namespace&&this.swapping&&(this.core.options.animateOut||this.core.options.animateIn)&&this.swap()},this)},this.core.$element.on(this.handlers)};e.Defaults={animateOut:!1,\r\nanimateIn:!1},e.prototype.swap=function(){if(1===this.core.settings.items&&a.support.animation&&a.support.transition){this.core.speed(0);var b,c=a.proxy(this.clear,this),d=this.core.$stage.children().eq(this.previous),e=this.core.$stage.children().eq(this.next),f=this.core.settings.animateIn,g=this.core.settings.animateOut;this.core.current()!==this.previous&&(g&&(b=this.core.coordinates(this.previous)-this.core.coordinates(this.next),d.one(a.support.animation.end,c).css({left:b+\"px\"}).addClass(\"animated owl-animated-out\").addClass(g)),f&&e.one(a.support.animation.end,c).addClass(\"animated owl-animated-in\").addClass(f))}},e.prototype.clear=function(b){a(b.target).css({left:\"\"}).removeClass(\"animated owl-animated-out owl-animated-in\").removeClass(this.core.settings.animateIn).removeClass(this.core.settings.animateOut),this.core.onTransitionEnd()},e.prototype.destroy=function(){var a,b;for(a in this.handlers)this.core.$element.off(a,this.handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.Animate=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){var e=function(b){this._core=b,this._call=null,this._time=0,this._timeout=0,this._paused=!0,this._handlers={\"changed.owl.carousel\":a.proxy(function(a){a.namespace&&\"settings\"===a.property.name?this._core.settings.autoplay?this.play():this.stop():a.namespace&&\"position\"===a.property.name&&this._paused&&(this._time=0)},this),\"initialized.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.autoplay&&this.play()},this),\"play.owl.autoplay\":a.proxy(function(a,b,c){a.namespace&&this.play(b,c)},this),\"stop.owl.autoplay\":a.proxy(function(a){a.namespace&&this.stop()},this),\"mouseover.owl.autoplay\":a.proxy(function(){this._core.settings.autoplayHoverPause&&this._core.is(\"rotating\")&&this.pause()},this),\"mouseleave.owl.autoplay\":a.proxy(function(){this._core.settings.autoplayHoverPause&&this._core.is(\"rotating\")&&this.play()},this),\"touchstart.owl.core\":a.proxy(function(){this._core.settings.autoplayHoverPause&&this._core.is(\"rotating\")&&this.pause()},this),\"touchend.owl.core\":a.proxy(function(){this._core.settings.autoplayHoverPause&&this.play()},this)},this._core.$element.on(this._handlers),this._core.options=a.extend({},e.Defaults,this._core.options)};e.Defaults={autoplay:!1,autoplayTimeout:5e3,autoplayHoverPause:!1,autoplaySpeed:!1},e.prototype._next=function(d){this._call=b.setTimeout(a.proxy(this._next,this,d),this._timeout*(Math.round(this.read()/this._timeout)+1)-this.read()),this._core.is(\"interacting\")||c.hidden||this._core.next(d||this._core.settings.autoplaySpeed)},e.prototype.read=function(){return(new Date).getTime()-this._time},e.prototype.play=function(c,d){var e;this._core.is(\"rotating\")||this._core.enter(\"rotating\"),c=c||this._core.settings.autoplayTimeout,e=Math.min(this._time%(this._timeout||c),c),this._paused?(this._time=this.read(),this._paused=!1):b.clearTimeout(this._call),this._time+=this.read()%c-e,this._timeout=c,this._call=b.setTimeout(a.proxy(this._next,this,d),c-e)},e.prototype.stop=function(){this._core.is(\"rotating\")&&(this._time=0,this._paused=!0,b.clearTimeout(this._call),this._core.leave(\"rotating\"))},e.prototype.pause=function(){this._core.is(\"rotating\")&&!this._paused&&(this._time=this.read(),this._paused=!0,b.clearTimeout(this._call))},e.prototype.destroy=function(){var a,b;this.stop();for(a in this._handlers)this._core.$element.off(a,this._handlers[a]);for(b in Object.getOwnPropertyNames(this))\"function\"!=typeof this[b]&&(this[b]=null)},a.fn.owlCarousel.Constructor.Plugins.autoplay=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){\"use strict\";var e=function(b){this._core=b,this._initialized=!1,this._pages=[],this._controls={},this._templates=[],this.$element=this._core.$element,this._overrides={next:this._core.next,prev:this._core.prev,to:this._core.to},this._handlers={\"prepared.owl.carousel\":a.proxy(function(b){b.namespace&&this._core.settings.dotsData&&this._templates.push('<div class=\"'+this._core.settings.dotClass+'\">'+a(b.content).find(\"[data-dot]\").addBack(\"[data-dot]\").attr(\"data-dot\")+\"</div>\")},this),\"added.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.dotsData&&this._templates.splice(a.position,0,this._templates.pop())},this),\"remove.owl.carousel\":a.proxy(function(a){a.namespace&&this._core.settings.dotsData&&this._templates.splice(a.position,1)},this),\"changed.owl.carousel\":a.proxy(function(a){a.namespace&&\"position\"==a.property.name&&this.draw()},this),\"initialized.owl.carousel\":a.proxy(function(a){a.namespace&&!this._initialized&&(this._core.trigger(\"initialize\",null,\"navigation\"),this.initialize(),this.update(),this.draw(),this._initialized=!0,this._core.trigger(\"initialized\",null,\"navigation\"))},this),\"refreshed.owl.carousel\":a.proxy(function(a){a.namespace&&this._initialized&&(this._core.trigger(\"refresh\",null,\"navigation\"),this.update(),this.draw(),this._core.trigger(\"refreshed\",null,\"navigation\"))},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this.$element.on(this._handlers)};e.Defaults={nav:!1,navText:['<span aria-label=\"Previous\">&#x2039;</span>','<span aria-label=\"Next\">&#x203a;</span>'],navSpeed:!1,navElement:'button type=\"button\" role=\"presentation\"',navContainer:!1,navContainerClass:\"owl-nav\",navClass:[\"owl-prev\",\"owl-next\"],slideBy:1,dotClass:\"owl-dot\",dotsClass:\"owl-dots\",dots:!0,dotsEach:!1,dotsData:!1,dotsSpeed:!1,dotsContainer:!1},e.prototype.initialize=function(){var b,c=this._core.settings;this._controls.$relative=(c.navContainer?a(c.navContainer):a(\"<div>\").addClass(c.navContainerClass).appendTo(this.$element)).addClass(\"disabled\"),this._controls.$previous=a(\"<\"+c.navElement+\">\").addClass(c.navClass[0]).html(c.navText[0]).prependTo(this._controls.$relative).on(\"click\",a.proxy(function(a){this.prev(c.navSpeed)},this)),this._controls.$next=a(\"<\"+c.navElement+\">\").addClass(c.navClass[1]).html(c.navText[1]).appendTo(this._controls.$relative).on(\"click\",a.proxy(function(a){this.next(c.navSpeed)},this)),c.dotsData||(this._templates=[a('<button role=\"button\">').addClass(c.dotClass).append(a(\"<span>\")).prop(\"outerHTML\")]),this._controls.$absolute=(c.dotsContainer?a(c.dotsContainer):a(\"<div>\").addClass(c.dotsClass).appendTo(this.$element)).addClass(\"disabled\"),this._controls.$absolute.on(\"click\",\"button\",a.proxy(function(b){var d=a(b.target).parent().is(this._controls.$absolute)?a(b.target).index():a(b.target).parent().index();b.preventDefault(),this.to(d,c.dotsSpeed)},this));for(b in this._overrides)this._core[b]=a.proxy(this[b],this)},e.prototype.destroy=function(){var a,b,c,d,e;e=this._core.settings;for(a in this._handlers)this.$element.off(a,this._handlers[a]);for(b in this._controls)\"$relative\"===b&&e.navContainer?this._controls[b].html(\"\"):this._controls[b].remove();for(d in this.overides)this._core[d]=this._overrides[d];for(c in Object.getOwnPropertyNames(this))\"function\"!=typeof this[c]&&(this[c]=null)},e.prototype.update=function(){var a,b,c,d=this._core.clones().length/2,e=d+this._core.items().length,f=this._core.maximum(!0),g=this._core.settings,h=g.center||g.autoWidth||g.dotsData?1:g.dotsEach||g.items;if(\"page\"!==g.slideBy&&(g.slideBy=Math.min(g.slideBy,g.items)),g.dots||\"page\"==g.slideBy)for(this._pages=[],a=d,b=0,c=0;a<e;a++){if(b>=h||0===b){if(this._pages.push({start:Math.min(f,a-d),end:a-d+h-1}),Math.min(f,a-d)===f)break;b=0,++c}b+=this._core.mergers(this._core.relative(a))}},e.prototype.draw=function(){var b,c=this._core.settings,d=this._core.items().length<=c.items,e=this._core.relative(this._core.current()),f=c.loop||c.rewind;this._controls.$relative.toggleClass(\"disabled\",!c.nav||d),c.nav&&(this._controls.$previous.toggleClass(\"disabled\",!f&&e<=this._core.minimum(!0)),this._controls.$next.toggleClass(\"disabled\",!f&&e>=this._core.maximum(!0))),this._controls.$absolute.toggleClass(\"disabled\",!c.dots||d),c.dots&&(b=this._pages.length-this._controls.$absolute.children().length,c.dotsData&&0!==b?this._controls.$absolute.html(this._templates.join(\"\")):b>0?this._controls.$absolute.append(new Array(b+1).join(this._templates[0])):b<0&&this._controls.$absolute.children().slice(b).remove(),this._controls.$absolute.find(\".active\").removeClass(\"active\"),this._controls.$absolute.children().eq(a.inArray(this.current(),this._pages)).addClass(\"active\"))},e.prototype.onTrigger=function(b){var c=this._core.settings;b.page={index:a.inArray(this.current(),this._pages),count:this._pages.length,size:c&&(c.center||c.autoWidth||c.dotsData?1:c.dotsEach||c.items)}},e.prototype.current=function(){var b=this._core.relative(this._core.current());return a.grep(this._pages,a.proxy(function(a,c){return a.start<=b&&a.end>=b},this)).pop()},e.prototype.getPosition=function(b){var c,d,e=this._core.settings;return\"page\"==e.slideBy?(c=a.inArray(this.current(),this._pages),d=this._pages.length,b?++c:--c,c=this._pages[(c%d+d)%d].start):(c=this._core.relative(this._core.current()),d=this._core.items().length,b?c+=e.slideBy:c-=e.slideBy),c},e.prototype.next=function(b){a.proxy(this._overrides.to,this._core)(this.getPosition(!0),b)},e.prototype.prev=function(b){a.proxy(this._overrides.to,this._core)(this.getPosition(!1),b)},e.prototype.to=function(b,c,d){var e;!d&&this._pages.length?(e=this._pages.length,a.proxy(this._overrides.to,this._core)(this._pages[(b%e+e)%e].start,c)):a.proxy(this._overrides.to,this._core)(b,c)},a.fn.owlCarousel.Constructor.Plugins.Navigation=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){\"use strict\";var e=function(c){this._core=c,this._hashes={},this.$element=this._core.$element,this._handlers={\"initialized.owl.carousel\":a.proxy(function(c){c.namespace&&\"URLHash\"===this._core.settings.startPosition&&a(b).trigger(\"hashchange.owl.navigation\")},this),\"prepared.owl.carousel\":a.proxy(function(b){if(b.namespace){var c=a(b.content).find(\"[data-hash]\").addBack(\"[data-hash]\").attr(\"data-hash\");if(!c)return;this._hashes[c]=b.content}},this),\"changed.owl.carousel\":a.proxy(function(c){if(c.namespace&&\"position\"===c.property.name){var d=this._core.items(this._core.relative(this._core.current())),e=a.map(this._hashes,function(a,b){return a===d?b:null}).join();if(!e||b.location.hash.slice(1)===e)return;b.location.hash=e}},this)},this._core.options=a.extend({},e.Defaults,this._core.options),this.$element.on(this._handlers),a(b).on(\"hashchange.owl.navigation\",a.proxy(function(a){var c=b.location.hash.substring(1),e=this._core.$stage.children(),f=this._hashes[c]&&e.index(this._hashes[c]);f!==d&&f!==this._core.current()&&this._core.to(this._core.relative(f),!1,!0)},this))};e.Defaults={URLhashListener:!1},e.prototype.destroy=function(){var c,d;a(b).off(\"hashchange.owl.navigation\");for(c in this._handlers)this._core.$element.off(c,this._handlers[c]);for(d in Object.getOwnPropertyNames(this))\"function\"!=typeof this[d]&&(this[d]=null)},a.fn.owlCarousel.Constructor.Plugins.Hash=e}(window.Zepto||window.jQuery,window,document),function(a,b,c,d){function e(b,c){var e=!1,f=b.charAt(0).toUpperCase()+b.slice(1);return a.each((b+\" \"+h.join(f+\" \")+f).split(\" \"),function(a,b){if(g[b]!==d)return e=!c||b,!1}),e}function f(a){return e(a,!0)}var g=a(\"<support>\").get(0).style,h=\"Webkit Moz O ms\".split(\" \"),i={transition:{end:{WebkitTransition:\"webkitTransitionEnd\",MozTransition:\"transitionend\",OTransition:\"oTransitionEnd\",transition:\"transitionend\"}},animation:{end:{WebkitAnimation:\"webkitAnimationEnd\",MozAnimation:\"animationend\",OAnimation:\"oAnimationEnd\",animation:\"animationend\"}}},j={csstransforms:function(){return!!e(\"transform\")},csstransforms3d:function(){return!!e(\"perspective\")},csstransitions:function(){return!!e(\"transition\")},cssanimations:function(){return!!e(\"animation\")}};j.csstransitions()&&(a.support.transition=new String(f(\"transition\")),a.support.transition.end=i.transition.end[a.support.transition]),j.cssanimations()&&(a.support.animation=new String(f(\"animation\")),a.support.animation.end=i.animation.end[a.support.animation]),j.csstransforms()&&(a.support.transform=new String(f(\"transform\")),a.support.transform3d=j.csstransforms3d())}(window.Zepto||window.jQuery,window,document);","Mageplaza_Core/lib/fileUploader/jquery.fileupload-validate.js":"/*\n * jQuery File Upload Validation Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery', 'Mageplaza_Core/lib/fileUploader/jquery.fileupload-process'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(require('jquery'), require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-process'));\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})(function ($) {\n  'use strict';\n\n  // Append to the default processQueue:\n  $.blueimp.fileupload.prototype.options.processQueue.push({\n    action: 'validate',\n    // Always trigger this action,\n    // even if the previous action was rejected:\n    always: true,\n    // Options taken from the global options map:\n    acceptFileTypes: '@',\n    maxFileSize: '@',\n    minFileSize: '@',\n    maxNumberOfFiles: '@',\n    disabled: '@disableValidation'\n  });\n\n  // The File Upload Validation plugin extends the fileupload widget\n  // with file validation functionality:\n  $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n    options: {\n      /*\n            // The regular expression for allowed file types, matches\n            // against either file type or file name:\n            acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i,\n            // The maximum allowed file size in bytes:\n            maxFileSize: 10000000, // 10 MB\n            // The minimum allowed file size in bytes:\n            minFileSize: undefined, // No minimal file size\n            // The limit of files to be uploaded:\n            maxNumberOfFiles: 10,\n            */\n\n      // Function returning the current number of files,\n      // has to be overridden for maxNumberOfFiles validation:\n      getNumberOfFiles: $.noop,\n\n      // Error and info messages:\n      messages: {\n        maxNumberOfFiles: 'Maximum number of files exceeded',\n        acceptFileTypes: 'File type not allowed',\n        maxFileSize: 'File is too large',\n        minFileSize: 'File is too small'\n      }\n    },\n\n    processActions: {\n      validate: function (data, options) {\n        if (options.disabled) {\n          return data;\n        }\n        // eslint-disable-next-line new-cap\n        var dfd = $.Deferred(),\n          settings = this.options,\n          file = data.files[data.index],\n          fileSize;\n        if (options.minFileSize || options.maxFileSize) {\n          fileSize = file.size;\n        }\n        if (\n          $.type(options.maxNumberOfFiles) === 'number' &&\n          (settings.getNumberOfFiles() || 0) + data.files.length >\n            options.maxNumberOfFiles\n        ) {\n          file.error = settings.i18n('maxNumberOfFiles');\n        } else if (\n          options.acceptFileTypes &&\n          !(\n            options.acceptFileTypes.test(file.type) ||\n            options.acceptFileTypes.test(file.name)\n          )\n        ) {\n          file.error = settings.i18n('acceptFileTypes');\n        } else if (fileSize > options.maxFileSize) {\n          file.error = settings.i18n('maxFileSize');\n        } else if (\n          $.type(fileSize) === 'number' &&\n          fileSize < options.minFileSize\n        ) {\n          file.error = settings.i18n('minFileSize');\n        } else {\n          delete file.error;\n        }\n        if (file.error || data.files.error) {\n          data.files.error = true;\n          dfd.rejectWith(this, [data]);\n        } else {\n          dfd.resolveWith(this, [data]);\n        }\n        return dfd.promise();\n      }\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/jquery.fileupload.js":"/*\n * jQuery File Upload Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n/* eslint-disable new-cap */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery', 'Mageplaza_Core/lib/fileUploader/vendor/jquery.ui.widget'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(require('jquery'), require('Mageplaza_Core/lib/fileUploader/vendor/jquery.ui.widget'));\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})(function ($) {\n  'use strict';\n\n  // Detect file input support, based on\n  // https://viljamis.com/2012/file-upload-support-on-mobile/\n  $.support.fileInput = !(\n    new RegExp(\n      // Handle devices which give false positives for the feature detection:\n      '(Android (1\\\\.[0156]|2\\\\.[01]))' +\n        '|(Windows Phone (OS 7|8\\\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +\n        '|(w(eb)?OSBrowser)|(webOS)' +\n        '|(Kindle/(1\\\\.0|2\\\\.[05]|3\\\\.0))'\n    ).test(window.navigator.userAgent) ||\n    // Feature detection for all other devices:\n    $('<input type=\"file\"/>').prop('disabled')\n  );\n\n  // The FileReader API is not actually used, but works as feature detection,\n  // as some Safari versions (5?) support XHR file uploads via the FormData API,\n  // but not non-multipart XHR file uploads.\n  // window.XMLHttpRequestUpload is not available on IE10, so we check for\n  // window.ProgressEvent instead to detect XHR2 file upload capability:\n  $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);\n  $.support.xhrFormDataFileUpload = !!window.FormData;\n\n  // Detect support for Blob slicing (required for chunked uploads):\n  $.support.blobSlice =\n    window.Blob &&\n    (Blob.prototype.slice ||\n      Blob.prototype.webkitSlice ||\n      Blob.prototype.mozSlice);\n\n  /**\n   * Helper function to create drag handlers for dragover/dragenter/dragleave\n   *\n   * @param {string} type Event type\n   * @returns {Function} Drag handler\n   */\n  function getDragHandler(type) {\n    var isDragOver = type === 'dragover';\n    return function (e) {\n      e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n      var dataTransfer = e.dataTransfer;\n      if (\n        dataTransfer &&\n        $.inArray('Files', dataTransfer.types) !== -1 &&\n        this._trigger(type, $.Event(type, { delegatedEvent: e })) !== false\n      ) {\n        e.preventDefault();\n        if (isDragOver) {\n          dataTransfer.dropEffect = 'copy';\n        }\n      }\n    };\n  }\n\n  // The fileupload widget listens for change events on file input fields defined\n  // via fileInput setting and paste or drop events of the given dropZone.\n  // In addition to the default jQuery Widget methods, the fileupload widget\n  // exposes the \"add\" and \"send\" methods, to add or directly send files using\n  // the fileupload API.\n  // By default, files added via file input selection, paste, drag & drop or\n  // \"add\" method are uploaded immediately, but it is possible to override\n  // the \"add\" callback option to queue file uploads.\n  $.widget('blueimp.fileupload', {\n    options: {\n      // The drop target element(s), by the default the complete document.\n      // Set to null to disable drag & drop support:\n      dropZone: $(document),\n      // The paste target element(s), by the default undefined.\n      // Set to a DOM node or jQuery object to enable file pasting:\n      pasteZone: undefined,\n      // The file input field(s), that are listened to for change events.\n      // If undefined, it is set to the file input fields inside\n      // of the widget element on plugin initialization.\n      // Set to null to disable the change listener.\n      fileInput: undefined,\n      // By default, the file input field is replaced with a clone after\n      // each input field change event. This is required for iframe transport\n      // queues and allows change events to be fired for the same file\n      // selection, but can be disabled by setting the following option to false:\n      replaceFileInput: true,\n      // The parameter name for the file form data (the request argument name).\n      // If undefined or empty, the name property of the file input field is\n      // used, or \"files[]\" if the file input name property is also empty,\n      // can be a string or an array of strings:\n      paramName: undefined,\n      // By default, each file of a selection is uploaded using an individual\n      // request for XHR type uploads. Set to false to upload file\n      // selections in one request each:\n      singleFileUploads: true,\n      // To limit the number of files uploaded with one XHR request,\n      // set the following option to an integer greater than 0:\n      limitMultiFileUploads: undefined,\n      // The following option limits the number of files uploaded with one\n      // XHR request to keep the request size under or equal to the defined\n      // limit in bytes:\n      limitMultiFileUploadSize: undefined,\n      // Multipart file uploads add a number of bytes to each uploaded file,\n      // therefore the following option adds an overhead for each file used\n      // in the limitMultiFileUploadSize configuration:\n      limitMultiFileUploadSizeOverhead: 512,\n      // Set the following option to true to issue all file upload requests\n      // in a sequential order:\n      sequentialUploads: false,\n      // To limit the number of concurrent uploads,\n      // set the following option to an integer greater than 0:\n      limitConcurrentUploads: undefined,\n      // Set the following option to true to force iframe transport uploads:\n      forceIframeTransport: false,\n      // Set the following option to the location of a redirect url on the\n      // origin server, for cross-domain iframe transport uploads:\n      redirect: undefined,\n      // The parameter name for the redirect url, sent as part of the form\n      // data and set to 'redirect' if this option is empty:\n      redirectParamName: undefined,\n      // Set the following option to the location of a postMessage window,\n      // to enable postMessage transport uploads:\n      postMessage: undefined,\n      // By default, XHR file uploads are sent as multipart/form-data.\n      // The iframe transport is always using multipart/form-data.\n      // Set to false to enable non-multipart XHR uploads:\n      multipart: true,\n      // To upload large files in smaller chunks, set the following option\n      // to a preferred maximum chunk size. If set to 0, null or undefined,\n      // or the browser does not support the required Blob API, files will\n      // be uploaded as a whole.\n      maxChunkSize: undefined,\n      // When a non-multipart upload or a chunked multipart upload has been\n      // aborted, this option can be used to resume the upload by setting\n      // it to the size of the already uploaded bytes. This option is most\n      // useful when modifying the options object inside of the \"add\" or\n      // \"send\" callbacks, as the options are cloned for each file upload.\n      uploadedBytes: undefined,\n      // By default, failed (abort or error) file uploads are removed from the\n      // global progress calculation. Set the following option to false to\n      // prevent recalculating the global progress data:\n      recalculateProgress: true,\n      // Interval in milliseconds to calculate and trigger progress events:\n      progressInterval: 100,\n      // Interval in milliseconds to calculate progress bitrate:\n      bitrateInterval: 500,\n      // By default, uploads are started automatically when adding files:\n      autoUpload: true,\n      // By default, duplicate file names are expected to be handled on\n      // the server-side. If this is not possible (e.g. when uploading\n      // files directly to Amazon S3), the following option can be set to\n      // an empty object or an object mapping existing filenames, e.g.:\n      // { \"image.jpg\": true, \"image (1).jpg\": true }\n      // If it is set, all files will be uploaded with unique filenames,\n      // adding increasing number suffixes if necessary, e.g.:\n      // \"image (2).jpg\"\n      uniqueFilenames: undefined,\n\n      // Error and info messages:\n      messages: {\n        uploadedBytes: 'Uploaded bytes exceed file size'\n      },\n\n      // Translation function, gets the message key to be translated\n      // and an object with context specific data as arguments:\n      i18n: function (message, context) {\n        // eslint-disable-next-line no-param-reassign\n        message = this.messages[message] || message.toString();\n        if (context) {\n          $.each(context, function (key, value) {\n            // eslint-disable-next-line no-param-reassign\n            message = message.replace('{' + key + '}', value);\n          });\n        }\n        return message;\n      },\n\n      // Additional form data to be sent along with the file uploads can be set\n      // using this option, which accepts an array of objects with name and\n      // value properties, a function returning such an array, a FormData\n      // object (for XHR file uploads), or a simple object.\n      // The form of the first fileInput is given as parameter to the function:\n      formData: function (form) {\n        return form.serializeArray();\n      },\n\n      // The add callback is invoked as soon as files are added to the fileupload\n      // widget (via file input selection, drag & drop, paste or add API call).\n      // If the singleFileUploads option is enabled, this callback will be\n      // called once for each file in the selection for XHR file uploads, else\n      // once for each file selection.\n      //\n      // The upload starts when the submit method is invoked on the data parameter.\n      // The data object contains a files property holding the added files\n      // and allows you to override plugin options as well as define ajax settings.\n      //\n      // Listeners for this callback can also be bound the following way:\n      // .on('fileuploadadd', func);\n      //\n      // data.submit() returns a Promise object and allows to attach additional\n      // handlers using jQuery's Deferred callbacks:\n      // data.submit().done(func).fail(func).always(func);\n      add: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        if (\n          data.autoUpload ||\n          (data.autoUpload !== false &&\n            $(this).fileupload('option', 'autoUpload'))\n        ) {\n          data.process().done(function () {\n            data.submit();\n          });\n        }\n      },\n\n      // Other callbacks:\n\n      // Callback for the submit event of each file upload:\n      // submit: function (e, data) {}, // .on('fileuploadsubmit', func);\n\n      // Callback for the start of each file upload request:\n      // send: function (e, data) {}, // .on('fileuploadsend', func);\n\n      // Callback for successful uploads:\n      // done: function (e, data) {}, // .on('fileuploaddone', func);\n\n      // Callback for failed (abort or error) uploads:\n      // fail: function (e, data) {}, // .on('fileuploadfail', func);\n\n      // Callback for completed (success, abort or error) requests:\n      // always: function (e, data) {}, // .on('fileuploadalways', func);\n\n      // Callback for upload progress events:\n      // progress: function (e, data) {}, // .on('fileuploadprogress', func);\n\n      // Callback for global upload progress events:\n      // progressall: function (e, data) {}, // .on('fileuploadprogressall', func);\n\n      // Callback for uploads start, equivalent to the global ajaxStart event:\n      // start: function (e) {}, // .on('fileuploadstart', func);\n\n      // Callback for uploads stop, equivalent to the global ajaxStop event:\n      // stop: function (e) {}, // .on('fileuploadstop', func);\n\n      // Callback for change events of the fileInput(s):\n      // change: function (e, data) {}, // .on('fileuploadchange', func);\n\n      // Callback for paste events to the pasteZone(s):\n      // paste: function (e, data) {}, // .on('fileuploadpaste', func);\n\n      // Callback for drop events of the dropZone(s):\n      // drop: function (e, data) {}, // .on('fileuploaddrop', func);\n\n      // Callback for dragover events of the dropZone(s):\n      // dragover: function (e) {}, // .on('fileuploaddragover', func);\n\n      // Callback before the start of each chunk upload request (before form data initialization):\n      // chunkbeforesend: function (e, data) {}, // .on('fileuploadchunkbeforesend', func);\n\n      // Callback for the start of each chunk upload request:\n      // chunksend: function (e, data) {}, // .on('fileuploadchunksend', func);\n\n      // Callback for successful chunk uploads:\n      // chunkdone: function (e, data) {}, // .on('fileuploadchunkdone', func);\n\n      // Callback for failed (abort or error) chunk uploads:\n      // chunkfail: function (e, data) {}, // .on('fileuploadchunkfail', func);\n\n      // Callback for completed (success, abort or error) chunk upload requests:\n      // chunkalways: function (e, data) {}, // .on('fileuploadchunkalways', func);\n\n      // The plugin options are used as settings object for the ajax calls.\n      // The following are jQuery ajax settings required for the file uploads:\n      processData: false,\n      contentType: false,\n      cache: false,\n      timeout: 0\n    },\n\n    // jQuery versions before 1.8 require promise.pipe if the return value is\n    // used, as promise.then in older versions has a different behavior, see:\n    // https://blog.jquery.com/2012/08/09/jquery-1-8-released/\n    // https://bugs.jquery.com/ticket/11010\n    // https://github.com/blueimp/jQuery-File-Upload/pull/3435\n    _promisePipe: (function () {\n      var parts = $.fn.jquery.split('.');\n      return Number(parts[0]) > 1 || Number(parts[1]) > 7 ? 'then' : 'pipe';\n    })(),\n\n    // A list of options that require reinitializing event listeners and/or\n    // special initialization code:\n    _specialOptions: [\n      'fileInput',\n      'dropZone',\n      'pasteZone',\n      'multipart',\n      'forceIframeTransport'\n    ],\n\n    _blobSlice:\n      $.support.blobSlice &&\n      function () {\n        var slice = this.slice || this.webkitSlice || this.mozSlice;\n        return slice.apply(this, arguments);\n      },\n\n    _BitrateTimer: function () {\n      this.timestamp = Date.now ? Date.now() : new Date().getTime();\n      this.loaded = 0;\n      this.bitrate = 0;\n      this.getBitrate = function (now, loaded, interval) {\n        var timeDiff = now - this.timestamp;\n        if (!this.bitrate || !interval || timeDiff > interval) {\n          this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;\n          this.loaded = loaded;\n          this.timestamp = now;\n        }\n        return this.bitrate;\n      };\n    },\n\n    _isXHRUpload: function (options) {\n      return (\n        !options.forceIframeTransport &&\n        ((!options.multipart && $.support.xhrFileUpload) ||\n          $.support.xhrFormDataFileUpload)\n      );\n    },\n\n    _getFormData: function (options) {\n      var formData;\n      if ($.type(options.formData) === 'function') {\n        return options.formData(options.form);\n      }\n      if ($.isArray(options.formData)) {\n        return options.formData;\n      }\n      if ($.type(options.formData) === 'object') {\n        formData = [];\n        $.each(options.formData, function (name, value) {\n          formData.push({ name: name, value: value });\n        });\n        return formData;\n      }\n      return [];\n    },\n\n    _getTotal: function (files) {\n      var total = 0;\n      $.each(files, function (index, file) {\n        total += file.size || 1;\n      });\n      return total;\n    },\n\n    _initProgressObject: function (obj) {\n      var progress = {\n        loaded: 0,\n        total: 0,\n        bitrate: 0\n      };\n      if (obj._progress) {\n        $.extend(obj._progress, progress);\n      } else {\n        obj._progress = progress;\n      }\n    },\n\n    _initResponseObject: function (obj) {\n      var prop;\n      if (obj._response) {\n        for (prop in obj._response) {\n          if (Object.prototype.hasOwnProperty.call(obj._response, prop)) {\n            delete obj._response[prop];\n          }\n        }\n      } else {\n        obj._response = {};\n      }\n    },\n\n    _onProgress: function (e, data) {\n      if (e.lengthComputable) {\n        var now = Date.now ? Date.now() : new Date().getTime(),\n          loaded;\n        if (\n          data._time &&\n          data.progressInterval &&\n          now - data._time < data.progressInterval &&\n          e.loaded !== e.total\n        ) {\n          return;\n        }\n        data._time = now;\n        loaded =\n          Math.floor(\n            (e.loaded / e.total) * (data.chunkSize || data._progress.total)\n          ) + (data.uploadedBytes || 0);\n        // Add the difference from the previously loaded state\n        // to the global loaded counter:\n        this._progress.loaded += loaded - data._progress.loaded;\n        this._progress.bitrate = this._bitrateTimer.getBitrate(\n          now,\n          this._progress.loaded,\n          data.bitrateInterval\n        );\n        data._progress.loaded = data.loaded = loaded;\n        data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(\n          now,\n          loaded,\n          data.bitrateInterval\n        );\n        // Trigger a custom progress event with a total data property set\n        // to the file size(s) of the current upload and a loaded data\n        // property calculated accordingly:\n        this._trigger(\n          'progress',\n          $.Event('progress', { delegatedEvent: e }),\n          data\n        );\n        // Trigger a global progress event for all current file uploads,\n        // including ajax calls queued for sequential file uploads:\n        this._trigger(\n          'progressall',\n          $.Event('progressall', { delegatedEvent: e }),\n          this._progress\n        );\n      }\n    },\n\n    _initProgressListener: function (options) {\n      var that = this,\n        xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n      // Access to the native XHR object is required to add event listeners\n      // for the upload progress event:\n      if (xhr.upload) {\n        $(xhr.upload).on('progress', function (e) {\n          var oe = e.originalEvent;\n          // Make sure the progress event properties get copied over:\n          e.lengthComputable = oe.lengthComputable;\n          e.loaded = oe.loaded;\n          e.total = oe.total;\n          that._onProgress(e, options);\n        });\n        options.xhr = function () {\n          return xhr;\n        };\n      }\n    },\n\n    _deinitProgressListener: function (options) {\n      var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();\n      if (xhr.upload) {\n        $(xhr.upload).off('progress');\n      }\n    },\n\n    _isInstanceOf: function (type, obj) {\n      // Cross-frame instanceof check\n      return Object.prototype.toString.call(obj) === '[object ' + type + ']';\n    },\n\n    _getUniqueFilename: function (name, map) {\n      // eslint-disable-next-line no-param-reassign\n      name = String(name);\n      if (map[name]) {\n        // eslint-disable-next-line no-param-reassign\n        name = name.replace(\n          /(?: \\(([\\d]+)\\))?(\\.[^.]+)?$/,\n          function (_, p1, p2) {\n            var index = p1 ? Number(p1) + 1 : 1;\n            var ext = p2 || '';\n            return ' (' + index + ')' + ext;\n          }\n        );\n        return this._getUniqueFilename(name, map);\n      }\n      map[name] = true;\n      return name;\n    },\n\n    _initXHRData: function (options) {\n      var that = this,\n        formData,\n        file = options.files[0],\n        // Ignore non-multipart setting if not supported:\n        multipart = options.multipart || !$.support.xhrFileUpload,\n        paramName =\n          $.type(options.paramName) === 'array'\n            ? options.paramName[0]\n            : options.paramName;\n      options.headers = $.extend({}, options.headers);\n      if (options.contentRange) {\n        options.headers['Content-Range'] = options.contentRange;\n      }\n      if (!multipart || options.blob || !this._isInstanceOf('File', file)) {\n        options.headers['Content-Disposition'] =\n          'attachment; filename=\"' +\n          encodeURI(file.uploadName || file.name) +\n          '\"';\n      }\n      if (!multipart) {\n        options.contentType = file.type || 'application/octet-stream';\n        options.data = options.blob || file;\n      } else if ($.support.xhrFormDataFileUpload) {\n        if (options.postMessage) {\n          // window.postMessage does not allow sending FormData\n          // objects, so we just add the File/Blob objects to\n          // the formData array and let the postMessage window\n          // create the FormData object out of this array:\n          formData = this._getFormData(options);\n          if (options.blob) {\n            formData.push({\n              name: paramName,\n              value: options.blob\n            });\n          } else {\n            $.each(options.files, function (index, file) {\n              formData.push({\n                name:\n                  ($.type(options.paramName) === 'array' &&\n                    options.paramName[index]) ||\n                  paramName,\n                value: file\n              });\n            });\n          }\n        } else {\n          if (that._isInstanceOf('FormData', options.formData)) {\n            formData = options.formData;\n          } else {\n            formData = new FormData();\n            $.each(this._getFormData(options), function (index, field) {\n              formData.append(field.name, field.value);\n            });\n          }\n          if (options.blob) {\n            formData.append(\n              paramName,\n              options.blob,\n              file.uploadName || file.name\n            );\n          } else {\n            $.each(options.files, function (index, file) {\n              // This check allows the tests to run with\n              // dummy objects:\n              if (\n                that._isInstanceOf('File', file) ||\n                that._isInstanceOf('Blob', file)\n              ) {\n                var fileName = file.uploadName || file.name;\n                if (options.uniqueFilenames) {\n                  fileName = that._getUniqueFilename(\n                    fileName,\n                    options.uniqueFilenames\n                  );\n                }\n                formData.append(\n                  ($.type(options.paramName) === 'array' &&\n                    options.paramName[index]) ||\n                    paramName,\n                  file,\n                  fileName\n                );\n              }\n            });\n          }\n        }\n        options.data = formData;\n      }\n      // Blob reference is not needed anymore, free memory:\n      options.blob = null;\n    },\n\n    _initIframeSettings: function (options) {\n      var targetHost = $('<a></a>').prop('href', options.url).prop('host');\n      // Setting the dataType to iframe enables the iframe transport:\n      options.dataType = 'iframe ' + (options.dataType || '');\n      // The iframe transport accepts a serialized array as form data:\n      options.formData = this._getFormData(options);\n      // Add redirect url to form data on cross-domain uploads:\n      if (options.redirect && targetHost && targetHost !== location.host) {\n        options.formData.push({\n          name: options.redirectParamName || 'redirect',\n          value: options.redirect\n        });\n      }\n    },\n\n    _initDataSettings: function (options) {\n      if (this._isXHRUpload(options)) {\n        if (!this._chunkedUpload(options, true)) {\n          if (!options.data) {\n            this._initXHRData(options);\n          }\n          this._initProgressListener(options);\n        }\n        if (options.postMessage) {\n          // Setting the dataType to postmessage enables the\n          // postMessage transport:\n          options.dataType = 'postmessage ' + (options.dataType || '');\n        }\n      } else {\n        this._initIframeSettings(options);\n      }\n    },\n\n    _getParamName: function (options) {\n      var fileInput = $(options.fileInput),\n        paramName = options.paramName;\n      if (!paramName) {\n        paramName = [];\n        fileInput.each(function () {\n          var input = $(this),\n            name = input.prop('name') || 'files[]',\n            i = (input.prop('files') || [1]).length;\n          while (i) {\n            paramName.push(name);\n            i -= 1;\n          }\n        });\n        if (!paramName.length) {\n          paramName = [fileInput.prop('name') || 'files[]'];\n        }\n      } else if (!$.isArray(paramName)) {\n        paramName = [paramName];\n      }\n      return paramName;\n    },\n\n    _initFormSettings: function (options) {\n      // Retrieve missing options from the input field and the\n      // associated form, if available:\n      if (!options.form || !options.form.length) {\n        options.form = $(options.fileInput.prop('form'));\n        // If the given file input doesn't have an associated form,\n        // use the default widget file input's form:\n        if (!options.form.length) {\n          options.form = $(this.options.fileInput.prop('form'));\n        }\n      }\n      options.paramName = this._getParamName(options);\n      if (!options.url) {\n        options.url = options.form.prop('action') || location.href;\n      }\n      // The HTTP request method must be \"POST\" or \"PUT\":\n      options.type = (\n        options.type ||\n        ($.type(options.form.prop('method')) === 'string' &&\n          options.form.prop('method')) ||\n        ''\n      ).toUpperCase();\n      if (\n        options.type !== 'POST' &&\n        options.type !== 'PUT' &&\n        options.type !== 'PATCH'\n      ) {\n        options.type = 'POST';\n      }\n      if (!options.formAcceptCharset) {\n        options.formAcceptCharset = options.form.attr('accept-charset');\n      }\n    },\n\n    _getAJAXSettings: function (data) {\n      var options = $.extend({}, this.options, data);\n      this._initFormSettings(options);\n      this._initDataSettings(options);\n      return options;\n    },\n\n    // jQuery 1.6 doesn't provide .state(),\n    // while jQuery 1.8+ removed .isRejected() and .isResolved():\n    _getDeferredState: function (deferred) {\n      if (deferred.state) {\n        return deferred.state();\n      }\n      if (deferred.isResolved()) {\n        return 'resolved';\n      }\n      if (deferred.isRejected()) {\n        return 'rejected';\n      }\n      return 'pending';\n    },\n\n    // Maps jqXHR callbacks to the equivalent\n    // methods of the given Promise object:\n    _enhancePromise: function (promise) {\n      promise.success = promise.done;\n      promise.error = promise.fail;\n      promise.complete = promise.always;\n      return promise;\n    },\n\n    // Creates and returns a Promise object enhanced with\n    // the jqXHR methods abort, success, error and complete:\n    _getXHRPromise: function (resolveOrReject, context, args) {\n      var dfd = $.Deferred(),\n        promise = dfd.promise();\n      // eslint-disable-next-line no-param-reassign\n      context = context || this.options.context || promise;\n      if (resolveOrReject === true) {\n        dfd.resolveWith(context, args);\n      } else if (resolveOrReject === false) {\n        dfd.rejectWith(context, args);\n      }\n      promise.abort = dfd.promise;\n      return this._enhancePromise(promise);\n    },\n\n    // Adds convenience methods to the data callback argument:\n    _addConvenienceMethods: function (e, data) {\n      var that = this,\n        getPromise = function (args) {\n          return $.Deferred().resolveWith(that, args).promise();\n        };\n      data.process = function (resolveFunc, rejectFunc) {\n        if (resolveFunc || rejectFunc) {\n          data._processQueue = this._processQueue = (this._processQueue ||\n            getPromise([this]))\n            [that._promisePipe](function () {\n              if (data.errorThrown) {\n                return $.Deferred().rejectWith(that, [data]).promise();\n              }\n              return getPromise(arguments);\n            })\n            [that._promisePipe](resolveFunc, rejectFunc);\n        }\n        return this._processQueue || getPromise([this]);\n      };\n      data.submit = function () {\n        if (this.state() !== 'pending') {\n          data.jqXHR = this.jqXHR =\n            that._trigger(\n              'submit',\n              $.Event('submit', { delegatedEvent: e }),\n              this\n            ) !== false && that._onSend(e, this);\n        }\n        return this.jqXHR || that._getXHRPromise();\n      };\n      data.abort = function () {\n        if (this.jqXHR) {\n          return this.jqXHR.abort();\n        }\n        this.errorThrown = 'abort';\n        that._trigger('fail', null, this);\n        return that._getXHRPromise(false);\n      };\n      data.state = function () {\n        if (this.jqXHR) {\n          return that._getDeferredState(this.jqXHR);\n        }\n        if (this._processQueue) {\n          return that._getDeferredState(this._processQueue);\n        }\n      };\n      data.processing = function () {\n        return (\n          !this.jqXHR &&\n          this._processQueue &&\n          that._getDeferredState(this._processQueue) === 'pending'\n        );\n      };\n      data.progress = function () {\n        return this._progress;\n      };\n      data.response = function () {\n        return this._response;\n      };\n    },\n\n    // Parses the Range header from the server response\n    // and returns the uploaded bytes:\n    _getUploadedBytes: function (jqXHR) {\n      var range = jqXHR.getResponseHeader('Range'),\n        parts = range && range.split('-'),\n        upperBytesPos = parts && parts.length > 1 && parseInt(parts[1], 10);\n      return upperBytesPos && upperBytesPos + 1;\n    },\n\n    // Uploads a file in multiple, sequential requests\n    // by splitting the file up in multiple blob chunks.\n    // If the second parameter is true, only tests if the file\n    // should be uploaded in chunks, but does not invoke any\n    // upload requests:\n    _chunkedUpload: function (options, testOnly) {\n      options.uploadedBytes = options.uploadedBytes || 0;\n      var that = this,\n        file = options.files[0],\n        fs = file.size,\n        ub = options.uploadedBytes,\n        mcs = options.maxChunkSize || fs,\n        slice = this._blobSlice,\n        dfd = $.Deferred(),\n        promise = dfd.promise(),\n        jqXHR,\n        upload;\n      if (\n        !(\n          this._isXHRUpload(options) &&\n          slice &&\n          (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)\n        ) ||\n        options.data\n      ) {\n        return false;\n      }\n      if (testOnly) {\n        return true;\n      }\n      if (ub >= fs) {\n        file.error = options.i18n('uploadedBytes');\n        return this._getXHRPromise(false, options.context, [\n          null,\n          'error',\n          file.error\n        ]);\n      }\n      // The chunk upload method:\n      upload = function () {\n        // Clone the options object for each chunk upload:\n        var o = $.extend({}, options),\n          currentLoaded = o._progress.loaded;\n        o.blob = slice.call(\n          file,\n          ub,\n          ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),\n          file.type\n        );\n        // Store the current chunk size, as the blob itself\n        // will be dereferenced after data processing:\n        o.chunkSize = o.blob.size;\n        // Expose the chunk bytes position range:\n        o.contentRange =\n          'bytes ' + ub + '-' + (ub + o.chunkSize - 1) + '/' + fs;\n        // Trigger chunkbeforesend to allow form data to be updated for this chunk\n        that._trigger('chunkbeforesend', null, o);\n        // Process the upload data (the blob and potential form data):\n        that._initXHRData(o);\n        // Add progress listeners for this chunk upload:\n        that._initProgressListener(o);\n        jqXHR = (\n          (that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||\n          that._getXHRPromise(false, o.context)\n        )\n          .done(function (result, textStatus, jqXHR) {\n            ub = that._getUploadedBytes(jqXHR) || ub + o.chunkSize;\n            // Create a progress event if no final progress event\n            // with loaded equaling total has been triggered\n            // for this chunk:\n            if (currentLoaded + o.chunkSize - o._progress.loaded) {\n              that._onProgress(\n                $.Event('progress', {\n                  lengthComputable: true,\n                  loaded: ub - o.uploadedBytes,\n                  total: ub - o.uploadedBytes\n                }),\n                o\n              );\n            }\n            options.uploadedBytes = o.uploadedBytes = ub;\n            o.result = result;\n            o.textStatus = textStatus;\n            o.jqXHR = jqXHR;\n            that._trigger('chunkdone', null, o);\n            that._trigger('chunkalways', null, o);\n            if (ub < fs) {\n              // File upload not yet complete,\n              // continue with the next chunk:\n              upload();\n            } else {\n              dfd.resolveWith(o.context, [result, textStatus, jqXHR]);\n            }\n          })\n          .fail(function (jqXHR, textStatus, errorThrown) {\n            o.jqXHR = jqXHR;\n            o.textStatus = textStatus;\n            o.errorThrown = errorThrown;\n            that._trigger('chunkfail', null, o);\n            that._trigger('chunkalways', null, o);\n            dfd.rejectWith(o.context, [jqXHR, textStatus, errorThrown]);\n          })\n          .always(function () {\n            that._deinitProgressListener(o);\n          });\n      };\n      this._enhancePromise(promise);\n      promise.abort = function () {\n        return jqXHR.abort();\n      };\n      upload();\n      return promise;\n    },\n\n    _beforeSend: function (e, data) {\n      if (this._active === 0) {\n        // the start callback is triggered when an upload starts\n        // and no other uploads are currently running,\n        // equivalent to the global ajaxStart event:\n        this._trigger('start');\n        // Set timer for global bitrate progress calculation:\n        this._bitrateTimer = new this._BitrateTimer();\n        // Reset the global progress values:\n        this._progress.loaded = this._progress.total = 0;\n        this._progress.bitrate = 0;\n      }\n      // Make sure the container objects for the .response() and\n      // .progress() methods on the data object are available\n      // and reset to their initial state:\n      this._initResponseObject(data);\n      this._initProgressObject(data);\n      data._progress.loaded = data.loaded = data.uploadedBytes || 0;\n      data._progress.total = data.total = this._getTotal(data.files) || 1;\n      data._progress.bitrate = data.bitrate = 0;\n      this._active += 1;\n      // Initialize the global progress values:\n      this._progress.loaded += data.loaded;\n      this._progress.total += data.total;\n    },\n\n    _onDone: function (result, textStatus, jqXHR, options) {\n      var total = options._progress.total,\n        response = options._response;\n      if (options._progress.loaded < total) {\n        // Create a progress event if no final progress event\n        // with loaded equaling total has been triggered:\n        this._onProgress(\n          $.Event('progress', {\n            lengthComputable: true,\n            loaded: total,\n            total: total\n          }),\n          options\n        );\n      }\n      response.result = options.result = result;\n      response.textStatus = options.textStatus = textStatus;\n      response.jqXHR = options.jqXHR = jqXHR;\n      this._trigger('done', null, options);\n    },\n\n    _onFail: function (jqXHR, textStatus, errorThrown, options) {\n      var response = options._response;\n      if (options.recalculateProgress) {\n        // Remove the failed (error or abort) file upload from\n        // the global progress calculation:\n        this._progress.loaded -= options._progress.loaded;\n        this._progress.total -= options._progress.total;\n      }\n      response.jqXHR = options.jqXHR = jqXHR;\n      response.textStatus = options.textStatus = textStatus;\n      response.errorThrown = options.errorThrown = errorThrown;\n      this._trigger('fail', null, options);\n    },\n\n    _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {\n      // jqXHRorResult, textStatus and jqXHRorError are added to the\n      // options object via done and fail callbacks\n      this._trigger('always', null, options);\n    },\n\n    _onSend: function (e, data) {\n      if (!data.submit) {\n        this._addConvenienceMethods(e, data);\n      }\n      var that = this,\n        jqXHR,\n        aborted,\n        slot,\n        pipe,\n        options = that._getAJAXSettings(data),\n        send = function () {\n          that._sending += 1;\n          // Set timer for bitrate progress calculation:\n          options._bitrateTimer = new that._BitrateTimer();\n          jqXHR =\n            jqXHR ||\n            (\n              ((aborted ||\n                that._trigger(\n                  'send',\n                  $.Event('send', { delegatedEvent: e }),\n                  options\n                ) === false) &&\n                that._getXHRPromise(false, options.context, aborted)) ||\n              that._chunkedUpload(options) ||\n              $.ajax(options)\n            )\n              .done(function (result, textStatus, jqXHR) {\n                that._onDone(result, textStatus, jqXHR, options);\n              })\n              .fail(function (jqXHR, textStatus, errorThrown) {\n                that._onFail(jqXHR, textStatus, errorThrown, options);\n              })\n              .always(function (jqXHRorResult, textStatus, jqXHRorError) {\n                that._deinitProgressListener(options);\n                that._onAlways(\n                  jqXHRorResult,\n                  textStatus,\n                  jqXHRorError,\n                  options\n                );\n                that._sending -= 1;\n                that._active -= 1;\n                if (\n                  options.limitConcurrentUploads &&\n                  options.limitConcurrentUploads > that._sending\n                ) {\n                  // Start the next queued upload,\n                  // that has not been aborted:\n                  var nextSlot = that._slots.shift();\n                  while (nextSlot) {\n                    if (that._getDeferredState(nextSlot) === 'pending') {\n                      nextSlot.resolve();\n                      break;\n                    }\n                    nextSlot = that._slots.shift();\n                  }\n                }\n                if (that._active === 0) {\n                  // The stop callback is triggered when all uploads have\n                  // been completed, equivalent to the global ajaxStop event:\n                  that._trigger('stop');\n                }\n              });\n          return jqXHR;\n        };\n      this._beforeSend(e, options);\n      if (\n        this.options.sequentialUploads ||\n        (this.options.limitConcurrentUploads &&\n          this.options.limitConcurrentUploads <= this._sending)\n      ) {\n        if (this.options.limitConcurrentUploads > 1) {\n          slot = $.Deferred();\n          this._slots.push(slot);\n          pipe = slot[that._promisePipe](send);\n        } else {\n          this._sequence = this._sequence[that._promisePipe](send, send);\n          pipe = this._sequence;\n        }\n        // Return the piped Promise object, enhanced with an abort method,\n        // which is delegated to the jqXHR object of the current upload,\n        // and jqXHR callbacks mapped to the equivalent Promise methods:\n        pipe.abort = function () {\n          aborted = [undefined, 'abort', 'abort'];\n          if (!jqXHR) {\n            if (slot) {\n              slot.rejectWith(options.context, aborted);\n            }\n            return send();\n          }\n          return jqXHR.abort();\n        };\n        return this._enhancePromise(pipe);\n      }\n      return send();\n    },\n\n    _onAdd: function (e, data) {\n      var that = this,\n        result = true,\n        options = $.extend({}, this.options, data),\n        files = data.files,\n        filesLength = files.length,\n        limit = options.limitMultiFileUploads,\n        limitSize = options.limitMultiFileUploadSize,\n        overhead = options.limitMultiFileUploadSizeOverhead,\n        batchSize = 0,\n        paramName = this._getParamName(options),\n        paramNameSet,\n        paramNameSlice,\n        fileSet,\n        i,\n        j = 0;\n      if (!filesLength) {\n        return false;\n      }\n      if (limitSize && files[0].size === undefined) {\n        limitSize = undefined;\n      }\n      if (\n        !(options.singleFileUploads || limit || limitSize) ||\n        !this._isXHRUpload(options)\n      ) {\n        fileSet = [files];\n        paramNameSet = [paramName];\n      } else if (!(options.singleFileUploads || limitSize) && limit) {\n        fileSet = [];\n        paramNameSet = [];\n        for (i = 0; i < filesLength; i += limit) {\n          fileSet.push(files.slice(i, i + limit));\n          paramNameSlice = paramName.slice(i, i + limit);\n          if (!paramNameSlice.length) {\n            paramNameSlice = paramName;\n          }\n          paramNameSet.push(paramNameSlice);\n        }\n      } else if (!options.singleFileUploads && limitSize) {\n        fileSet = [];\n        paramNameSet = [];\n        for (i = 0; i < filesLength; i = i + 1) {\n          batchSize += files[i].size + overhead;\n          if (\n            i + 1 === filesLength ||\n            batchSize + files[i + 1].size + overhead > limitSize ||\n            (limit && i + 1 - j >= limit)\n          ) {\n            fileSet.push(files.slice(j, i + 1));\n            paramNameSlice = paramName.slice(j, i + 1);\n            if (!paramNameSlice.length) {\n              paramNameSlice = paramName;\n            }\n            paramNameSet.push(paramNameSlice);\n            j = i + 1;\n            batchSize = 0;\n          }\n        }\n      } else {\n        paramNameSet = paramName;\n      }\n      data.originalFiles = files;\n      $.each(fileSet || files, function (index, element) {\n        var newData = $.extend({}, data);\n        newData.files = fileSet ? element : [element];\n        newData.paramName = paramNameSet[index];\n        that._initResponseObject(newData);\n        that._initProgressObject(newData);\n        that._addConvenienceMethods(e, newData);\n        result = that._trigger(\n          'add',\n          $.Event('add', { delegatedEvent: e }),\n          newData\n        );\n        return result;\n      });\n      return result;\n    },\n\n    _replaceFileInput: function (data) {\n      var input = data.fileInput,\n        inputClone = input.clone(true),\n        restoreFocus = input.is(document.activeElement);\n      // Add a reference for the new cloned file input to the data argument:\n      data.fileInputClone = inputClone;\n      $('<form></form>').append(inputClone)[0].reset();\n      // Detaching allows to insert the fileInput on another form\n      // without losing the file input value:\n      input.after(inputClone).detach();\n      // If the fileInput had focus before it was detached,\n      // restore focus to the inputClone.\n      if (restoreFocus) {\n        inputClone.trigger('focus');\n      }\n      // Avoid memory leaks with the detached file input:\n      $.cleanData(input.off('remove'));\n      // Replace the original file input element in the fileInput\n      // elements set with the clone, which has been copied including\n      // event handlers:\n      this.options.fileInput = this.options.fileInput.map(function (i, el) {\n        if (el === input[0]) {\n          return inputClone[0];\n        }\n        return el;\n      });\n      // If the widget has been initialized on the file input itself,\n      // override this.element with the file input clone:\n      if (input[0] === this.element[0]) {\n        this.element = inputClone;\n      }\n    },\n\n    _handleFileTreeEntry: function (entry, path) {\n      var that = this,\n        dfd = $.Deferred(),\n        entries = [],\n        dirReader,\n        errorHandler = function (e) {\n          if (e && !e.entry) {\n            e.entry = entry;\n          }\n          // Since $.when returns immediately if one\n          // Deferred is rejected, we use resolve instead.\n          // This allows valid files and invalid items\n          // to be returned together in one set:\n          dfd.resolve([e]);\n        },\n        successHandler = function (entries) {\n          that\n            ._handleFileTreeEntries(entries, path + entry.name + '/')\n            .done(function (files) {\n              dfd.resolve(files);\n            })\n            .fail(errorHandler);\n        },\n        readEntries = function () {\n          dirReader.readEntries(function (results) {\n            if (!results.length) {\n              successHandler(entries);\n            } else {\n              entries = entries.concat(results);\n              readEntries();\n            }\n          }, errorHandler);\n        };\n      // eslint-disable-next-line no-param-reassign\n      path = path || '';\n      if (entry.isFile) {\n        if (entry._file) {\n          // Workaround for Chrome bug #149735\n          entry._file.relativePath = path;\n          dfd.resolve(entry._file);\n        } else {\n          entry.file(function (file) {\n            file.relativePath = path;\n            dfd.resolve(file);\n          }, errorHandler);\n        }\n      } else if (entry.isDirectory) {\n        dirReader = entry.createReader();\n        readEntries();\n      } else {\n        // Return an empty list for file system items\n        // other than files or directories:\n        dfd.resolve([]);\n      }\n      return dfd.promise();\n    },\n\n    _handleFileTreeEntries: function (entries, path) {\n      var that = this;\n      return $.when\n        .apply(\n          $,\n          $.map(entries, function (entry) {\n            return that._handleFileTreeEntry(entry, path);\n          })\n        )\n        [this._promisePipe](function () {\n          return Array.prototype.concat.apply([], arguments);\n        });\n    },\n\n    _getDroppedFiles: function (dataTransfer) {\n      // eslint-disable-next-line no-param-reassign\n      dataTransfer = dataTransfer || {};\n      var items = dataTransfer.items;\n      if (\n        items &&\n        items.length &&\n        (items[0].webkitGetAsEntry || items[0].getAsEntry)\n      ) {\n        return this._handleFileTreeEntries(\n          $.map(items, function (item) {\n            var entry;\n            if (item.webkitGetAsEntry) {\n              entry = item.webkitGetAsEntry();\n              if (entry) {\n                // Workaround for Chrome bug #149735:\n                entry._file = item.getAsFile();\n              }\n              return entry;\n            }\n            return item.getAsEntry();\n          })\n        );\n      }\n      return $.Deferred().resolve($.makeArray(dataTransfer.files)).promise();\n    },\n\n    _getSingleFileInputFiles: function (fileInput) {\n      // eslint-disable-next-line no-param-reassign\n      fileInput = $(fileInput);\n      var entries = fileInput.prop('entries'),\n        files,\n        value;\n      if (entries && entries.length) {\n        return this._handleFileTreeEntries(entries);\n      }\n      files = $.makeArray(fileInput.prop('files'));\n      if (!files.length) {\n        value = fileInput.prop('value');\n        if (!value) {\n          return $.Deferred().resolve([]).promise();\n        }\n        // If the files property is not available, the browser does not\n        // support the File API and we add a pseudo File object with\n        // the input value as name with path information removed:\n        files = [{ name: value.replace(/^.*\\\\/, '') }];\n      } else if (files[0].name === undefined && files[0].fileName) {\n        // File normalization for Safari 4 and Firefox 3:\n        $.each(files, function (index, file) {\n          file.name = file.fileName;\n          file.size = file.fileSize;\n        });\n      }\n      return $.Deferred().resolve(files).promise();\n    },\n\n    _getFileInputFiles: function (fileInput) {\n      if (!(fileInput instanceof $) || fileInput.length === 1) {\n        return this._getSingleFileInputFiles(fileInput);\n      }\n      return $.when\n        .apply($, $.map(fileInput, this._getSingleFileInputFiles))\n        [this._promisePipe](function () {\n          return Array.prototype.concat.apply([], arguments);\n        });\n    },\n\n    _onChange: function (e) {\n      var that = this,\n        data = {\n          fileInput: $(e.target),\n          form: $(e.target.form)\n        };\n      this._getFileInputFiles(data.fileInput).always(function (files) {\n        data.files = files;\n        if (that.options.replaceFileInput) {\n          that._replaceFileInput(data);\n        }\n        if (\n          that._trigger(\n            'change',\n            $.Event('change', { delegatedEvent: e }),\n            data\n          ) !== false\n        ) {\n          that._onAdd(e, data);\n        }\n      });\n    },\n\n    _onPaste: function (e) {\n      var items =\n          e.originalEvent &&\n          e.originalEvent.clipboardData &&\n          e.originalEvent.clipboardData.items,\n        data = { files: [] };\n      if (items && items.length) {\n        $.each(items, function (index, item) {\n          var file = item.getAsFile && item.getAsFile();\n          if (file) {\n            data.files.push(file);\n          }\n        });\n        if (\n          this._trigger(\n            'paste',\n            $.Event('paste', { delegatedEvent: e }),\n            data\n          ) !== false\n        ) {\n          this._onAdd(e, data);\n        }\n      }\n    },\n\n    _onDrop: function (e) {\n      e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;\n      var that = this,\n        dataTransfer = e.dataTransfer,\n        data = {};\n      if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {\n        e.preventDefault();\n        this._getDroppedFiles(dataTransfer).always(function (files) {\n          data.files = files;\n          if (\n            that._trigger(\n              'drop',\n              $.Event('drop', { delegatedEvent: e }),\n              data\n            ) !== false\n          ) {\n            that._onAdd(e, data);\n          }\n        });\n      }\n    },\n\n    _onDragOver: getDragHandler('dragover'),\n\n    _onDragEnter: getDragHandler('dragenter'),\n\n    _onDragLeave: getDragHandler('dragleave'),\n\n    _initEventHandlers: function () {\n      if (this._isXHRUpload(this.options)) {\n        this._on(this.options.dropZone, {\n          dragover: this._onDragOver,\n          drop: this._onDrop,\n          // event.preventDefault() on dragenter is required for IE10+:\n          dragenter: this._onDragEnter,\n          // dragleave is not required, but added for completeness:\n          dragleave: this._onDragLeave\n        });\n        this._on(this.options.pasteZone, {\n          paste: this._onPaste\n        });\n      }\n      if ($.support.fileInput) {\n        this._on(this.options.fileInput, {\n          change: this._onChange\n        });\n      }\n    },\n\n    _destroyEventHandlers: function () {\n      this._off(this.options.dropZone, 'dragenter dragleave dragover drop');\n      this._off(this.options.pasteZone, 'paste');\n      this._off(this.options.fileInput, 'change');\n    },\n\n    _destroy: function () {\n      this._destroyEventHandlers();\n    },\n\n    _setOption: function (key, value) {\n      var reinit = $.inArray(key, this._specialOptions) !== -1;\n      if (reinit) {\n        this._destroyEventHandlers();\n      }\n      this._super(key, value);\n      if (reinit) {\n        this._initSpecialOptions();\n        this._initEventHandlers();\n      }\n    },\n\n    _initSpecialOptions: function () {\n      var options = this.options;\n      if (options.fileInput === undefined) {\n        options.fileInput = this.element.is('input[type=\"file\"]')\n          ? this.element\n          : this.element.find('input[type=\"file\"]');\n      } else if (!(options.fileInput instanceof $)) {\n        options.fileInput = $(options.fileInput);\n      }\n      if (!(options.dropZone instanceof $)) {\n        options.dropZone = $(options.dropZone);\n      }\n      if (!(options.pasteZone instanceof $)) {\n        options.pasteZone = $(options.pasteZone);\n      }\n    },\n\n    _getRegExp: function (str) {\n      var parts = str.split('/'),\n        modifiers = parts.pop();\n      parts.shift();\n      return new RegExp(parts.join('/'), modifiers);\n    },\n\n    _isRegExpOption: function (key, value) {\n      return (\n        key !== 'url' &&\n        $.type(value) === 'string' &&\n        /^\\/.*\\/[igm]{0,3}$/.test(value)\n      );\n    },\n\n    _initDataAttributes: function () {\n      var that = this,\n        options = this.options,\n        data = this.element.data();\n      // Initialize options set via HTML5 data-attributes:\n      $.each(this.element[0].attributes, function (index, attr) {\n        var key = attr.name.toLowerCase(),\n          value;\n        if (/^data-/.test(key)) {\n          // Convert hyphen-ated key to camelCase:\n          key = key.slice(5).replace(/-[a-z]/g, function (str) {\n            return str.charAt(1).toUpperCase();\n          });\n          value = data[key];\n          if (that._isRegExpOption(key, value)) {\n            value = that._getRegExp(value);\n          }\n          options[key] = value;\n        }\n      });\n    },\n\n    _create: function () {\n      this._initDataAttributes();\n      this._initSpecialOptions();\n      this._slots = [];\n      this._sequence = this._getXHRPromise(true);\n      this._sending = this._active = 0;\n      this._initProgressObject(this);\n      this._initEventHandlers();\n    },\n\n    // This method is exposed to the widget API and allows to query\n    // the number of active uploads:\n    active: function () {\n      return this._active;\n    },\n\n    // This method is exposed to the widget API and allows to query\n    // the widget upload progress.\n    // It returns an object with loaded, total and bitrate properties\n    // for the running uploads:\n    progress: function () {\n      return this._progress;\n    },\n\n    // This method is exposed to the widget API and allows adding files\n    // using the fileupload API. The data parameter accepts an object which\n    // must have a files property and can contain additional options:\n    // .fileupload('add', {files: filesList});\n    add: function (data) {\n      var that = this;\n      if (!data || this.options.disabled) {\n        return;\n      }\n      if (data.fileInput && !data.files) {\n        this._getFileInputFiles(data.fileInput).always(function (files) {\n          data.files = files;\n          that._onAdd(null, data);\n        });\n      } else {\n        data.files = $.makeArray(data.files);\n        this._onAdd(null, data);\n      }\n    },\n\n    // This method is exposed to the widget API and allows sending files\n    // using the fileupload API. The data parameter accepts an object which\n    // must have a files or fileInput property and can contain additional options:\n    // .fileupload('send', {files: filesList});\n    // The method returns a Promise object for the file upload call.\n    send: function (data) {\n      if (data && !this.options.disabled) {\n        if (data.fileInput && !data.files) {\n          var that = this,\n            dfd = $.Deferred(),\n            promise = dfd.promise(),\n            jqXHR,\n            aborted;\n          promise.abort = function () {\n            aborted = true;\n            if (jqXHR) {\n              return jqXHR.abort();\n            }\n            dfd.reject(null, 'abort', 'abort');\n            return promise;\n          };\n          this._getFileInputFiles(data.fileInput).always(function (files) {\n            if (aborted) {\n              return;\n            }\n            if (!files.length) {\n              dfd.reject();\n              return;\n            }\n            data.files = files;\n            jqXHR = that._onSend(null, data);\n            jqXHR.then(\n              function (result, textStatus, jqXHR) {\n                dfd.resolve(result, textStatus, jqXHR);\n              },\n              function (jqXHR, textStatus, errorThrown) {\n                dfd.reject(jqXHR, textStatus, errorThrown);\n              }\n            );\n          });\n          return this._enhancePromise(promise);\n        }\n        data.files = $.makeArray(data.files);\n        if (data.files.length) {\n          return this._onSend(null, data);\n        }\n      }\n      return this._getXHRPromise(false, data && data.context);\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/jquery.iframe-transport.js":"/*\n * jQuery Iframe Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(require('jquery'));\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})(function ($) {\n  'use strict';\n\n  // Helper variable to create unique names for the transport iframes:\n  var counter = 0,\n    jsonAPI = $,\n    jsonParse = 'parseJSON';\n\n  if ('JSON' in window && 'parse' in JSON) {\n    jsonAPI = JSON;\n    jsonParse = 'parse';\n  }\n\n  // The iframe transport accepts four additional options:\n  // options.fileInput: a jQuery collection of file input fields\n  // options.paramName: the parameter name for the file form data,\n  //  overrides the name property of the file input field(s),\n  //  can be a string or an array of strings.\n  // options.formData: an array of objects with name and value properties,\n  //  equivalent to the return data of .serializeArray(), e.g.:\n  //  [{name: 'a', value: 1}, {name: 'b', value: 2}]\n  // options.initialIframeSrc: the URL of the initial iframe src,\n  //  by default set to \"javascript:false;\"\n  $.ajaxTransport('iframe', function (options) {\n    if (options.async) {\n      // javascript:false as initial iframe src\n      // prevents warning popups on HTTPS in IE6:\n      // eslint-disable-next-line no-script-url\n      var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',\n        form,\n        iframe,\n        addParamChar;\n      return {\n        send: function (_, completeCallback) {\n          form = $('<form style=\"display:none;\"></form>');\n          form.attr('accept-charset', options.formAcceptCharset);\n          addParamChar = /\\?/.test(options.url) ? '&' : '?';\n          // XDomainRequest only supports GET and POST:\n          if (options.type === 'DELETE') {\n            options.url = options.url + addParamChar + '_method=DELETE';\n            options.type = 'POST';\n          } else if (options.type === 'PUT') {\n            options.url = options.url + addParamChar + '_method=PUT';\n            options.type = 'POST';\n          } else if (options.type === 'PATCH') {\n            options.url = options.url + addParamChar + '_method=PATCH';\n            options.type = 'POST';\n          }\n          // IE versions below IE8 cannot set the name property of\n          // elements that have already been added to the DOM,\n          // so we set the name along with the iframe HTML markup:\n          counter += 1;\n          iframe = $(\n            '<iframe src=\"' +\n              initialIframeSrc +\n              '\" name=\"iframe-transport-' +\n              counter +\n              '\"></iframe>'\n          ).on('load', function () {\n            var fileInputClones,\n              paramNames = $.isArray(options.paramName)\n                ? options.paramName\n                : [options.paramName];\n            iframe.off('load').on('load', function () {\n              var response;\n              // Wrap in a try/catch block to catch exceptions thrown\n              // when trying to access cross-domain iframe contents:\n              try {\n                response = iframe.contents();\n                // Google Chrome and Firefox do not throw an\n                // exception when calling iframe.contents() on\n                // cross-domain requests, so we unify the response:\n                if (!response.length || !response[0].firstChild) {\n                  throw new Error();\n                }\n              } catch (e) {\n                response = undefined;\n              }\n              // The complete callback returns the\n              // iframe content document as response object:\n              completeCallback(200, 'success', { iframe: response });\n              // Fix for IE endless progress bar activity bug\n              // (happens on form submits to iframe targets):\n              $('<iframe src=\"' + initialIframeSrc + '\"></iframe>').appendTo(\n                form\n              );\n              window.setTimeout(function () {\n                // Removing the form in a setTimeout call\n                // allows Chrome's developer tools to display\n                // the response result\n                form.remove();\n              }, 0);\n            });\n            form\n              .prop('target', iframe.prop('name'))\n              .prop('action', options.url)\n              .prop('method', options.type);\n            if (options.formData) {\n              $.each(options.formData, function (index, field) {\n                $('<input type=\"hidden\"/>')\n                  .prop('name', field.name)\n                  .val(field.value)\n                  .appendTo(form);\n              });\n            }\n            if (\n              options.fileInput &&\n              options.fileInput.length &&\n              options.type === 'POST'\n            ) {\n              fileInputClones = options.fileInput.clone();\n              // Insert a clone for each file input field:\n              options.fileInput.after(function (index) {\n                return fileInputClones[index];\n              });\n              if (options.paramName) {\n                options.fileInput.each(function (index) {\n                  $(this).prop('name', paramNames[index] || options.paramName);\n                });\n              }\n              // Appending the file input fields to the hidden form\n              // removes them from their original location:\n              form\n                .append(options.fileInput)\n                .prop('enctype', 'multipart/form-data')\n                // enctype must be set as encoding for IE:\n                .prop('encoding', 'multipart/form-data');\n              // Remove the HTML5 form attribute from the input(s):\n              options.fileInput.removeAttr('form');\n            }\n            window.setTimeout(function () {\n              // Submitting the form in a setTimeout call fixes an issue with\n              // Safari 13 not triggering the iframe load event after resetting\n              // the load event handler, see also:\n              // https://github.com/blueimp/jQuery-File-Upload/issues/3633\n              form.submit();\n              // Insert the file input fields at their original location\n              // by replacing the clones with the originals:\n              if (fileInputClones && fileInputClones.length) {\n                options.fileInput.each(function (index, input) {\n                  var clone = $(fileInputClones[index]);\n                  // Restore the original name and form properties:\n                  $(input)\n                    .prop('name', clone.prop('name'))\n                    .attr('form', clone.attr('form'));\n                  clone.replaceWith(input);\n                });\n              }\n            }, 0);\n          });\n          form.append(iframe).appendTo(document.body);\n        },\n        abort: function () {\n          if (iframe) {\n            // javascript:false as iframe src aborts the request\n            // and prevents warning popups on HTTPS in IE6.\n            iframe.off('load').prop('src', initialIframeSrc);\n          }\n          if (form) {\n            form.remove();\n          }\n        }\n      };\n    }\n  });\n\n  // The iframe transport returns the iframe content document as response.\n  // The following adds converters from iframe to text, json, html, xml\n  // and script.\n  // Please note that the Content-Type for JSON responses has to be text/plain\n  // or text/html, if the browser doesn't include application/json in the\n  // Accept header, else IE will show a download dialog.\n  // The Content-Type for XML responses on the other hand has to be always\n  // application/xml or text/xml, so IE properly parses the XML response.\n  // See also\n  // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation\n  $.ajaxSetup({\n    converters: {\n      'iframe text': function (iframe) {\n        return iframe && $(iframe[0].body).text();\n      },\n      'iframe json': function (iframe) {\n        return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());\n      },\n      'iframe html': function (iframe) {\n        return iframe && $(iframe[0].body).html();\n      },\n      'iframe xml': function (iframe) {\n        var xmlDoc = iframe && iframe[0];\n        return xmlDoc && $.isXMLDoc(xmlDoc)\n          ? xmlDoc\n          : $.parseXML(\n              (xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||\n                $(xmlDoc.body).html()\n            );\n      },\n      'iframe script': function (iframe) {\n        return iframe && $.globalEval($(iframe[0].body).text());\n      }\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/jquery.fileupload-video.js":"/*\n * jQuery File Upload Video Preview Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/jquery.fileupload-process'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(\n      require('jquery'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-process')\n    );\n  } else {\n    // Browser globals:\n    factory(window.jQuery, window.loadImage);\n  }\n})(function ($, loadImage) {\n  'use strict';\n\n  // Prepend to the default processQueue:\n  $.blueimp.fileupload.prototype.options.processQueue.unshift(\n    {\n      action: 'loadVideo',\n      // Use the action as prefix for the \"@\" options:\n      prefix: true,\n      fileTypes: '@',\n      maxFileSize: '@',\n      disabled: '@disableVideoPreview'\n    },\n    {\n      action: 'setVideo',\n      name: '@videoPreviewName',\n      disabled: '@disableVideoPreview'\n    }\n  );\n\n  // The File Upload Video Preview plugin extends the fileupload widget\n  // with video preview functionality:\n  $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n    options: {\n      // The regular expression for the types of video files to load,\n      // matched against the file type:\n      loadVideoFileTypes: /^video\\/.*$/\n    },\n\n    _videoElement: document.createElement('video'),\n\n    processActions: {\n      // Loads the video file given via data.files and data.index\n      // as video element if the browser supports playing it.\n      // Accepts the options fileTypes (regular expression)\n      // and maxFileSize (integer) to limit the files to load:\n      loadVideo: function (data, options) {\n        if (options.disabled) {\n          return data;\n        }\n        var file = data.files[data.index],\n          url,\n          video;\n        if (\n          this._videoElement.canPlayType &&\n          this._videoElement.canPlayType(file.type) &&\n          ($.type(options.maxFileSize) !== 'number' ||\n            file.size <= options.maxFileSize) &&\n          (!options.fileTypes || options.fileTypes.test(file.type))\n        ) {\n          url = loadImage.createObjectURL(file);\n          if (url) {\n            video = this._videoElement.cloneNode(false);\n            video.src = url;\n            video.controls = true;\n            data.video = video;\n            return data;\n          }\n        }\n        return data;\n      },\n\n      // Sets the video element as a property of the file object:\n      setVideo: function (data, options) {\n        if (data.video && !options.disabled) {\n          data.files[data.index][options.name || 'preview'] = data.video;\n        }\n        return data;\n      }\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/jquery.fileupload-process.js":"/*\n * jQuery File Upload Processing Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery', 'Mageplaza_Core/lib/fileUploader/jquery.fileupload'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(require('jquery'), require('Mageplaza_Core/lib/fileUploader/jquery.fileupload'));\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})(function ($) {\n  'use strict';\n\n  var originalAdd = $.blueimp.fileupload.prototype.options.add;\n\n  // The File Upload Processing plugin extends the fileupload widget\n  // with file processing functionality:\n  $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n    options: {\n      // The list of processing actions:\n      processQueue: [\n        /*\n                {\n                    action: 'log',\n                    type: 'debug'\n                }\n                */\n      ],\n      add: function (e, data) {\n        var $this = $(this);\n        data.process(function () {\n          return $this.fileupload('process', data);\n        });\n        originalAdd.call(this, e, data);\n      }\n    },\n\n    processActions: {\n      /*\n            log: function (data, options) {\n                console[options.type](\n                    'Processing \"' + data.files[data.index].name + '\"'\n                );\n            }\n            */\n    },\n\n    _processFile: function (data, originalData) {\n      var that = this,\n        // eslint-disable-next-line new-cap\n        dfd = $.Deferred().resolveWith(that, [data]),\n        chain = dfd.promise();\n      this._trigger('process', null, data);\n      $.each(data.processQueue, function (i, settings) {\n        var func = function (data) {\n          if (originalData.errorThrown) {\n            // eslint-disable-next-line new-cap\n            return $.Deferred().rejectWith(that, [originalData]).promise();\n          }\n          return that.processActions[settings.action].call(\n            that,\n            data,\n            settings\n          );\n        };\n        chain = chain[that._promisePipe](func, settings.always && func);\n      });\n      chain\n        .done(function () {\n          that._trigger('processdone', null, data);\n          that._trigger('processalways', null, data);\n        })\n        .fail(function () {\n          that._trigger('processfail', null, data);\n          that._trigger('processalways', null, data);\n        });\n      return chain;\n    },\n\n    // Replaces the settings of each processQueue item that\n    // are strings starting with an \"@\", using the remaining\n    // substring as key for the option map,\n    // e.g. \"@autoUpload\" is replaced with options.autoUpload:\n    _transformProcessQueue: function (options) {\n      var processQueue = [];\n      $.each(options.processQueue, function () {\n        var settings = {},\n          action = this.action,\n          prefix = this.prefix === true ? action : this.prefix;\n        $.each(this, function (key, value) {\n          if ($.type(value) === 'string' && value.charAt(0) === '@') {\n            settings[key] =\n              options[\n                value.slice(1) ||\n                  (prefix\n                    ? prefix + key.charAt(0).toUpperCase() + key.slice(1)\n                    : key)\n              ];\n          } else {\n            settings[key] = value;\n          }\n        });\n        processQueue.push(settings);\n      });\n      options.processQueue = processQueue;\n    },\n\n    // Returns the number of files currently in the processing queue:\n    processing: function () {\n      return this._processing;\n    },\n\n    // Processes the files given as files property of the data parameter,\n    // returns a Promise object that allows to bind callbacks:\n    process: function (data) {\n      var that = this,\n        options = $.extend({}, this.options, data);\n      if (options.processQueue && options.processQueue.length) {\n        this._transformProcessQueue(options);\n        if (this._processing === 0) {\n          this._trigger('processstart');\n        }\n        $.each(data.files, function (index) {\n          var opts = index ? $.extend({}, options) : options,\n            func = function () {\n              if (data.errorThrown) {\n                // eslint-disable-next-line new-cap\n                return $.Deferred().rejectWith(that, [data]).promise();\n              }\n              return that._processFile(opts, data);\n            };\n          opts.index = index;\n          that._processing += 1;\n          that._processingQueue = that._processingQueue[that._promisePipe](\n            func,\n            func\n          ).always(function () {\n            that._processing -= 1;\n            if (that._processing === 0) {\n              that._trigger('processstop');\n            }\n          });\n        });\n      }\n      return this._processingQueue;\n    },\n\n    _create: function () {\n      this._super();\n      this._processing = 0;\n      // eslint-disable-next-line new-cap\n      this._processingQueue = $.Deferred().resolveWith(this).promise();\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/jquery.fileupload-ui.js":"/*\n * jQuery File Upload User Interface Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2010, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      'jquery',\n      'Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/tmpl',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-image',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-video',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-validate'\n    ], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(\n      require('jquery'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/tmpl'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-image'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-video'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-validate')\n    );\n  } else {\n    // Browser globals:\n    factory(window.jQuery, window.tmpl);\n  }\n})(function ($, tmpl) {\n  'use strict';\n\n  $.blueimp.fileupload.prototype._specialOptions.push(\n    'filesContainer',\n    'uploadTemplateId',\n    'downloadTemplateId'\n  );\n\n  // The UI version extends the file upload widget\n  // and adds complete user interface interaction:\n  $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n    options: {\n      // By default, files added to the widget are uploaded as soon\n      // as the user clicks on the start buttons. To enable automatic\n      // uploads, set the following option to true:\n      autoUpload: false,\n      // The class to show/hide UI elements:\n      showElementClass: 'in',\n      // The ID of the upload template:\n      uploadTemplateId: 'template-upload',\n      // The ID of the download template:\n      downloadTemplateId: 'template-download',\n      // The container for the list of files. If undefined, it is set to\n      // an element with class \"files\" inside of the widget element:\n      filesContainer: undefined,\n      // By default, files are appended to the files container.\n      // Set the following option to true, to prepend files instead:\n      prependFiles: false,\n      // The expected data type of the upload response, sets the dataType\n      // option of the $.ajax upload requests:\n      dataType: 'json',\n\n      // Error and info messages:\n      messages: {\n        unknownError: 'Unknown error'\n      },\n\n      // Function returning the current number of files,\n      // used by the maxNumberOfFiles validation:\n      getNumberOfFiles: function () {\n        return this.filesContainer.children().not('.processing').length;\n      },\n\n      // Callback to retrieve the list of files from the server response:\n      getFilesFromResponse: function (data) {\n        if (data.result && $.isArray(data.result.files)) {\n          return data.result.files;\n        }\n        return [];\n      },\n\n      // The add callback is invoked as soon as files are added to the fileupload\n      // widget (via file input selection, drag & drop or add API call).\n      // See the basic file upload widget for more information:\n      add: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var $this = $(this),\n          that = $this.data('blueimp-fileupload') || $this.data('fileupload'),\n          options = that.options;\n        data.context = that\n          ._renderUpload(data.files)\n          .data('data', data)\n          .addClass('processing');\n        options.filesContainer[options.prependFiles ? 'prepend' : 'append'](\n          data.context\n        );\n        that._forceReflow(data.context);\n        that._transition(data.context);\n        data\n          .process(function () {\n            return $this.fileupload('process', data);\n          })\n          .always(function () {\n            data.context\n              .each(function (index) {\n                $(this)\n                  .find('.size')\n                  .text(that._formatFileSize(data.files[index].size));\n              })\n              .removeClass('processing');\n            that._renderPreviews(data);\n          })\n          .done(function () {\n            data.context.find('.edit,.start').prop('disabled', false);\n            if (\n              that._trigger('added', e, data) !== false &&\n              (options.autoUpload || data.autoUpload) &&\n              data.autoUpload !== false\n            ) {\n              data.submit();\n            }\n          })\n          .fail(function () {\n            if (data.files.error) {\n              data.context.each(function (index) {\n                var error = data.files[index].error;\n                if (error) {\n                  $(this).find('.error').text(error);\n                }\n              });\n            }\n          });\n      },\n      // Callback for the start of each file upload request:\n      send: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n          $(this).data('blueimp-fileupload') || $(this).data('fileupload');\n        if (\n          data.context &&\n          data.dataType &&\n          data.dataType.substr(0, 6) === 'iframe'\n        ) {\n          // Iframe Transport does not support progress events.\n          // In lack of an indeterminate progress bar, we set\n          // the progress to 100%, showing the full animated bar:\n          data.context\n            .find('.progress')\n            .addClass(!$.support.transition && 'progress-animated')\n            .attr('aria-valuenow', 100)\n            .children()\n            .first()\n            .css('width', '100%');\n        }\n        return that._trigger('sent', e, data);\n      },\n      // Callback for successful uploads:\n      done: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n            $(this).data('blueimp-fileupload') || $(this).data('fileupload'),\n          getFilesFromResponse =\n            data.getFilesFromResponse || that.options.getFilesFromResponse,\n          files = getFilesFromResponse(data),\n          template,\n          deferred;\n        if (data.context) {\n          data.context.each(function (index) {\n            var file = files[index] || { error: 'Empty file upload result' };\n            deferred = that._addFinishedDeferreds();\n            that._transition($(this)).done(function () {\n              var node = $(this);\n              template = that._renderDownload([file]).replaceAll(node);\n              that._forceReflow(template);\n              that._transition(template).done(function () {\n                data.context = $(this);\n                that._trigger('completed', e, data);\n                that._trigger('finished', e, data);\n                deferred.resolve();\n              });\n            });\n          });\n        } else {\n          template = that\n            ._renderDownload(files)\n            [that.options.prependFiles ? 'prependTo' : 'appendTo'](\n              that.options.filesContainer\n            );\n          that._forceReflow(template);\n          deferred = that._addFinishedDeferreds();\n          that._transition(template).done(function () {\n            data.context = $(this);\n            that._trigger('completed', e, data);\n            that._trigger('finished', e, data);\n            deferred.resolve();\n          });\n        }\n      },\n      // Callback for failed (abort or error) uploads:\n      fail: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n            $(this).data('blueimp-fileupload') || $(this).data('fileupload'),\n          template,\n          deferred;\n        if (data.context) {\n          data.context.each(function (index) {\n            if (data.errorThrown !== 'abort') {\n              var file = data.files[index];\n              file.error =\n                file.error || data.errorThrown || data.i18n('unknownError');\n              deferred = that._addFinishedDeferreds();\n              that._transition($(this)).done(function () {\n                var node = $(this);\n                template = that._renderDownload([file]).replaceAll(node);\n                that._forceReflow(template);\n                that._transition(template).done(function () {\n                  data.context = $(this);\n                  that._trigger('failed', e, data);\n                  that._trigger('finished', e, data);\n                  deferred.resolve();\n                });\n              });\n            } else {\n              deferred = that._addFinishedDeferreds();\n              that._transition($(this)).done(function () {\n                $(this).remove();\n                that._trigger('failed', e, data);\n                that._trigger('finished', e, data);\n                deferred.resolve();\n              });\n            }\n          });\n        } else if (data.errorThrown !== 'abort') {\n          data.context = that\n            ._renderUpload(data.files)\n            [that.options.prependFiles ? 'prependTo' : 'appendTo'](\n              that.options.filesContainer\n            )\n            .data('data', data);\n          that._forceReflow(data.context);\n          deferred = that._addFinishedDeferreds();\n          that._transition(data.context).done(function () {\n            data.context = $(this);\n            that._trigger('failed', e, data);\n            that._trigger('finished', e, data);\n            deferred.resolve();\n          });\n        } else {\n          that._trigger('failed', e, data);\n          that._trigger('finished', e, data);\n          that._addFinishedDeferreds().resolve();\n        }\n      },\n      // Callback for upload progress events:\n      progress: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var progress = Math.floor((data.loaded / data.total) * 100);\n        if (data.context) {\n          data.context.each(function () {\n            $(this)\n              .find('.progress')\n              .attr('aria-valuenow', progress)\n              .children()\n              .first()\n              .css('width', progress + '%');\n          });\n        }\n      },\n      // Callback for global upload progress events:\n      progressall: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var $this = $(this),\n          progress = Math.floor((data.loaded / data.total) * 100),\n          globalProgressNode = $this.find('.fileupload-progress'),\n          extendedProgressNode = globalProgressNode.find('.progress-extended');\n        if (extendedProgressNode.length) {\n          extendedProgressNode.html(\n            (\n              $this.data('blueimp-fileupload') || $this.data('fileupload')\n            )._renderExtendedProgress(data)\n          );\n        }\n        globalProgressNode\n          .find('.progress')\n          .attr('aria-valuenow', progress)\n          .children()\n          .first()\n          .css('width', progress + '%');\n      },\n      // Callback for uploads start, equivalent to the global ajaxStart event:\n      start: function (e) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n          $(this).data('blueimp-fileupload') || $(this).data('fileupload');\n        that._resetFinishedDeferreds();\n        that\n          ._transition($(this).find('.fileupload-progress'))\n          .done(function () {\n            that._trigger('started', e);\n          });\n      },\n      // Callback for uploads stop, equivalent to the global ajaxStop event:\n      stop: function (e) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n            $(this).data('blueimp-fileupload') || $(this).data('fileupload'),\n          deferred = that._addFinishedDeferreds();\n        $.when.apply($, that._getFinishedDeferreds()).done(function () {\n          that._trigger('stopped', e);\n        });\n        that\n          ._transition($(this).find('.fileupload-progress'))\n          .done(function () {\n            $(this)\n              .find('.progress')\n              .attr('aria-valuenow', '0')\n              .children()\n              .first()\n              .css('width', '0%');\n            $(this).find('.progress-extended').html('&nbsp;');\n            deferred.resolve();\n          });\n      },\n      processstart: function (e) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        $(this).addClass('fileupload-processing');\n      },\n      processstop: function (e) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        $(this).removeClass('fileupload-processing');\n      },\n      // Callback for file deletion:\n      destroy: function (e, data) {\n        if (e.isDefaultPrevented()) {\n          return false;\n        }\n        var that =\n            $(this).data('blueimp-fileupload') || $(this).data('fileupload'),\n          removeNode = function () {\n            that._transition(data.context).done(function () {\n              $(this).remove();\n              that._trigger('destroyed', e, data);\n            });\n          };\n        if (data.url) {\n          data.dataType = data.dataType || that.options.dataType;\n          $.ajax(data)\n            .done(removeNode)\n            .fail(function () {\n              that._trigger('destroyfailed', e, data);\n            });\n        } else {\n          removeNode();\n        }\n      }\n    },\n\n    _resetFinishedDeferreds: function () {\n      this._finishedUploads = [];\n    },\n\n    _addFinishedDeferreds: function (deferred) {\n      // eslint-disable-next-line new-cap\n      var promise = deferred || $.Deferred();\n      this._finishedUploads.push(promise);\n      return promise;\n    },\n\n    _getFinishedDeferreds: function () {\n      return this._finishedUploads;\n    },\n\n    // Link handler, that allows to download files\n    // by drag & drop of the links to the desktop:\n    _enableDragToDesktop: function () {\n      var link = $(this),\n        url = link.prop('href'),\n        name = link.prop('download'),\n        type = 'application/octet-stream';\n      link.on('dragstart', function (e) {\n        try {\n          e.originalEvent.dataTransfer.setData(\n            'DownloadURL',\n            [type, name, url].join(':')\n          );\n        } catch (ignore) {\n          // Ignore exceptions\n        }\n      });\n    },\n\n    _formatFileSize: function (bytes) {\n      if (typeof bytes !== 'number') {\n        return '';\n      }\n      if (bytes >= 1000000000) {\n        return (bytes / 1000000000).toFixed(2) + ' GB';\n      }\n      if (bytes >= 1000000) {\n        return (bytes / 1000000).toFixed(2) + ' MB';\n      }\n      return (bytes / 1000).toFixed(2) + ' KB';\n    },\n\n    _formatBitrate: function (bits) {\n      if (typeof bits !== 'number') {\n        return '';\n      }\n      if (bits >= 1000000000) {\n        return (bits / 1000000000).toFixed(2) + ' Gbit/s';\n      }\n      if (bits >= 1000000) {\n        return (bits / 1000000).toFixed(2) + ' Mbit/s';\n      }\n      if (bits >= 1000) {\n        return (bits / 1000).toFixed(2) + ' kbit/s';\n      }\n      return bits.toFixed(2) + ' bit/s';\n    },\n\n    _formatTime: function (seconds) {\n      var date = new Date(seconds * 1000),\n        days = Math.floor(seconds / 86400);\n      days = days ? days + 'd ' : '';\n      return (\n        days +\n        ('0' + date.getUTCHours()).slice(-2) +\n        ':' +\n        ('0' + date.getUTCMinutes()).slice(-2) +\n        ':' +\n        ('0' + date.getUTCSeconds()).slice(-2)\n      );\n    },\n\n    _formatPercentage: function (floatValue) {\n      return (floatValue * 100).toFixed(2) + ' %';\n    },\n\n    _renderExtendedProgress: function (data) {\n      return (\n        this._formatBitrate(data.bitrate) +\n        ' | ' +\n        this._formatTime(((data.total - data.loaded) * 8) / data.bitrate) +\n        ' | ' +\n        this._formatPercentage(data.loaded / data.total) +\n        ' | ' +\n        this._formatFileSize(data.loaded) +\n        ' / ' +\n        this._formatFileSize(data.total)\n      );\n    },\n\n    _renderTemplate: function (func, files) {\n      if (!func) {\n        return $();\n      }\n      var result = func({\n        files: files,\n        formatFileSize: this._formatFileSize,\n        options: this.options\n      });\n      if (result instanceof $) {\n        return result;\n      }\n      return $(this.options.templatesContainer).html(result).children();\n    },\n\n    _renderPreviews: function (data) {\n      data.context.find('.preview').each(function (index, elm) {\n        $(elm).empty().append(data.files[index].preview);\n      });\n    },\n\n    _renderUpload: function (files) {\n      return this._renderTemplate(this.options.uploadTemplate, files);\n    },\n\n    _renderDownload: function (files) {\n      return this._renderTemplate(this.options.downloadTemplate, files)\n        .find('a[download]')\n        .each(this._enableDragToDesktop)\n        .end();\n    },\n\n    _editHandler: function (e) {\n      e.preventDefault();\n      if (!this.options.edit) return;\n      var that = this,\n        button = $(e.currentTarget),\n        template = button.closest('.template-upload'),\n        data = template.data('data'),\n        index = button.data().index;\n      this.options.edit(data.files[index]).then(function (file) {\n        if (!file) return;\n        data.files[index] = file;\n        data.context.addClass('processing');\n        template.find('.edit,.start').prop('disabled', true);\n        $(that.element)\n          .fileupload('process', data)\n          .always(function () {\n            template\n              .find('.size')\n              .text(that._formatFileSize(data.files[index].size));\n            data.context.removeClass('processing');\n            that._renderPreviews(data);\n          })\n          .done(function () {\n            template.find('.edit,.start').prop('disabled', false);\n          })\n          .fail(function () {\n            template.find('.edit').prop('disabled', false);\n            var error = data.files[index].error;\n            if (error) {\n              template.find('.error').text(error);\n            }\n          });\n      });\n    },\n\n    _startHandler: function (e) {\n      e.preventDefault();\n      var button = $(e.currentTarget),\n        template = button.closest('.template-upload'),\n        data = template.data('data');\n      button.prop('disabled', true);\n      if (data && data.submit) {\n        data.submit();\n      }\n    },\n\n    _cancelHandler: function (e) {\n      e.preventDefault();\n      var template = $(e.currentTarget).closest(\n          '.template-upload,.template-download'\n        ),\n        data = template.data('data') || {};\n      data.context = data.context || template;\n      if (data.abort) {\n        data.abort();\n      } else {\n        data.errorThrown = 'abort';\n        this._trigger('fail', e, data);\n      }\n    },\n\n    _deleteHandler: function (e) {\n      e.preventDefault();\n      var button = $(e.currentTarget);\n      this._trigger(\n        'destroy',\n        e,\n        $.extend(\n          {\n            context: button.closest('.template-download'),\n            type: 'DELETE'\n          },\n          button.data()\n        )\n      );\n    },\n\n    _forceReflow: function (node) {\n      return $.support.transition && node.length && node[0].offsetWidth;\n    },\n\n    _transition: function (node) {\n      // eslint-disable-next-line new-cap\n      var dfd = $.Deferred();\n      if (\n        $.support.transition &&\n        node.hasClass('fade') &&\n        node.is(':visible')\n      ) {\n        var transitionEndHandler = function (e) {\n          // Make sure we don't respond to other transition events\n          // in the container element, e.g. from button elements:\n          if (e.target === node[0]) {\n            node.off($.support.transition.end, transitionEndHandler);\n            dfd.resolveWith(node);\n          }\n        };\n        node\n          .on($.support.transition.end, transitionEndHandler)\n          .toggleClass(this.options.showElementClass);\n      } else {\n        node.toggleClass(this.options.showElementClass);\n        dfd.resolveWith(node);\n      }\n      return dfd;\n    },\n\n    _initButtonBarEventHandlers: function () {\n      var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),\n        filesList = this.options.filesContainer;\n      this._on(fileUploadButtonBar.find('.start'), {\n        click: function (e) {\n          e.preventDefault();\n          filesList.find('.start').trigger('click');\n        }\n      });\n      this._on(fileUploadButtonBar.find('.cancel'), {\n        click: function (e) {\n          e.preventDefault();\n          filesList.find('.cancel').trigger('click');\n        }\n      });\n      this._on(fileUploadButtonBar.find('.delete'), {\n        click: function (e) {\n          e.preventDefault();\n          filesList\n            .find('.toggle:checked')\n            .closest('.template-download')\n            .find('.delete')\n            .trigger('click');\n          fileUploadButtonBar.find('.toggle').prop('checked', false);\n        }\n      });\n      this._on(fileUploadButtonBar.find('.toggle'), {\n        change: function (e) {\n          filesList\n            .find('.toggle')\n            .prop('checked', $(e.currentTarget).is(':checked'));\n        }\n      });\n    },\n\n    _destroyButtonBarEventHandlers: function () {\n      this._off(\n        this.element\n          .find('.fileupload-buttonbar')\n          .find('.start, .cancel, .delete'),\n        'click'\n      );\n      this._off(this.element.find('.fileupload-buttonbar .toggle'), 'change.');\n    },\n\n    _initEventHandlers: function () {\n      this._super();\n      this._on(this.options.filesContainer, {\n        'click .edit': this._editHandler,\n        'click .start': this._startHandler,\n        'click .cancel': this._cancelHandler,\n        'click .delete': this._deleteHandler\n      });\n      this._initButtonBarEventHandlers();\n    },\n\n    _destroyEventHandlers: function () {\n      this._destroyButtonBarEventHandlers();\n      this._off(this.options.filesContainer, 'click');\n      this._super();\n    },\n\n    _enableFileInputButton: function () {\n      this.element\n        .find('.fileinput-button input')\n        .prop('disabled', false)\n        .parent()\n        .removeClass('disabled');\n    },\n\n    _disableFileInputButton: function () {\n      this.element\n        .find('.fileinput-button input')\n        .prop('disabled', true)\n        .parent()\n        .addClass('disabled');\n    },\n\n    _initTemplates: function () {\n      var options = this.options;\n      options.templatesContainer = this.document[0].createElement(\n        options.filesContainer.prop('nodeName')\n      );\n      if (tmpl) {\n        if (options.uploadTemplateId) {\n          options.uploadTemplate = tmpl(options.uploadTemplateId);\n        }\n        if (options.downloadTemplateId) {\n          options.downloadTemplate = tmpl(options.downloadTemplateId);\n        }\n      }\n    },\n\n    _initFilesContainer: function () {\n      var options = this.options;\n      if (options.filesContainer === undefined) {\n        options.filesContainer = this.element.find('.files');\n      } else if (!(options.filesContainer instanceof $)) {\n        options.filesContainer = $(options.filesContainer);\n      }\n    },\n\n    _initSpecialOptions: function () {\n      this._super();\n      this._initFilesContainer();\n      // this._initTemplates();\n    },\n\n    _create: function () {\n      this._super();\n      this._resetFinishedDeferreds();\n      if (!$.support.fileInput) {\n        this._disableFileInputButton();\n      }\n    },\n\n    enable: function () {\n      var wasDisabled = false;\n      if (this.options.disabled) {\n        wasDisabled = true;\n      }\n      this._super();\n      if (wasDisabled) {\n        this.element.find('input, button').prop('disabled', false);\n        this._enableFileInputButton();\n      }\n    },\n\n    disable: function () {\n      if (!this.options.disabled) {\n        this.element.find('input, button').prop('disabled', true);\n        this._disableFileInputButton();\n      }\n      this._super();\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/jquery.fileuploader.js":"/**\n * Custom Uploader\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      'jquery',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-image',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-video',\n      'Mageplaza_Core/lib/fileUploader/jquery.iframe-transport',\n    ], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(\n      require('jquery'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-image'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-video'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.iframe-transport')\n    );\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})();\n","Mageplaza_Core/lib/fileUploader/jquery.fileupload-image.js":"/*\n * jQuery File Upload Image Preview & Resize Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define([\n      'jquery',\n      'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image',\n      'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta',\n      'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale',\n      'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif',\n      'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-orientation',\n      'Mageplaza_Core/lib/fileUploader/vendor/blueimp-canvas-to-blob/js/canvas-to-blob',\n      'Mageplaza_Core/lib/fileUploader/jquery.fileupload-process'\n    ], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(\n      require('jquery'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-orientation'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-canvas-to-blob/js/canvas-to-blob'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-process')\n    );\n  } else {\n    // Browser globals:\n    factory(window.jQuery, window.loadImage);\n  }\n})(function ($, loadImage) {\n  'use strict';\n\n  // Prepend to the default processQueue:\n  $.blueimp.fileupload.prototype.options.processQueue.unshift(\n    {\n      action: 'loadImageMetaData',\n      maxMetaDataSize: '@',\n      disableImageHead: '@',\n      disableMetaDataParsers: '@',\n      disableExif: '@',\n      disableExifOffsets: '@',\n      includeExifTags: '@',\n      excludeExifTags: '@',\n      disableIptc: '@',\n      disableIptcOffsets: '@',\n      includeIptcTags: '@',\n      excludeIptcTags: '@',\n      disabled: '@disableImageMetaDataLoad'\n    },\n    {\n      action: 'loadImage',\n      // Use the action as prefix for the \"@\" options:\n      prefix: true,\n      fileTypes: '@',\n      maxFileSize: '@',\n      noRevoke: '@',\n      disabled: '@disableImageLoad'\n    },\n    {\n      action: 'resizeImage',\n      // Use \"image\" as prefix for the \"@\" options:\n      prefix: 'image',\n      maxWidth: '@',\n      maxHeight: '@',\n      minWidth: '@',\n      minHeight: '@',\n      crop: '@',\n      orientation: '@',\n      forceResize: '@',\n      disabled: '@disableImageResize'\n    },\n    {\n      action: 'saveImage',\n      quality: '@imageQuality',\n      type: '@imageType',\n      disabled: '@disableImageResize'\n    },\n    {\n      action: 'saveImageMetaData',\n      disabled: '@disableImageMetaDataSave'\n    },\n    {\n      action: 'resizeImage',\n      // Use \"preview\" as prefix for the \"@\" options:\n      prefix: 'preview',\n      maxWidth: '@',\n      maxHeight: '@',\n      minWidth: '@',\n      minHeight: '@',\n      crop: '@',\n      orientation: '@',\n      thumbnail: '@',\n      canvas: '@',\n      disabled: '@disableImagePreview'\n    },\n    {\n      action: 'setImage',\n      name: '@imagePreviewName',\n      disabled: '@disableImagePreview'\n    },\n    {\n      action: 'deleteImageReferences',\n      disabled: '@disableImageReferencesDeletion'\n    }\n  );\n\n  // The File Upload Resize plugin extends the fileupload widget\n  // with image resize functionality:\n  $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n    options: {\n      // The regular expression for the types of images to load:\n      // matched against the file type:\n      loadImageFileTypes: /^image\\/(gif|jpeg|png|svg\\+xml)$/,\n      // The maximum file size of images to load:\n      loadImageMaxFileSize: 10000000, // 10MB\n      // The maximum width of resized images:\n      imageMaxWidth: 1920,\n      // The maximum height of resized images:\n      imageMaxHeight: 1080,\n      // Defines the image orientation (1-8) or takes the orientation\n      // value from Exif data if set to true:\n      imageOrientation: true,\n      // Define if resized images should be cropped or only scaled:\n      imageCrop: false,\n      // Disable the resize image functionality by default:\n      disableImageResize: true,\n      // The maximum width of the preview images:\n      previewMaxWidth: 80,\n      // The maximum height of the preview images:\n      previewMaxHeight: 80,\n      // Defines the preview orientation (1-8) or takes the orientation\n      // value from Exif data if set to true:\n      previewOrientation: true,\n      // Create the preview using the Exif data thumbnail:\n      previewThumbnail: true,\n      // Define if preview images should be cropped or only scaled:\n      previewCrop: false,\n      // Define if preview images should be resized as canvas elements:\n      previewCanvas: true\n    },\n\n    processActions: {\n      // Loads the image given via data.files and data.index\n      // as img element, if the browser supports the File API.\n      // Accepts the options fileTypes (regular expression)\n      // and maxFileSize (integer) to limit the files to load:\n      loadImage: function (data, options) {\n        if (options.disabled) {\n          return data;\n        }\n        var that = this,\n          file = data.files[data.index],\n          // eslint-disable-next-line new-cap\n          dfd = $.Deferred();\n        if (\n          ($.type(options.maxFileSize) === 'number' &&\n            file.size > options.maxFileSize) ||\n          (options.fileTypes && !options.fileTypes.test(file.type)) ||\n          !loadImage(\n            file,\n            function (img) {\n              if (img.src) {\n                data.img = img;\n              }\n              dfd.resolveWith(that, [data]);\n            },\n            options\n          )\n        ) {\n          return data;\n        }\n        return dfd.promise();\n      },\n\n      // Resizes the image given as data.canvas or data.img\n      // and updates data.canvas or data.img with the resized image.\n      // Also stores the resized image as preview property.\n      // Accepts the options maxWidth, maxHeight, minWidth,\n      // minHeight, canvas and crop:\n      resizeImage: function (data, options) {\n        if (options.disabled || !(data.canvas || data.img)) {\n          return data;\n        }\n        // eslint-disable-next-line no-param-reassign\n        options = $.extend({ canvas: true }, options);\n        var that = this,\n          // eslint-disable-next-line new-cap\n          dfd = $.Deferred(),\n          img = (options.canvas && data.canvas) || data.img,\n          resolve = function (newImg) {\n            if (\n              newImg &&\n              (newImg.width !== img.width ||\n                newImg.height !== img.height ||\n                options.forceResize)\n            ) {\n              data[newImg.getContext ? 'canvas' : 'img'] = newImg;\n            }\n            data.preview = newImg;\n            dfd.resolveWith(that, [data]);\n          },\n          thumbnail,\n          thumbnailBlob;\n        if (data.exif && options.thumbnail) {\n          thumbnail = data.exif.get('Thumbnail');\n          thumbnailBlob = thumbnail && thumbnail.get('Blob');\n          if (thumbnailBlob) {\n            options.orientation = data.exif.get('Orientation');\n            loadImage(thumbnailBlob, resolve, options);\n            return dfd.promise();\n          }\n        }\n        if (data.orientation) {\n          // Prevent orienting the same image twice:\n          delete options.orientation;\n        } else {\n          data.orientation = options.orientation || loadImage.orientation;\n        }\n        if (img) {\n          resolve(loadImage.scale(img, options, data));\n          return dfd.promise();\n        }\n        return data;\n      },\n\n      // Saves the processed image given as data.canvas\n      // inplace at data.index of data.files:\n      saveImage: function (data, options) {\n        if (!data.canvas || options.disabled) {\n          return data;\n        }\n        var that = this,\n          file = data.files[data.index],\n          // eslint-disable-next-line new-cap\n          dfd = $.Deferred();\n        if (data.canvas.toBlob) {\n          data.canvas.toBlob(\n            function (blob) {\n              if (!blob.name) {\n                if (file.type === blob.type) {\n                  blob.name = file.name;\n                } else if (file.name) {\n                  blob.name = file.name.replace(\n                    /\\.\\w+$/,\n                    '.' + blob.type.substr(6)\n                  );\n                }\n              }\n              // Don't restore invalid meta data:\n              if (file.type !== blob.type) {\n                delete data.imageHead;\n              }\n              // Store the created blob at the position\n              // of the original file in the files list:\n              data.files[data.index] = blob;\n              dfd.resolveWith(that, [data]);\n            },\n            options.type || file.type,\n            options.quality\n          );\n        } else {\n          return data;\n        }\n        return dfd.promise();\n      },\n\n      loadImageMetaData: function (data, options) {\n        if (options.disabled) {\n          return data;\n        }\n        var that = this,\n          // eslint-disable-next-line new-cap\n          dfd = $.Deferred();\n        loadImage.parseMetaData(\n          data.files[data.index],\n          function (result) {\n            $.extend(data, result);\n            dfd.resolveWith(that, [data]);\n          },\n          options\n        );\n        return dfd.promise();\n      },\n\n      saveImageMetaData: function (data, options) {\n        if (\n          !(\n            data.imageHead &&\n            data.canvas &&\n            data.canvas.toBlob &&\n            !options.disabled\n          )\n        ) {\n          return data;\n        }\n        var that = this,\n          file = data.files[data.index],\n          // eslint-disable-next-line new-cap\n          dfd = $.Deferred();\n        if (data.orientation === true && data.exifOffsets) {\n          // Reset Exif Orientation data:\n          loadImage.writeExifData(data.imageHead, data, 'Orientation', 1);\n        }\n        loadImage.replaceHead(file, data.imageHead, function (blob) {\n          blob.name = file.name;\n          data.files[data.index] = blob;\n          dfd.resolveWith(that, [data]);\n        });\n        return dfd.promise();\n      },\n\n      // Sets the resized version of the image as a property of the\n      // file object, must be called after \"saveImage\":\n      setImage: function (data, options) {\n        if (data.preview && !options.disabled) {\n          data.files[data.index][options.name || 'preview'] = data.preview;\n        }\n        return data;\n      },\n\n      deleteImageReferences: function (data, options) {\n        if (!options.disabled) {\n          delete data.img;\n          delete data.canvas;\n          delete data.preview;\n          delete data.imageHead;\n        }\n        return data;\n      }\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/jquery.fileupload-audio.js":"/*\n * jQuery File Upload Audio Preview Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/jquery.fileupload-process'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(\n      require('jquery'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'),\n      require('Mageplaza_Core/lib/fileUploader/jquery.fileupload-process')\n    );\n  } else {\n    // Browser globals:\n    factory(window.jQuery, window.loadImage);\n  }\n})(function ($, loadImage) {\n  'use strict';\n\n  // Prepend to the default processQueue:\n  $.blueimp.fileupload.prototype.options.processQueue.unshift(\n    {\n      action: 'loadAudio',\n      // Use the action as prefix for the \"@\" options:\n      prefix: true,\n      fileTypes: '@',\n      maxFileSize: '@',\n      disabled: '@disableAudioPreview'\n    },\n    {\n      action: 'setAudio',\n      name: '@audioPreviewName',\n      disabled: '@disableAudioPreview'\n    }\n  );\n\n  // The File Upload Audio Preview plugin extends the fileupload widget\n  // with audio preview functionality:\n  $.widget('blueimp.fileupload', $.blueimp.fileupload, {\n    options: {\n      // The regular expression for the types of audio files to load,\n      // matched against the file type:\n      loadAudioFileTypes: /^audio\\/.*$/\n    },\n\n    _audioElement: document.createElement('audio'),\n\n    processActions: {\n      // Loads the audio file given via data.files and data.index\n      // as audio element if the browser supports playing it.\n      // Accepts the options fileTypes (regular expression)\n      // and maxFileSize (integer) to limit the files to load:\n      loadAudio: function (data, options) {\n        if (options.disabled) {\n          return data;\n        }\n        var file = data.files[data.index],\n          url,\n          audio;\n        if (\n          this._audioElement.canPlayType &&\n          this._audioElement.canPlayType(file.type) &&\n          ($.type(options.maxFileSize) !== 'number' ||\n            file.size <= options.maxFileSize) &&\n          (!options.fileTypes || options.fileTypes.test(file.type))\n        ) {\n          url = loadImage.createObjectURL(file);\n          if (url) {\n            audio = this._audioElement.cloneNode(false);\n            audio.src = url;\n            audio.controls = true;\n            data.audio = audio;\n            return data;\n          }\n        }\n        return data;\n      },\n\n      // Sets the audio element as a property of the file object:\n      setAudio: function (data, options) {\n        if (data.audio && !options.disabled) {\n          data.files[data.index][options.name || 'preview'] = data.audio;\n        }\n        return data;\n      }\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/vendor/jquery.ui.widget.js":"/*! jQuery UI - v1.12.1+0b7246b6eeadfa9e2696e22f3230f6452f8129dc - 2020-02-20\n * http://jqueryui.com\n * Includes: widget.js\n * Copyright jQuery Foundation and other contributors; Licensed MIT */\n\n/* global define, require */\n/* eslint-disable no-param-reassign, new-cap, jsdoc/require-jsdoc */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS\n    factory(require('jquery'));\n  } else {\n    // Browser globals\n    factory(window.jQuery);\n  }\n})(function ($) {\n  ('use strict');\n\n  $.ui = $.ui || {};\n\n  $.ui.version = '1.12.1';\n\n  /*!\n   * jQuery UI Widget 1.12.1\n   * http://jqueryui.com\n   *\n   * Copyright jQuery Foundation and other contributors\n   * Released under the MIT license.\n   * http://jquery.org/license\n   */\n\n  //>>label: Widget\n  //>>group: Core\n  //>>description: Provides a factory for creating stateful widgets with a common API.\n  //>>docs: http://api.jqueryui.com/jQuery.widget/\n  //>>demos: http://jqueryui.com/widget/\n\n  // Support: jQuery 1.9.x or older\n  // $.expr[ \":\" ] is deprecated.\n  if (!$.expr.pseudos) {\n    $.expr.pseudos = $.expr[':'];\n  }\n\n  // Support: jQuery 1.11.x or older\n  // $.unique has been renamed to $.uniqueSort\n  if (!$.uniqueSort) {\n    $.uniqueSort = $.unique;\n  }\n\n  var widgetUuid = 0;\n  var widgetHasOwnProperty = Array.prototype.hasOwnProperty;\n  var widgetSlice = Array.prototype.slice;\n\n  $.cleanData = (function (orig) {\n    return function (elems) {\n      var events, elem, i;\n      // eslint-disable-next-line eqeqeq\n      for (i = 0; (elem = elems[i]) != null; i++) {\n        // Only trigger remove when necessary to save time\n        events = $._data(elem, 'events');\n        if (events && events.remove) {\n          $(elem).triggerHandler('remove');\n        }\n      }\n      orig(elems);\n    };\n  })($.cleanData);\n\n  $.widget = function (name, base, prototype) {\n    var existingConstructor, constructor, basePrototype;\n\n    // ProxiedPrototype allows the provided prototype to remain unmodified\n    // so that it can be used as a mixin for multiple widgets (#8876)\n    var proxiedPrototype = {};\n\n    var namespace = name.split('.')[0];\n    name = name.split('.')[1];\n    var fullName = namespace + '-' + name;\n\n    if (!prototype) {\n      prototype = base;\n      base = $.Widget;\n    }\n\n    if ($.isArray(prototype)) {\n      prototype = $.extend.apply(null, [{}].concat(prototype));\n    }\n\n    // Create selector for plugin\n    $.expr.pseudos[fullName.toLowerCase()] = function (elem) {\n      return !!$.data(elem, fullName);\n    };\n\n    $[namespace] = $[namespace] || {};\n    existingConstructor = $[namespace][name];\n    constructor = $[namespace][name] = function (options, element) {\n      // Allow instantiation without \"new\" keyword\n      if (!this._createWidget) {\n        return new constructor(options, element);\n      }\n\n      // Allow instantiation without initializing for simple inheritance\n      // must use \"new\" keyword (the code above always passes args)\n      if (arguments.length) {\n        this._createWidget(options, element);\n      }\n    };\n\n    // Extend with the existing constructor to carry over any static properties\n    $.extend(constructor, existingConstructor, {\n      version: prototype.version,\n\n      // Copy the object used to create the prototype in case we need to\n      // redefine the widget later\n      _proto: $.extend({}, prototype),\n\n      // Track widgets that inherit from this widget in case this widget is\n      // redefined after a widget inherits from it\n      _childConstructors: []\n    });\n\n    basePrototype = new base();\n\n    // We need to make the options hash a property directly on the new instance\n    // otherwise we'll modify the options hash on the prototype that we're\n    // inheriting from\n    basePrototype.options = $.widget.extend({}, basePrototype.options);\n    $.each(prototype, function (prop, value) {\n      if (!$.isFunction(value)) {\n        proxiedPrototype[prop] = value;\n        return;\n      }\n      proxiedPrototype[prop] = (function () {\n        function _super() {\n          return base.prototype[prop].apply(this, arguments);\n        }\n\n        function _superApply(args) {\n          return base.prototype[prop].apply(this, args);\n        }\n\n        return function () {\n          var __super = this._super;\n          var __superApply = this._superApply;\n          var returnValue;\n\n          this._super = _super;\n          this._superApply = _superApply;\n\n          returnValue = value.apply(this, arguments);\n\n          this._super = __super;\n          this._superApply = __superApply;\n\n          return returnValue;\n        };\n      })();\n    });\n    constructor.prototype = $.widget.extend(\n      basePrototype,\n      {\n        // TODO: remove support for widgetEventPrefix\n        // always use the name + a colon as the prefix, e.g., draggable:start\n        // don't prefix for widgets that aren't DOM-based\n        widgetEventPrefix: existingConstructor\n          ? basePrototype.widgetEventPrefix || name\n          : name\n      },\n      proxiedPrototype,\n      {\n        constructor: constructor,\n        namespace: namespace,\n        widgetName: name,\n        widgetFullName: fullName\n      }\n    );\n\n    // If this widget is being redefined then we need to find all widgets that\n    // are inheriting from it and redefine all of them so that they inherit from\n    // the new version of this widget. We're essentially trying to replace one\n    // level in the prototype chain.\n    if (existingConstructor) {\n      $.each(existingConstructor._childConstructors, function (i, child) {\n        var childPrototype = child.prototype;\n\n        // Redefine the child widget using the same prototype that was\n        // originally used, but inherit from the new version of the base\n        $.widget(\n          childPrototype.namespace + '.' + childPrototype.widgetName,\n          constructor,\n          child._proto\n        );\n      });\n\n      // Remove the list of existing child constructors from the old constructor\n      // so the old child constructors can be garbage collected\n      delete existingConstructor._childConstructors;\n    } else {\n      base._childConstructors.push(constructor);\n    }\n\n    $.widget.bridge(name, constructor);\n\n    return constructor;\n  };\n\n  $.widget.extend = function (target) {\n    var input = widgetSlice.call(arguments, 1);\n    var inputIndex = 0;\n    var inputLength = input.length;\n    var key;\n    var value;\n\n    for (; inputIndex < inputLength; inputIndex++) {\n      for (key in input[inputIndex]) {\n        value = input[inputIndex][key];\n        if (\n          widgetHasOwnProperty.call(input[inputIndex], key) &&\n          value !== undefined\n        ) {\n          // Clone objects\n          if ($.isPlainObject(value)) {\n            target[key] = $.isPlainObject(target[key])\n              ? $.widget.extend({}, target[key], value)\n              : // Don't extend strings, arrays, etc. with objects\n                $.widget.extend({}, value);\n\n            // Copy everything else by reference\n          } else {\n            target[key] = value;\n          }\n        }\n      }\n    }\n    return target;\n  };\n\n  $.widget.bridge = function (name, object) {\n    var fullName = object.prototype.widgetFullName || name;\n    $.fn[name] = function (options) {\n      var isMethodCall = typeof options === 'string';\n      var args = widgetSlice.call(arguments, 1);\n      var returnValue = this;\n\n      if (isMethodCall) {\n        // If this is an empty collection, we need to have the instance method\n        // return undefined instead of the jQuery instance\n        if (!this.length && options === 'instance') {\n          returnValue = undefined;\n        } else {\n          this.each(function () {\n            var methodValue;\n            var instance = $.data(this, fullName);\n\n            if (options === 'instance') {\n              returnValue = instance;\n              return false;\n            }\n\n            if (!instance) {\n              return $.error(\n                'cannot call methods on ' +\n                  name +\n                  ' prior to initialization; ' +\n                  \"attempted to call method '\" +\n                  options +\n                  \"'\"\n              );\n            }\n\n            if (!$.isFunction(instance[options]) || options.charAt(0) === '_') {\n              return $.error(\n                \"no such method '\" +\n                  options +\n                  \"' for \" +\n                  name +\n                  ' widget instance'\n              );\n            }\n\n            methodValue = instance[options].apply(instance, args);\n\n            if (methodValue !== instance && methodValue !== undefined) {\n              returnValue =\n                methodValue && methodValue.jquery\n                  ? returnValue.pushStack(methodValue.get())\n                  : methodValue;\n              return false;\n            }\n          });\n        }\n      } else {\n        // Allow multiple hashes to be passed on init\n        if (args.length) {\n          options = $.widget.extend.apply(null, [options].concat(args));\n        }\n\n        this.each(function () {\n          var instance = $.data(this, fullName);\n          if (instance) {\n            instance.option(options || {});\n            if (instance._init) {\n              instance._init();\n            }\n          } else {\n            $.data(this, fullName, new object(options, this));\n          }\n        });\n      }\n\n      return returnValue;\n    };\n  };\n\n  $.Widget = function (/* options, element */) {};\n  $.Widget._childConstructors = [];\n\n  $.Widget.prototype = {\n    widgetName: 'widget',\n    widgetEventPrefix: '',\n    defaultElement: '<div>',\n\n    options: {\n      classes: {},\n      disabled: false,\n\n      // Callbacks\n      create: null\n    },\n\n    _createWidget: function (options, element) {\n      element = $(element || this.defaultElement || this)[0];\n      this.element = $(element);\n      this.uuid = widgetUuid++;\n      this.eventNamespace = '.' + this.widgetName + this.uuid;\n\n      this.bindings = $();\n      this.hoverable = $();\n      this.focusable = $();\n      this.classesElementLookup = {};\n\n      if (element !== this) {\n        $.data(element, this.widgetFullName, this);\n        this._on(true, this.element, {\n          remove: function (event) {\n            if (event.target === element) {\n              this.destroy();\n            }\n          }\n        });\n        this.document = $(\n          element.style\n            ? // Element within the document\n              element.ownerDocument\n            : // Element is window or document\n              element.document || element\n        );\n        this.window = $(\n          this.document[0].defaultView || this.document[0].parentWindow\n        );\n      }\n\n      this.options = $.widget.extend(\n        {},\n        this.options,\n        this._getCreateOptions(),\n        options\n      );\n\n      this._create();\n\n      if (this.options.disabled) {\n        this._setOptionDisabled(this.options.disabled);\n      }\n\n      this._trigger('create', null, this._getCreateEventData());\n      this._init();\n    },\n\n    _getCreateOptions: function () {\n      return {};\n    },\n\n    _getCreateEventData: $.noop,\n\n    _create: $.noop,\n\n    _init: $.noop,\n\n    destroy: function () {\n      var that = this;\n\n      this._destroy();\n      $.each(this.classesElementLookup, function (key, value) {\n        that._removeClass(value, key);\n      });\n\n      // We can probably remove the unbind calls in 2.0\n      // all event bindings should go through this._on()\n      this.element.off(this.eventNamespace).removeData(this.widgetFullName);\n      this.widget().off(this.eventNamespace).removeAttr('aria-disabled');\n\n      // Clean up events and states\n      this.bindings.off(this.eventNamespace);\n    },\n\n    _destroy: $.noop,\n\n    widget: function () {\n      return this.element;\n    },\n\n    option: function (key, value) {\n      var options = key;\n      var parts;\n      var curOption;\n      var i;\n\n      if (arguments.length === 0) {\n        // Don't return a reference to the internal hash\n        return $.widget.extend({}, this.options);\n      }\n\n      if (typeof key === 'string') {\n        // Handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n        options = {};\n        parts = key.split('.');\n        key = parts.shift();\n        if (parts.length) {\n          curOption = options[key] = $.widget.extend({}, this.options[key]);\n          for (i = 0; i < parts.length - 1; i++) {\n            curOption[parts[i]] = curOption[parts[i]] || {};\n            curOption = curOption[parts[i]];\n          }\n          key = parts.pop();\n          if (arguments.length === 1) {\n            return curOption[key] === undefined ? null : curOption[key];\n          }\n          curOption[key] = value;\n        } else {\n          if (arguments.length === 1) {\n            return this.options[key] === undefined ? null : this.options[key];\n          }\n          options[key] = value;\n        }\n      }\n\n      this._setOptions(options);\n\n      return this;\n    },\n\n    _setOptions: function (options) {\n      var key;\n\n      for (key in options) {\n        this._setOption(key, options[key]);\n      }\n\n      return this;\n    },\n\n    _setOption: function (key, value) {\n      if (key === 'classes') {\n        this._setOptionClasses(value);\n      }\n\n      this.options[key] = value;\n\n      if (key === 'disabled') {\n        this._setOptionDisabled(value);\n      }\n\n      return this;\n    },\n\n    _setOptionClasses: function (value) {\n      var classKey, elements, currentElements;\n\n      for (classKey in value) {\n        currentElements = this.classesElementLookup[classKey];\n        if (\n          value[classKey] === this.options.classes[classKey] ||\n          !currentElements ||\n          !currentElements.length\n        ) {\n          continue;\n        }\n\n        // We are doing this to create a new jQuery object because the _removeClass() call\n        // on the next line is going to destroy the reference to the current elements being\n        // tracked. We need to save a copy of this collection so that we can add the new classes\n        // below.\n        elements = $(currentElements.get());\n        this._removeClass(currentElements, classKey);\n\n        // We don't use _addClass() here, because that uses this.options.classes\n        // for generating the string of classes. We want to use the value passed in from\n        // _setOption(), this is the new value of the classes option which was passed to\n        // _setOption(). We pass this value directly to _classes().\n        elements.addClass(\n          this._classes({\n            element: elements,\n            keys: classKey,\n            classes: value,\n            add: true\n          })\n        );\n      }\n    },\n\n    _setOptionDisabled: function (value) {\n      this._toggleClass(\n        this.widget(),\n        this.widgetFullName + '-disabled',\n        null,\n        !!value\n      );\n\n      // If the widget is becoming disabled, then nothing is interactive\n      if (value) {\n        this._removeClass(this.hoverable, null, 'ui-state-hover');\n        this._removeClass(this.focusable, null, 'ui-state-focus');\n      }\n    },\n\n    enable: function () {\n      return this._setOptions({ disabled: false });\n    },\n\n    disable: function () {\n      return this._setOptions({ disabled: true });\n    },\n\n    _classes: function (options) {\n      var full = [];\n      var that = this;\n\n      options = $.extend(\n        {\n          element: this.element,\n          classes: this.options.classes || {}\n        },\n        options\n      );\n\n      function bindRemoveEvent() {\n        options.element.each(function (_, element) {\n          var isTracked = $.map(that.classesElementLookup, function (elements) {\n            return elements;\n          }).some(function (elements) {\n            return elements.is(element);\n          });\n\n          if (!isTracked) {\n            that._on($(element), {\n              remove: '_untrackClassesElement'\n            });\n          }\n        });\n      }\n\n      function processClassString(classes, checkOption) {\n        var current, i;\n        for (i = 0; i < classes.length; i++) {\n          current = that.classesElementLookup[classes[i]] || $();\n          if (options.add) {\n            bindRemoveEvent();\n            current = $(\n              $.uniqueSort(current.get().concat(options.element.get()))\n            );\n          } else {\n            current = $(current.not(options.element).get());\n          }\n          that.classesElementLookup[classes[i]] = current;\n          full.push(classes[i]);\n          if (checkOption && options.classes[classes[i]]) {\n            full.push(options.classes[classes[i]]);\n          }\n        }\n      }\n\n      if (options.keys) {\n        processClassString(options.keys.match(/\\S+/g) || [], true);\n      }\n      if (options.extra) {\n        processClassString(options.extra.match(/\\S+/g) || []);\n      }\n\n      return full.join(' ');\n    },\n\n    _untrackClassesElement: function (event) {\n      var that = this;\n      $.each(that.classesElementLookup, function (key, value) {\n        if ($.inArray(event.target, value) !== -1) {\n          that.classesElementLookup[key] = $(value.not(event.target).get());\n        }\n      });\n\n      this._off($(event.target));\n    },\n\n    _removeClass: function (element, keys, extra) {\n      return this._toggleClass(element, keys, extra, false);\n    },\n\n    _addClass: function (element, keys, extra) {\n      return this._toggleClass(element, keys, extra, true);\n    },\n\n    _toggleClass: function (element, keys, extra, add) {\n      add = typeof add === 'boolean' ? add : extra;\n      var shift = typeof element === 'string' || element === null,\n        options = {\n          extra: shift ? keys : extra,\n          keys: shift ? element : keys,\n          element: shift ? this.element : element,\n          add: add\n        };\n      options.element.toggleClass(this._classes(options), add);\n      return this;\n    },\n\n    _on: function (suppressDisabledCheck, element, handlers) {\n      var delegateElement;\n      var instance = this;\n\n      // No suppressDisabledCheck flag, shuffle arguments\n      if (typeof suppressDisabledCheck !== 'boolean') {\n        handlers = element;\n        element = suppressDisabledCheck;\n        suppressDisabledCheck = false;\n      }\n\n      // No element argument, shuffle and use this.element\n      if (!handlers) {\n        handlers = element;\n        element = this.element;\n        delegateElement = this.widget();\n      } else {\n        element = delegateElement = $(element);\n        this.bindings = this.bindings.add(element);\n      }\n\n      $.each(handlers, function (event, handler) {\n        function handlerProxy() {\n          // Allow widgets to customize the disabled handling\n          // - disabled as an array instead of boolean\n          // - disabled class as method for disabling individual parts\n          if (\n            !suppressDisabledCheck &&\n            (instance.options.disabled === true ||\n              $(this).hasClass('ui-state-disabled'))\n          ) {\n            return;\n          }\n          return (\n            typeof handler === 'string' ? instance[handler] : handler\n          ).apply(instance, arguments);\n        }\n\n        // Copy the guid so direct unbinding works\n        if (typeof handler !== 'string') {\n          handlerProxy.guid = handler.guid =\n            handler.guid || handlerProxy.guid || $.guid++;\n        }\n\n        var match = event.match(/^([\\w:-]*)\\s*(.*)$/);\n        var eventName = match[1] + instance.eventNamespace;\n        var selector = match[2];\n\n        if (selector) {\n          delegateElement.on(eventName, selector, handlerProxy);\n        } else {\n          element.on(eventName, handlerProxy);\n        }\n      });\n    },\n\n    _off: function (element, eventName) {\n      eventName =\n        (eventName || '').split(' ').join(this.eventNamespace + ' ') +\n        this.eventNamespace;\n      element.off(eventName);\n\n      // Clear the stack to avoid memory leaks (#10056)\n      this.bindings = $(this.bindings.not(element).get());\n      this.focusable = $(this.focusable.not(element).get());\n      this.hoverable = $(this.hoverable.not(element).get());\n    },\n\n    _delay: function (handler, delay) {\n      var instance = this;\n      function handlerProxy() {\n        return (\n          typeof handler === 'string' ? instance[handler] : handler\n        ).apply(instance, arguments);\n      }\n      return setTimeout(handlerProxy, delay || 0);\n    },\n\n    _hoverable: function (element) {\n      this.hoverable = this.hoverable.add(element);\n      this._on(element, {\n        mouseenter: function (event) {\n          this._addClass($(event.currentTarget), null, 'ui-state-hover');\n        },\n        mouseleave: function (event) {\n          this._removeClass($(event.currentTarget), null, 'ui-state-hover');\n        }\n      });\n    },\n\n    _focusable: function (element) {\n      this.focusable = this.focusable.add(element);\n      this._on(element, {\n        focusin: function (event) {\n          this._addClass($(event.currentTarget), null, 'ui-state-focus');\n        },\n        focusout: function (event) {\n          this._removeClass($(event.currentTarget), null, 'ui-state-focus');\n        }\n      });\n    },\n\n    _trigger: function (type, event, data) {\n      var prop, orig;\n      var callback = this.options[type];\n\n      data = data || {};\n      event = $.Event(event);\n      event.type = (\n        type === this.widgetEventPrefix ? type : this.widgetEventPrefix + type\n      ).toLowerCase();\n\n      // The original event may come from any element\n      // so we need to reset the target on the new event\n      event.target = this.element[0];\n\n      // Copy original event properties over to the new event\n      orig = event.originalEvent;\n      if (orig) {\n        for (prop in orig) {\n          if (!(prop in event)) {\n            event[prop] = orig[prop];\n          }\n        }\n      }\n\n      this.element.trigger(event, data);\n      return !(\n        ($.isFunction(callback) &&\n          callback.apply(this.element[0], [event].concat(data)) === false) ||\n        event.isDefaultPrevented()\n      );\n    }\n  };\n\n  $.each({ show: 'fadeIn', hide: 'fadeOut' }, function (method, defaultEffect) {\n    $.Widget.prototype['_' + method] = function (element, options, callback) {\n      if (typeof options === 'string') {\n        options = { effect: options };\n      }\n\n      var hasOptions;\n      var effectName = !options\n        ? method\n        : options === true || typeof options === 'number'\n        ? defaultEffect\n        : options.effect || defaultEffect;\n\n      options = options || {};\n      if (typeof options === 'number') {\n        options = { duration: options };\n      }\n\n      hasOptions = !$.isEmptyObject(options);\n      options.complete = callback;\n\n      if (options.delay) {\n        element.delay(options.delay);\n      }\n\n      if (hasOptions && $.effects && $.effects.effect[effectName]) {\n        element[method](options);\n      } else if (effectName !== method && element[effectName]) {\n        element[effectName](options.duration, options.easing, callback);\n      } else {\n        element.queue(function (next) {\n          $(this)[method]();\n          if (callback) {\n            callback.call(element[0]);\n          }\n          next();\n        });\n      }\n    };\n  });\n});\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc.js":"/*\n * JavaScript Load Image IPTC Parser\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * Copyright 2018, Dave Bevan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require, DataView */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'), require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  /**\n   * IPTC tag map\n   *\n   * @name IptcMap\n   * @class\n   */\n  function IptcMap() {}\n\n  IptcMap.prototype.map = {\n    ObjectName: 5\n  }\n\n  IptcMap.prototype.types = {\n    0: 'Uint16', // ApplicationRecordVersion\n    200: 'Uint16', // ObjectPreviewFileFormat\n    201: 'Uint16', // ObjectPreviewFileVersion\n    202: 'binary' // ObjectPreviewData\n  }\n\n  /**\n   * Retrieves IPTC tag value\n   *\n   * @param {number|string} id IPTC tag code or name\n   * @returns {object} IPTC tag value\n   */\n  IptcMap.prototype.get = function (id) {\n    return this[id] || this[this.map[id]]\n  }\n\n  /**\n   * Retrieves string for the given DataView and range\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Offset start\n   * @param {number} length Offset length\n   * @returns {string} String value\n   */\n  function getStringValue(dataView, offset, length) {\n    var outstr = ''\n    var end = offset + length\n    for (var n = offset; n < end; n += 1) {\n      outstr += String.fromCharCode(dataView.getUint8(n))\n    }\n    return outstr\n  }\n\n  /**\n   * Retrieves tag value for the given DataView and range\n   *\n   * @param {number} tagCode tag code\n   * @param {IptcMap} map IPTC tag map\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Range start\n   * @param {number} length Range length\n   * @returns {object} Tag value\n   */\n  function getTagValue(tagCode, map, dataView, offset, length) {\n    if (map.types[tagCode] === 'binary') {\n      return new Blob([dataView.buffer.slice(offset, offset + length)])\n    }\n    if (map.types[tagCode] === 'Uint16') {\n      return dataView.getUint16(offset)\n    }\n    return getStringValue(dataView, offset, length)\n  }\n\n  /**\n   * Combines IPTC value with existing ones.\n   *\n   * @param {object} value Existing IPTC field value\n   * @param {object} newValue New IPTC field value\n   * @returns {object} Resulting IPTC field value\n   */\n  function combineTagValues(value, newValue) {\n    if (value === undefined) return newValue\n    if (value instanceof Array) {\n      value.push(newValue)\n      return value\n    }\n    return [value, newValue]\n  }\n\n  /**\n   * Parses IPTC tags.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} segmentOffset Segment offset\n   * @param {number} segmentLength Segment length\n   * @param {object} data Data export object\n   * @param {object} includeTags Map of tags to include\n   * @param {object} excludeTags Map of tags to exclude\n   */\n  function parseIptcTags(\n    dataView,\n    segmentOffset,\n    segmentLength,\n    data,\n    includeTags,\n    excludeTags\n  ) {\n    var value, tagSize, tagCode\n    var segmentEnd = segmentOffset + segmentLength\n    var offset = segmentOffset\n    while (offset < segmentEnd) {\n      if (\n        dataView.getUint8(offset) === 0x1c && // tag marker\n        dataView.getUint8(offset + 1) === 0x02 // record number, only handles v2\n      ) {\n        tagCode = dataView.getUint8(offset + 2)\n        if (\n          (!includeTags || includeTags[tagCode]) &&\n          (!excludeTags || !excludeTags[tagCode])\n        ) {\n          tagSize = dataView.getInt16(offset + 3)\n          value = getTagValue(tagCode, data.iptc, dataView, offset + 5, tagSize)\n          data.iptc[tagCode] = combineTagValues(data.iptc[tagCode], value)\n          if (data.iptcOffsets) {\n            data.iptcOffsets[tagCode] = offset\n          }\n        }\n      }\n      offset += 1\n    }\n  }\n\n  /**\n   * Tests if field segment starts at offset.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Segment offset\n   * @returns {boolean} True if '8BIM<EOT><EOT>' exists at offset\n   */\n  function isSegmentStart(dataView, offset) {\n    return (\n      dataView.getUint32(offset) === 0x3842494d && // Photoshop segment start\n      dataView.getUint16(offset + 4) === 0x0404 // IPTC segment start\n    )\n  }\n\n  /**\n   * Returns header length.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Segment offset\n   * @returns {number} Header length\n   */\n  function getHeaderLength(dataView, offset) {\n    var length = dataView.getUint8(offset + 7)\n    if (length % 2 !== 0) length += 1\n    // Check for pre photoshop 6 format\n    if (length === 0) {\n      // Always 4\n      length = 4\n    }\n    return length\n  }\n\n  loadImage.parseIptcData = function (dataView, offset, length, data, options) {\n    if (options.disableIptc) {\n      return\n    }\n    var markerLength = offset + length\n    while (offset + 8 < markerLength) {\n      if (isSegmentStart(dataView, offset)) {\n        var headerLength = getHeaderLength(dataView, offset)\n        var segmentOffset = offset + 8 + headerLength\n        if (segmentOffset > markerLength) {\n          // eslint-disable-next-line no-console\n          console.log('Invalid IPTC data: Invalid segment offset.')\n          break\n        }\n        var segmentLength = dataView.getUint16(offset + 6 + headerLength)\n        if (offset + segmentLength > markerLength) {\n          // eslint-disable-next-line no-console\n          console.log('Invalid IPTC data: Invalid segment size.')\n          break\n        }\n        // Create the iptc object to store the tags:\n        data.iptc = new IptcMap()\n        if (!options.disableIptcOffsets) {\n          data.iptcOffsets = new IptcMap()\n        }\n        parseIptcTags(\n          dataView,\n          segmentOffset,\n          segmentLength,\n          data,\n          options.includeIptcTags,\n          options.excludeIptcTags || { 202: true } // ObjectPreviewData\n        )\n        return\n      }\n      // eslint-disable-next-line no-param-reassign\n      offset += 1\n    }\n  }\n\n  // Registers this IPTC parser for the APP13 JPEG metadata segment:\n  loadImage.metaDataParsers.jpeg[0xffed].push(loadImage.parseIptcData)\n\n  loadImage.IptcMap = IptcMap\n\n  // Adds the following properties to the parseMetaData callback data:\n  // - iptc: The iptc tags, parsed by the parseIptcData method\n\n  // Adds the following options to the parseMetaData method:\n  // - disableIptc: Disables IPTC parsing when true.\n  // - disableIptcOffsets: Disables storing IPTC tag offsets when true.\n  // - includeIptcTags: A map of IPTC tags to include for parsing.\n  // - excludeIptcTags: A map of IPTC tags to exclude from parsing.\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif.js":"/*\n * JavaScript Load Image Exif Parser\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require, DataView */\n\n/* eslint-disable no-console */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'), require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  /**\n   * Exif tag map\n   *\n   * @name ExifMap\n   * @class\n   * @param {number|string} tagCode IFD tag code\n   */\n  function ExifMap(tagCode) {\n    if (tagCode) {\n      Object.defineProperty(this, 'map', {\n        value: this.ifds[tagCode].map\n      })\n      Object.defineProperty(this, 'tags', {\n        value: (this.tags && this.tags[tagCode]) || {}\n      })\n    }\n  }\n\n  ExifMap.prototype.map = {\n    Orientation: 0x0112,\n    Thumbnail: 'ifd1',\n    Blob: 0x0201, // Alias for JPEGInterchangeFormat\n    Exif: 0x8769,\n    GPSInfo: 0x8825,\n    Interoperability: 0xa005\n  }\n\n  ExifMap.prototype.ifds = {\n    ifd1: { name: 'Thumbnail', map: ExifMap.prototype.map },\n    0x8769: { name: 'Exif', map: {} },\n    0x8825: { name: 'GPSInfo', map: {} },\n    0xa005: { name: 'Interoperability', map: {} }\n  }\n\n  /**\n   * Retrieves exif tag value\n   *\n   * @param {number|string} id Exif tag code or name\n   * @returns {object} Exif tag value\n   */\n  ExifMap.prototype.get = function (id) {\n    return this[id] || this[this.map[id]]\n  }\n\n  /**\n   * Returns the Exif Thumbnail data as Blob.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} offset Thumbnail data offset\n   * @param {number} length Thumbnail data length\n   * @returns {undefined|Blob} Returns the Thumbnail Blob or undefined\n   */\n  function getExifThumbnail(dataView, offset, length) {\n    if (!length) return\n    if (offset + length > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid thumbnail data.')\n      return\n    }\n    return new Blob(\n      [loadImage.bufferSlice.call(dataView.buffer, offset, offset + length)],\n      {\n        type: 'image/jpeg'\n      }\n    )\n  }\n\n  var ExifTagTypes = {\n    // byte, 8-bit unsigned int:\n    1: {\n      getValue: function (dataView, dataOffset) {\n        return dataView.getUint8(dataOffset)\n      },\n      size: 1\n    },\n    // ascii, 8-bit byte:\n    2: {\n      getValue: function (dataView, dataOffset) {\n        return String.fromCharCode(dataView.getUint8(dataOffset))\n      },\n      size: 1,\n      ascii: true\n    },\n    // short, 16 bit int:\n    3: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint16(dataOffset, littleEndian)\n      },\n      size: 2\n    },\n    // long, 32 bit int:\n    4: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getUint32(dataOffset, littleEndian)\n      },\n      size: 4\n    },\n    // rational = two long values, first is numerator, second is denominator:\n    5: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return (\n          dataView.getUint32(dataOffset, littleEndian) /\n          dataView.getUint32(dataOffset + 4, littleEndian)\n        )\n      },\n      size: 8\n    },\n    // slong, 32 bit signed int:\n    9: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return dataView.getInt32(dataOffset, littleEndian)\n      },\n      size: 4\n    },\n    // srational, two slongs, first is numerator, second is denominator:\n    10: {\n      getValue: function (dataView, dataOffset, littleEndian) {\n        return (\n          dataView.getInt32(dataOffset, littleEndian) /\n          dataView.getInt32(dataOffset + 4, littleEndian)\n        )\n      },\n      size: 8\n    }\n  }\n  // undefined, 8-bit byte, value depending on field:\n  ExifTagTypes[7] = ExifTagTypes[1]\n\n  /**\n   * Returns Exif tag value.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} tiffOffset TIFF offset\n   * @param {number} offset Tag offset\n   * @param {number} type Tag type\n   * @param {number} length Tag length\n   * @param {boolean} littleEndian Little endian encoding\n   * @returns {object} Tag value\n   */\n  function getExifValue(\n    dataView,\n    tiffOffset,\n    offset,\n    type,\n    length,\n    littleEndian\n  ) {\n    var tagType = ExifTagTypes[type]\n    var tagSize\n    var dataOffset\n    var values\n    var i\n    var str\n    var c\n    if (!tagType) {\n      console.log('Invalid Exif data: Invalid tag type.')\n      return\n    }\n    tagSize = tagType.size * length\n    // Determine if the value is contained in the dataOffset bytes,\n    // or if the value at the dataOffset is a pointer to the actual data:\n    dataOffset =\n      tagSize > 4\n        ? tiffOffset + dataView.getUint32(offset + 8, littleEndian)\n        : offset + 8\n    if (dataOffset + tagSize > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid data offset.')\n      return\n    }\n    if (length === 1) {\n      return tagType.getValue(dataView, dataOffset, littleEndian)\n    }\n    values = []\n    for (i = 0; i < length; i += 1) {\n      values[i] = tagType.getValue(\n        dataView,\n        dataOffset + i * tagType.size,\n        littleEndian\n      )\n    }\n    if (tagType.ascii) {\n      str = ''\n      // Concatenate the chars:\n      for (i = 0; i < values.length; i += 1) {\n        c = values[i]\n        // Ignore the terminating NULL byte(s):\n        if (c === '\\u0000') {\n          break\n        }\n        str += c\n      }\n      return str\n    }\n    return values\n  }\n\n  /**\n   * Determines if the given tag should be included.\n   *\n   * @param {object} includeTags Map of tags to include\n   * @param {object} excludeTags Map of tags to exclude\n   * @param {number|string} tagCode Tag code to check\n   * @returns {boolean} True if the tag should be included\n   */\n  function shouldIncludeTag(includeTags, excludeTags, tagCode) {\n    return (\n      (!includeTags || includeTags[tagCode]) &&\n      (!excludeTags || excludeTags[tagCode] !== true)\n    )\n  }\n\n  /**\n   * Parses Exif tags.\n   *\n   * @param {DataView} dataView Data view interface\n   * @param {number} tiffOffset TIFF offset\n   * @param {number} dirOffset Directory offset\n   * @param {boolean} littleEndian Little endian encoding\n   * @param {ExifMap} tags Map to store parsed exif tags\n   * @param {ExifMap} tagOffsets Map to store parsed exif tag offsets\n   * @param {object} includeTags Map of tags to include\n   * @param {object} excludeTags Map of tags to exclude\n   * @returns {number} Next directory offset\n   */\n  function parseExifTags(\n    dataView,\n    tiffOffset,\n    dirOffset,\n    littleEndian,\n    tags,\n    tagOffsets,\n    includeTags,\n    excludeTags\n  ) {\n    var tagsNumber, dirEndOffset, i, tagOffset, tagNumber, tagValue\n    if (dirOffset + 6 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid directory offset.')\n      return\n    }\n    tagsNumber = dataView.getUint16(dirOffset, littleEndian)\n    dirEndOffset = dirOffset + 2 + 12 * tagsNumber\n    if (dirEndOffset + 4 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid directory size.')\n      return\n    }\n    for (i = 0; i < tagsNumber; i += 1) {\n      tagOffset = dirOffset + 2 + 12 * i\n      tagNumber = dataView.getUint16(tagOffset, littleEndian)\n      if (!shouldIncludeTag(includeTags, excludeTags, tagNumber)) continue\n      tagValue = getExifValue(\n        dataView,\n        tiffOffset,\n        tagOffset,\n        dataView.getUint16(tagOffset + 2, littleEndian), // tag type\n        dataView.getUint32(tagOffset + 4, littleEndian), // tag length\n        littleEndian\n      )\n      tags[tagNumber] = tagValue\n      if (tagOffsets) {\n        tagOffsets[tagNumber] = tagOffset\n      }\n    }\n    // Return the offset to the next directory:\n    return dataView.getUint32(dirEndOffset, littleEndian)\n  }\n\n  /**\n   * Parses tags in a given IFD (Image File Directory).\n   *\n   * @param {object} data Data object to store exif tags and offsets\n   * @param {number|string} tagCode IFD tag code\n   * @param {DataView} dataView Data view interface\n   * @param {number} tiffOffset TIFF offset\n   * @param {boolean} littleEndian Little endian encoding\n   * @param {object} includeTags Map of tags to include\n   * @param {object} excludeTags Map of tags to exclude\n   */\n  function parseExifIFD(\n    data,\n    tagCode,\n    dataView,\n    tiffOffset,\n    littleEndian,\n    includeTags,\n    excludeTags\n  ) {\n    var dirOffset = data.exif[tagCode]\n    if (dirOffset) {\n      data.exif[tagCode] = new ExifMap(tagCode)\n      if (data.exifOffsets) {\n        data.exifOffsets[tagCode] = new ExifMap(tagCode)\n      }\n      parseExifTags(\n        dataView,\n        tiffOffset,\n        tiffOffset + dirOffset,\n        littleEndian,\n        data.exif[tagCode],\n        data.exifOffsets && data.exifOffsets[tagCode],\n        includeTags && includeTags[tagCode],\n        excludeTags && excludeTags[tagCode]\n      )\n    }\n  }\n\n  loadImage.parseExifData = function (dataView, offset, length, data, options) {\n    if (options.disableExif) {\n      return\n    }\n    var includeTags = options.includeExifTags\n    var excludeTags = options.excludeExifTags || {\n      0x8769: {\n        // ExifIFDPointer\n        0x927c: true // MakerNote\n      }\n    }\n    var tiffOffset = offset + 10\n    var littleEndian\n    var dirOffset\n    var thumbnailIFD\n    // Check for the ASCII code for \"Exif\" (0x45786966):\n    if (dataView.getUint32(offset + 4) !== 0x45786966) {\n      // No Exif data, might be XMP data instead\n      return\n    }\n    if (tiffOffset + 8 > dataView.byteLength) {\n      console.log('Invalid Exif data: Invalid segment size.')\n      return\n    }\n    // Check for the two null bytes:\n    if (dataView.getUint16(offset + 8) !== 0x0000) {\n      console.log('Invalid Exif data: Missing byte alignment offset.')\n      return\n    }\n    // Check the byte alignment:\n    switch (dataView.getUint16(tiffOffset)) {\n      case 0x4949:\n        littleEndian = true\n        break\n      case 0x4d4d:\n        littleEndian = false\n        break\n      default:\n        console.log('Invalid Exif data: Invalid byte alignment marker.')\n        return\n    }\n    // Check for the TIFF tag marker (0x002A):\n    if (dataView.getUint16(tiffOffset + 2, littleEndian) !== 0x002a) {\n      console.log('Invalid Exif data: Missing TIFF marker.')\n      return\n    }\n    // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\n    dirOffset = dataView.getUint32(tiffOffset + 4, littleEndian)\n    // Create the exif object to store the tags:\n    data.exif = new ExifMap()\n    if (!options.disableExifOffsets) {\n      data.exifOffsets = new ExifMap()\n      data.exifTiffOffset = tiffOffset\n      data.exifLittleEndian = littleEndian\n    }\n    // Parse the tags of the main image directory (IFD0) and retrieve the\n    // offset to the next directory (IFD1), usually the thumbnail directory:\n    dirOffset = parseExifTags(\n      dataView,\n      tiffOffset,\n      tiffOffset + dirOffset,\n      littleEndian,\n      data.exif,\n      data.exifOffsets,\n      includeTags,\n      excludeTags\n    )\n    if (dirOffset && shouldIncludeTag(includeTags, excludeTags, 'ifd1')) {\n      data.exif.ifd1 = dirOffset\n      if (data.exifOffsets) {\n        data.exifOffsets.ifd1 = tiffOffset + dirOffset\n      }\n    }\n    Object.keys(data.exif.ifds).forEach(function (tagCode) {\n      parseExifIFD(\n        data,\n        tagCode,\n        dataView,\n        tiffOffset,\n        littleEndian,\n        includeTags,\n        excludeTags\n      )\n    })\n    thumbnailIFD = data.exif.ifd1\n    // Check for JPEG Thumbnail offset and data length:\n    if (thumbnailIFD && thumbnailIFD[0x0201]) {\n      thumbnailIFD[0x0201] = getExifThumbnail(\n        dataView,\n        tiffOffset + thumbnailIFD[0x0201],\n        thumbnailIFD[0x0202] // Thumbnail data length\n      )\n    }\n  }\n\n  // Registers the Exif parser for the APP1 JPEG metadata segment:\n  loadImage.metaDataParsers.jpeg[0xffe1].push(loadImage.parseExifData)\n\n  loadImage.exifWriters = {\n    // Orientation writer:\n    0x0112: function (buffer, data, value) {\n      var orientationOffset = data.exifOffsets[0x0112]\n      if (!orientationOffset) return buffer\n      var view = new DataView(buffer, orientationOffset + 8, 2)\n      view.setUint16(0, value, data.exifLittleEndian)\n      return buffer\n    }\n  }\n\n  loadImage.writeExifData = function (buffer, data, id, value) {\n    loadImage.exifWriters[data.exif.map[id]](buffer, data, value)\n  }\n\n  loadImage.ExifMap = ExifMap\n\n  // Adds the following properties to the parseMetaData callback data:\n  // - exif: The parsed Exif tags\n  // - exifOffsets: The parsed Exif tag offsets\n  // - exifTiffOffset: TIFF header offset (used for offset pointers)\n  // - exifLittleEndian: little endian order if true, big endian if false\n\n  // Adds the following options to the parseMetaData method:\n  // - disableExif: Disables Exif parsing when true.\n  // - disableExifOffsets: Disables storing Exif tag offsets when true.\n  // - includeExifTags: A map of Exif tags to include for parsing.\n  // - excludeExifTags: A map of Exif tags to exclude from parsing.\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-fetch.js":"/*\n * JavaScript Load Image Fetch\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2017, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require, Promise */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var global = loadImage.global\n\n  if (\n    global.fetch &&\n    global.Request &&\n    global.Response &&\n    global.Response.prototype.blob\n  ) {\n    loadImage.fetchBlob = function (url, callback, options) {\n      /**\n       * Fetch response handler.\n       *\n       * @param {Response} response Fetch response\n       * @returns {Blob} Fetched Blob.\n       */\n      function responseHandler(response) {\n        return response.blob()\n      }\n      if (global.Promise && typeof callback !== 'function') {\n        return fetch(new Request(url, callback)).then(responseHandler)\n      }\n      fetch(new Request(url, options))\n        .then(responseHandler)\n        .then(callback)\n        [\n          // Avoid parsing error in IE<9, where catch is a reserved word.\n          // eslint-disable-next-line dot-notation\n          'catch'\n        ](function (err) {\n          callback(null, err)\n        })\n    }\n  } else if (\n    global.XMLHttpRequest &&\n    // https://xhr.spec.whatwg.org/#the-responsetype-attribute\n    new XMLHttpRequest().responseType === ''\n  ) {\n    loadImage.fetchBlob = function (url, callback, options) {\n      /**\n       * Promise executor\n       *\n       * @param {Function} resolve Resolution function\n       * @param {Function} reject Rejection function\n       */\n      function executor(resolve, reject) {\n        options = options || {} // eslint-disable-line no-param-reassign\n        var req = new XMLHttpRequest()\n        req.open(options.method || 'GET', url)\n        if (options.headers) {\n          Object.keys(options.headers).forEach(function (key) {\n            req.setRequestHeader(key, options.headers[key])\n          })\n        }\n        req.withCredentials = options.credentials === 'include'\n        req.responseType = 'blob'\n        req.onload = function () {\n          resolve(req.response)\n        }\n        req.onerror = req.onabort = req.ontimeout = function (err) {\n          if (resolve === reject) {\n            // Not using Promises\n            reject(null, err)\n          } else {\n            reject(err)\n          }\n        }\n        req.send(options.body)\n      }\n      if (global.Promise && typeof callback !== 'function') {\n        options = callback // eslint-disable-line no-param-reassign\n        return new Promise(executor)\n      }\n      return executor(callback, callback)\n    }\n  }\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif-map.js":"/*\n * JavaScript Load Image Exif Map\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Exif tags mapping based on\n * https://github.com/jseidelin/exif-js\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'), require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var ExifMapProto = loadImage.ExifMap.prototype\n\n  ExifMapProto.tags = {\n    // =================\n    // TIFF tags (IFD0):\n    // =================\n    0x0100: 'ImageWidth',\n    0x0101: 'ImageHeight',\n    0x0102: 'BitsPerSample',\n    0x0103: 'Compression',\n    0x0106: 'PhotometricInterpretation',\n    0x0112: 'Orientation',\n    0x0115: 'SamplesPerPixel',\n    0x011c: 'PlanarConfiguration',\n    0x0212: 'YCbCrSubSampling',\n    0x0213: 'YCbCrPositioning',\n    0x011a: 'XResolution',\n    0x011b: 'YResolution',\n    0x0128: 'ResolutionUnit',\n    0x0111: 'StripOffsets',\n    0x0116: 'RowsPerStrip',\n    0x0117: 'StripByteCounts',\n    0x0201: 'JPEGInterchangeFormat',\n    0x0202: 'JPEGInterchangeFormatLength',\n    0x012d: 'TransferFunction',\n    0x013e: 'WhitePoint',\n    0x013f: 'PrimaryChromaticities',\n    0x0211: 'YCbCrCoefficients',\n    0x0214: 'ReferenceBlackWhite',\n    0x0132: 'DateTime',\n    0x010e: 'ImageDescription',\n    0x010f: 'Make',\n    0x0110: 'Model',\n    0x0131: 'Software',\n    0x013b: 'Artist',\n    0x8298: 'Copyright',\n    0x8769: {\n      // ExifIFDPointer\n      0x9000: 'ExifVersion', // EXIF version\n      0xa000: 'FlashpixVersion', // Flashpix format version\n      0xa001: 'ColorSpace', // Color space information tag\n      0xa002: 'PixelXDimension', // Valid width of meaningful image\n      0xa003: 'PixelYDimension', // Valid height of meaningful image\n      0xa500: 'Gamma',\n      0x9101: 'ComponentsConfiguration', // Information about channels\n      0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel\n      0x927c: 'MakerNote', // Any desired information written by the manufacturer\n      0x9286: 'UserComment', // Comments by user\n      0xa004: 'RelatedSoundFile', // Name of related sound file\n      0x9003: 'DateTimeOriginal', // Date and time when the original image was generated\n      0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally\n      0x9010: 'OffsetTime', // Time zone when the image file was last changed\n      0x9011: 'OffsetTimeOriginal', // Time zone when the image was stored digitally\n      0x9012: 'OffsetTimeDigitized', // Time zone when the image was stored digitally\n      0x9290: 'SubSecTime', // Fractions of seconds for DateTime\n      0x9291: 'SubSecTimeOriginal', // Fractions of seconds for DateTimeOriginal\n      0x9292: 'SubSecTimeDigitized', // Fractions of seconds for DateTimeDigitized\n      0x829a: 'ExposureTime', // Exposure time (in seconds)\n      0x829d: 'FNumber',\n      0x8822: 'ExposureProgram', // Exposure program\n      0x8824: 'SpectralSensitivity', // Spectral sensitivity\n      0x8827: 'PhotographicSensitivity', // EXIF 2.3, ISOSpeedRatings in EXIF 2.2\n      0x8828: 'OECF', // Optoelectric conversion factor\n      0x8830: 'SensitivityType',\n      0x8831: 'StandardOutputSensitivity',\n      0x8832: 'RecommendedExposureIndex',\n      0x8833: 'ISOSpeed',\n      0x8834: 'ISOSpeedLatitudeyyy',\n      0x8835: 'ISOSpeedLatitudezzz',\n      0x9201: 'ShutterSpeedValue', // Shutter speed\n      0x9202: 'ApertureValue', // Lens aperture\n      0x9203: 'BrightnessValue', // Value of brightness\n      0x9204: 'ExposureBias', // Exposure bias\n      0x9205: 'MaxApertureValue', // Smallest F number of lens\n      0x9206: 'SubjectDistance', // Distance to subject in meters\n      0x9207: 'MeteringMode', // Metering mode\n      0x9208: 'LightSource', // Kind of light source\n      0x9209: 'Flash', // Flash status\n      0x9214: 'SubjectArea', // Location and area of main subject\n      0x920a: 'FocalLength', // Focal length of the lens in mm\n      0xa20b: 'FlashEnergy', // Strobe energy in BCPS\n      0xa20c: 'SpatialFrequencyResponse',\n      0xa20e: 'FocalPlaneXResolution', // Number of pixels in width direction per FPRUnit\n      0xa20f: 'FocalPlaneYResolution', // Number of pixels in height direction per FPRUnit\n      0xa210: 'FocalPlaneResolutionUnit', // Unit for measuring the focal plane resolution\n      0xa214: 'SubjectLocation', // Location of subject in image\n      0xa215: 'ExposureIndex', // Exposure index selected on camera\n      0xa217: 'SensingMethod', // Image sensor type\n      0xa300: 'FileSource', // Image source (3 == DSC)\n      0xa301: 'SceneType', // Scene type (1 == directly photographed)\n      0xa302: 'CFAPattern', // Color filter array geometric pattern\n      0xa401: 'CustomRendered', // Special processing\n      0xa402: 'ExposureMode', // Exposure mode\n      0xa403: 'WhiteBalance', // 1 = auto white balance, 2 = manual\n      0xa404: 'DigitalZoomRatio', // Digital zoom ratio\n      0xa405: 'FocalLengthIn35mmFilm',\n      0xa406: 'SceneCaptureType', // Type of scene\n      0xa407: 'GainControl', // Degree of overall image gain adjustment\n      0xa408: 'Contrast', // Direction of contrast processing applied by camera\n      0xa409: 'Saturation', // Direction of saturation processing applied by camera\n      0xa40a: 'Sharpness', // Direction of sharpness processing applied by camera\n      0xa40b: 'DeviceSettingDescription',\n      0xa40c: 'SubjectDistanceRange', // Distance to subject\n      0xa420: 'ImageUniqueID', // Identifier assigned uniquely to each image\n      0xa430: 'CameraOwnerName',\n      0xa431: 'BodySerialNumber',\n      0xa432: 'LensSpecification',\n      0xa433: 'LensMake',\n      0xa434: 'LensModel',\n      0xa435: 'LensSerialNumber'\n    },\n    0x8825: {\n      // GPSInfoIFDPointer\n      0x0000: 'GPSVersionID',\n      0x0001: 'GPSLatitudeRef',\n      0x0002: 'GPSLatitude',\n      0x0003: 'GPSLongitudeRef',\n      0x0004: 'GPSLongitude',\n      0x0005: 'GPSAltitudeRef',\n      0x0006: 'GPSAltitude',\n      0x0007: 'GPSTimeStamp',\n      0x0008: 'GPSSatellites',\n      0x0009: 'GPSStatus',\n      0x000a: 'GPSMeasureMode',\n      0x000b: 'GPSDOP',\n      0x000c: 'GPSSpeedRef',\n      0x000d: 'GPSSpeed',\n      0x000e: 'GPSTrackRef',\n      0x000f: 'GPSTrack',\n      0x0010: 'GPSImgDirectionRef',\n      0x0011: 'GPSImgDirection',\n      0x0012: 'GPSMapDatum',\n      0x0013: 'GPSDestLatitudeRef',\n      0x0014: 'GPSDestLatitude',\n      0x0015: 'GPSDestLongitudeRef',\n      0x0016: 'GPSDestLongitude',\n      0x0017: 'GPSDestBearingRef',\n      0x0018: 'GPSDestBearing',\n      0x0019: 'GPSDestDistanceRef',\n      0x001a: 'GPSDestDistance',\n      0x001b: 'GPSProcessingMethod',\n      0x001c: 'GPSAreaInformation',\n      0x001d: 'GPSDateStamp',\n      0x001e: 'GPSDifferential',\n      0x001f: 'GPSHPositioningError'\n    },\n    0xa005: {\n      // InteroperabilityIFDPointer\n      0x0001: 'InteroperabilityIndex'\n    }\n  }\n\n  // IFD1 directory can contain any IFD0 tags:\n  ExifMapProto.tags.ifd1 = ExifMapProto.tags\n\n  ExifMapProto.stringValues = {\n    ExposureProgram: {\n      0: 'Undefined',\n      1: 'Manual',\n      2: 'Normal program',\n      3: 'Aperture priority',\n      4: 'Shutter priority',\n      5: 'Creative program',\n      6: 'Action program',\n      7: 'Portrait mode',\n      8: 'Landscape mode'\n    },\n    MeteringMode: {\n      0: 'Unknown',\n      1: 'Average',\n      2: 'CenterWeightedAverage',\n      3: 'Spot',\n      4: 'MultiSpot',\n      5: 'Pattern',\n      6: 'Partial',\n      255: 'Other'\n    },\n    LightSource: {\n      0: 'Unknown',\n      1: 'Daylight',\n      2: 'Fluorescent',\n      3: 'Tungsten (incandescent light)',\n      4: 'Flash',\n      9: 'Fine weather',\n      10: 'Cloudy weather',\n      11: 'Shade',\n      12: 'Daylight fluorescent (D 5700 - 7100K)',\n      13: 'Day white fluorescent (N 4600 - 5400K)',\n      14: 'Cool white fluorescent (W 3900 - 4500K)',\n      15: 'White fluorescent (WW 3200 - 3700K)',\n      17: 'Standard light A',\n      18: 'Standard light B',\n      19: 'Standard light C',\n      20: 'D55',\n      21: 'D65',\n      22: 'D75',\n      23: 'D50',\n      24: 'ISO studio tungsten',\n      255: 'Other'\n    },\n    Flash: {\n      0x0000: 'Flash did not fire',\n      0x0001: 'Flash fired',\n      0x0005: 'Strobe return light not detected',\n      0x0007: 'Strobe return light detected',\n      0x0009: 'Flash fired, compulsory flash mode',\n      0x000d: 'Flash fired, compulsory flash mode, return light not detected',\n      0x000f: 'Flash fired, compulsory flash mode, return light detected',\n      0x0010: 'Flash did not fire, compulsory flash mode',\n      0x0018: 'Flash did not fire, auto mode',\n      0x0019: 'Flash fired, auto mode',\n      0x001d: 'Flash fired, auto mode, return light not detected',\n      0x001f: 'Flash fired, auto mode, return light detected',\n      0x0020: 'No flash function',\n      0x0041: 'Flash fired, red-eye reduction mode',\n      0x0045: 'Flash fired, red-eye reduction mode, return light not detected',\n      0x0047: 'Flash fired, red-eye reduction mode, return light detected',\n      0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',\n      0x004d: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',\n      0x004f: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',\n      0x0059: 'Flash fired, auto mode, red-eye reduction mode',\n      0x005d: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',\n      0x005f: 'Flash fired, auto mode, return light detected, red-eye reduction mode'\n    },\n    SensingMethod: {\n      1: 'Undefined',\n      2: 'One-chip color area sensor',\n      3: 'Two-chip color area sensor',\n      4: 'Three-chip color area sensor',\n      5: 'Color sequential area sensor',\n      7: 'Trilinear sensor',\n      8: 'Color sequential linear sensor'\n    },\n    SceneCaptureType: {\n      0: 'Standard',\n      1: 'Landscape',\n      2: 'Portrait',\n      3: 'Night scene'\n    },\n    SceneType: {\n      1: 'Directly photographed'\n    },\n    CustomRendered: {\n      0: 'Normal process',\n      1: 'Custom process'\n    },\n    WhiteBalance: {\n      0: 'Auto white balance',\n      1: 'Manual white balance'\n    },\n    GainControl: {\n      0: 'None',\n      1: 'Low gain up',\n      2: 'High gain up',\n      3: 'Low gain down',\n      4: 'High gain down'\n    },\n    Contrast: {\n      0: 'Normal',\n      1: 'Soft',\n      2: 'Hard'\n    },\n    Saturation: {\n      0: 'Normal',\n      1: 'Low saturation',\n      2: 'High saturation'\n    },\n    Sharpness: {\n      0: 'Normal',\n      1: 'Soft',\n      2: 'Hard'\n    },\n    SubjectDistanceRange: {\n      0: 'Unknown',\n      1: 'Macro',\n      2: 'Close view',\n      3: 'Distant view'\n    },\n    FileSource: {\n      3: 'DSC'\n    },\n    ComponentsConfiguration: {\n      0: '',\n      1: 'Y',\n      2: 'Cb',\n      3: 'Cr',\n      4: 'R',\n      5: 'G',\n      6: 'B'\n    },\n    Orientation: {\n      1: 'Original',\n      2: 'Horizontal flip',\n      3: 'Rotate 180\u00b0 CCW',\n      4: 'Vertical flip',\n      5: 'Vertical flip + Rotate 90\u00b0 CW',\n      6: 'Rotate 90\u00b0 CW',\n      7: 'Horizontal flip + Rotate 90\u00b0 CW',\n      8: 'Rotate 90\u00b0 CCW'\n    }\n  }\n\n  ExifMapProto.getText = function (name) {\n    var value = this.get(name)\n    switch (name) {\n      case 'LightSource':\n      case 'Flash':\n      case 'MeteringMode':\n      case 'ExposureProgram':\n      case 'SensingMethod':\n      case 'SceneCaptureType':\n      case 'SceneType':\n      case 'CustomRendered':\n      case 'WhiteBalance':\n      case 'GainControl':\n      case 'Contrast':\n      case 'Saturation':\n      case 'Sharpness':\n      case 'SubjectDistanceRange':\n      case 'FileSource':\n      case 'Orientation':\n        return this.stringValues[name][value]\n      case 'ExifVersion':\n      case 'FlashpixVersion':\n        if (!value) return\n        return String.fromCharCode(value[0], value[1], value[2], value[3])\n      case 'ComponentsConfiguration':\n        if (!value) return\n        return (\n          this.stringValues[name][value[0]] +\n          this.stringValues[name][value[1]] +\n          this.stringValues[name][value[2]] +\n          this.stringValues[name][value[3]]\n        )\n      case 'GPSVersionID':\n        if (!value) return\n        return value[0] + '.' + value[1] + '.' + value[2] + '.' + value[3]\n    }\n    return String(value)\n  }\n\n  ExifMapProto.getAll = function () {\n    var map = {}\n    var prop\n    var obj\n    var name\n    for (prop in this) {\n      if (Object.prototype.hasOwnProperty.call(this, prop)) {\n        obj = this[prop]\n        if (obj && obj.getAll) {\n          map[this.ifds[prop].name] = obj.getAll()\n        } else {\n          name = this.tags[prop]\n          if (name) map[name] = this.getText(name)\n        }\n      }\n    }\n    return map\n  }\n\n  ExifMapProto.getName = function (tagCode) {\n    var name = this.tags[tagCode]\n    if (typeof name === 'object') return this.ifds[tagCode].name\n    return name\n  }\n\n  // Extend the map of tag names to tag codes:\n  ;(function () {\n    var tags = ExifMapProto.tags\n    var prop\n    var ifd\n    var subTags\n    // Map the tag names to tags:\n    for (prop in tags) {\n      if (Object.prototype.hasOwnProperty.call(tags, prop)) {\n        ifd = ExifMapProto.ifds[prop]\n        if (ifd) {\n          subTags = tags[prop]\n          for (prop in subTags) {\n            if (Object.prototype.hasOwnProperty.call(subTags, prop)) {\n              ifd.map[subTags[prop]] = Number(prop)\n            }\n          }\n        } else {\n          ExifMapProto.map[tags[prop]] = Number(prop)\n        }\n      }\n    }\n  })()\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-orientation.js":"/*\n * JavaScript Load Image Orientation\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/*\nExif orientation values to correctly display the letter F:\n\n    1             2\n  \u2588\u2588\u2588\u2588\u2588\u2588        \u2588\u2588\u2588\u2588\u2588\u2588\n  \u2588\u2588                \u2588\u2588\n  \u2588\u2588\u2588\u2588            \u2588\u2588\u2588\u2588\n  \u2588\u2588                \u2588\u2588\n  \u2588\u2588                \u2588\u2588\n\n    3             4\n      \u2588\u2588        \u2588\u2588\n      \u2588\u2588        \u2588\u2588\n    \u2588\u2588\u2588\u2588        \u2588\u2588\u2588\u2588\n      \u2588\u2588        \u2588\u2588\n  \u2588\u2588\u2588\u2588\u2588\u2588        \u2588\u2588\u2588\u2588\u2588\u2588\n\n    5             6\n\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588    \u2588\u2588\n\u2588\u2588  \u2588\u2588        \u2588\u2588  \u2588\u2588\n\u2588\u2588            \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\n\n    7             8\n        \u2588\u2588    \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\n    \u2588\u2588  \u2588\u2588        \u2588\u2588  \u2588\u2588\n\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588            \u2588\u2588\n\n*/\n\n/* global define, module, require */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale'),\n      require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta')\n    )\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var originalTransform = loadImage.transform\n  var originalRequiresCanvas = loadImage.requiresCanvas\n  var originalRequiresMetaData = loadImage.requiresMetaData\n  var originalTransformCoordinates = loadImage.transformCoordinates\n  var originalGetTransformedOptions = loadImage.getTransformedOptions\n\n  ;(function ($) {\n    // Guard for non-browser environments (e.g. server-side rendering):\n    if (!$.global.document) return\n    // black+white 3x2 JPEG, with the following meta information set:\n    // - EXIF Orientation: 6 (Rotated 90\u00b0 CCW)\n    // Image data layout (B=black, F=white):\n    // BFF\n    // BBB\n    var testImageURL =\n      'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +\n      'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +\n      'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +\n      'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAIAAwMBEQACEQEDEQH/x' +\n      'ABRAAEAAAAAAAAAAAAAAAAAAAAKEAEBAQADAQEAAAAAAAAAAAAGBQQDCAkCBwEBAAAAAAA' +\n      'AAAAAAAAAAAAAABEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AG8T9NfSMEVMhQ' +\n      'voP3fFiRZ+MTHDifa/95OFSZU5OzRzxkyejv8ciEfhSceSXGjS8eSdLnZc2HDm4M3BxcXw' +\n      'H/9k='\n    var img = document.createElement('img')\n    img.onload = function () {\n      // Check if the browser supports automatic image orientation:\n      $.orientation = img.width === 2 && img.height === 3\n      if ($.orientation) {\n        var canvas = $.createCanvas(1, 1, true)\n        var ctx = canvas.getContext('2d')\n        ctx.drawImage(img, 1, 1, 1, 1, 0, 0, 1, 1)\n        // Check if the source image coordinates (sX, sY, sWidth, sHeight) are\n        // correctly applied to the auto-orientated image, which should result\n        // in a white opaque pixel (e.g. in Safari).\n        // Browsers that show a transparent pixel (e.g. Chromium) fail to crop\n        // auto-oriented images correctly and require a workaround, e.g.\n        // drawing the complete source image to an intermediate canvas first.\n        // See https://bugs.chromium.org/p/chromium/issues/detail?id=1074354\n        $.orientationCropBug =\n          ctx.getImageData(0, 0, 1, 1).data.toString() !== '255,255,255,255'\n      }\n    }\n    img.src = testImageURL\n  })(loadImage)\n\n  /**\n   * Determines if the orientation requires a canvas element.\n   *\n   * @param {object} [options] Options object\n   * @param {boolean} [withMetaData] Is metadata required for orientation\n   * @returns {boolean} Returns true if orientation requires canvas/meta\n   */\n  function requiresCanvasOrientation(options, withMetaData) {\n    var orientation = options && options.orientation\n    return (\n      // Exif orientation for browsers without automatic image orientation:\n      (orientation === true && !loadImage.orientation) ||\n      // Orientation reset for browsers with automatic image orientation:\n      (orientation === 1 && loadImage.orientation) ||\n      // Orientation to defined value, requires meta for orientation reset only:\n      ((!withMetaData || loadImage.orientation) &&\n        orientation > 1 &&\n        orientation < 9)\n    )\n  }\n\n  /**\n   * Determines if the image requires an orientation change.\n   *\n   * @param {number} [orientation] Defined orientation value\n   * @param {number} [autoOrientation] Auto-orientation based on Exif data\n   * @returns {boolean} Returns true if an orientation change is required\n   */\n  function requiresOrientationChange(orientation, autoOrientation) {\n    return (\n      orientation !== autoOrientation &&\n      ((orientation === 1 && autoOrientation > 1 && autoOrientation < 9) ||\n        (orientation > 1 && orientation < 9))\n    )\n  }\n\n  /**\n   * Determines orientation combinations that require a rotation by 180\u00b0.\n   *\n   * The following is a list of combinations that return true:\n   *\n   * 2 (flip) => 5 (rot90,flip), 7 (rot90,flip), 6 (rot90), 8 (rot90)\n   * 4 (flip) => 5 (rot90,flip), 7 (rot90,flip), 6 (rot90), 8 (rot90)\n   *\n   * 5 (rot90,flip) => 2 (flip), 4 (flip), 6 (rot90), 8 (rot90)\n   * 7 (rot90,flip) => 2 (flip), 4 (flip), 6 (rot90), 8 (rot90)\n   *\n   * 6 (rot90) => 2 (flip), 4 (flip), 5 (rot90,flip), 7 (rot90,flip)\n   * 8 (rot90) => 2 (flip), 4 (flip), 5 (rot90,flip), 7 (rot90,flip)\n   *\n   * @param {number} [orientation] Defined orientation value\n   * @param {number} [autoOrientation] Auto-orientation based on Exif data\n   * @returns {boolean} Returns true if rotation by 180\u00b0 is required\n   */\n  function requiresRot180(orientation, autoOrientation) {\n    if (autoOrientation > 1 && autoOrientation < 9) {\n      switch (orientation) {\n        case 2:\n        case 4:\n          return autoOrientation > 4\n        case 5:\n        case 7:\n          return autoOrientation % 2 === 0\n        case 6:\n        case 8:\n          return (\n            autoOrientation === 2 ||\n            autoOrientation === 4 ||\n            autoOrientation === 5 ||\n            autoOrientation === 7\n          )\n      }\n    }\n    return false\n  }\n\n  // Determines if the target image should be a canvas element:\n  loadImage.requiresCanvas = function (options) {\n    return (\n      requiresCanvasOrientation(options) ||\n      originalRequiresCanvas.call(loadImage, options)\n    )\n  }\n\n  // Determines if metadata should be loaded automatically:\n  loadImage.requiresMetaData = function (options) {\n    return (\n      requiresCanvasOrientation(options, true) ||\n      originalRequiresMetaData.call(loadImage, options)\n    )\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    originalTransform.call(\n      loadImage,\n      img,\n      options,\n      function (img, data) {\n        if (data) {\n          var autoOrientation =\n            loadImage.orientation && data.exif && data.exif.get('Orientation')\n          if (autoOrientation > 4 && autoOrientation < 9) {\n            // Automatic image orientation switched image dimensions\n            var originalWidth = data.originalWidth\n            var originalHeight = data.originalHeight\n            data.originalWidth = originalHeight\n            data.originalHeight = originalWidth\n          }\n        }\n        callback(img, data)\n      },\n      file,\n      data\n    )\n  }\n\n  // Transforms coordinate and dimension options\n  // based on the given orientation option:\n  loadImage.getTransformedOptions = function (img, opts, data) {\n    var options = originalGetTransformedOptions.call(loadImage, img, opts)\n    var exifOrientation = data.exif && data.exif.get('Orientation')\n    var orientation = options.orientation\n    var autoOrientation = loadImage.orientation && exifOrientation\n    if (orientation === true) orientation = exifOrientation\n    if (!requiresOrientationChange(orientation, autoOrientation)) {\n      return options\n    }\n    var top = options.top\n    var right = options.right\n    var bottom = options.bottom\n    var left = options.left\n    var newOptions = {}\n    for (var i in options) {\n      if (Object.prototype.hasOwnProperty.call(options, i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.orientation = orientation\n    if (\n      (orientation > 4 && !(autoOrientation > 4)) ||\n      (orientation < 5 && autoOrientation > 4)\n    ) {\n      // Image dimensions and target dimensions are switched\n      newOptions.maxWidth = options.maxHeight\n      newOptions.maxHeight = options.maxWidth\n      newOptions.minWidth = options.minHeight\n      newOptions.minHeight = options.minWidth\n      newOptions.sourceWidth = options.sourceHeight\n      newOptions.sourceHeight = options.sourceWidth\n    }\n    if (autoOrientation > 1) {\n      // Browsers which correctly apply source image coordinates to\n      // auto-oriented images\n      switch (autoOrientation) {\n        case 2:\n          // Horizontal flip\n          right = options.left\n          left = options.right\n          break\n        case 3:\n          // 180\u00b0 Rotate CCW\n          top = options.bottom\n          right = options.left\n          bottom = options.top\n          left = options.right\n          break\n        case 4:\n          // Vertical flip\n          top = options.bottom\n          bottom = options.top\n          break\n        case 5:\n          // Horizontal flip + 90\u00b0 Rotate CCW\n          top = options.left\n          right = options.bottom\n          bottom = options.right\n          left = options.top\n          break\n        case 6:\n          // 90\u00b0 Rotate CCW\n          top = options.left\n          right = options.top\n          bottom = options.right\n          left = options.bottom\n          break\n        case 7:\n          // Vertical flip + 90\u00b0 Rotate CCW\n          top = options.right\n          right = options.top\n          bottom = options.left\n          left = options.bottom\n          break\n        case 8:\n          // 90\u00b0 Rotate CW\n          top = options.right\n          right = options.bottom\n          bottom = options.left\n          left = options.top\n          break\n      }\n      // Some orientation combinations require additional rotation by 180\u00b0:\n      if (requiresRot180(orientation, autoOrientation)) {\n        var tmpTop = top\n        var tmpRight = right\n        top = bottom\n        right = left\n        bottom = tmpTop\n        left = tmpRight\n      }\n    }\n    newOptions.top = top\n    newOptions.right = right\n    newOptions.bottom = bottom\n    newOptions.left = left\n    // Account for defined browser orientation:\n    switch (orientation) {\n      case 2:\n        // Horizontal flip\n        newOptions.right = left\n        newOptions.left = right\n        break\n      case 3:\n        // 180\u00b0 Rotate CCW\n        newOptions.top = bottom\n        newOptions.right = left\n        newOptions.bottom = top\n        newOptions.left = right\n        break\n      case 4:\n        // Vertical flip\n        newOptions.top = bottom\n        newOptions.bottom = top\n        break\n      case 5:\n        // Vertical flip + 90\u00b0 Rotate CW\n        newOptions.top = left\n        newOptions.right = bottom\n        newOptions.bottom = right\n        newOptions.left = top\n        break\n      case 6:\n        // 90\u00b0 Rotate CW\n        newOptions.top = right\n        newOptions.right = bottom\n        newOptions.bottom = left\n        newOptions.left = top\n        break\n      case 7:\n        // Horizontal flip + 90\u00b0 Rotate CW\n        newOptions.top = right\n        newOptions.right = top\n        newOptions.bottom = left\n        newOptions.left = bottom\n        break\n      case 8:\n        // 90\u00b0 Rotate CCW\n        newOptions.top = left\n        newOptions.right = top\n        newOptions.bottom = right\n        newOptions.left = bottom\n        break\n    }\n    return newOptions\n  }\n\n  // Transform image orientation based on the given EXIF orientation option:\n  loadImage.transformCoordinates = function (canvas, options, data) {\n    originalTransformCoordinates.call(loadImage, canvas, options, data)\n    var orientation = options.orientation\n    var autoOrientation =\n      loadImage.orientation && data.exif && data.exif.get('Orientation')\n    if (!requiresOrientationChange(orientation, autoOrientation)) {\n      return\n    }\n    var ctx = canvas.getContext('2d')\n    var width = canvas.width\n    var height = canvas.height\n    var sourceWidth = width\n    var sourceHeight = height\n    if (\n      (orientation > 4 && !(autoOrientation > 4)) ||\n      (orientation < 5 && autoOrientation > 4)\n    ) {\n      // Image dimensions and target dimensions are switched\n      canvas.width = height\n      canvas.height = width\n    }\n    if (orientation > 4) {\n      // Destination and source dimensions are switched\n      sourceWidth = height\n      sourceHeight = width\n    }\n    // Reset automatic browser orientation:\n    switch (autoOrientation) {\n      case 2:\n        // Horizontal flip\n        ctx.translate(sourceWidth, 0)\n        ctx.scale(-1, 1)\n        break\n      case 3:\n        // 180\u00b0 Rotate CCW\n        ctx.translate(sourceWidth, sourceHeight)\n        ctx.rotate(Math.PI)\n        break\n      case 4:\n        // Vertical flip\n        ctx.translate(0, sourceHeight)\n        ctx.scale(1, -1)\n        break\n      case 5:\n        // Horizontal flip + 90\u00b0 Rotate CCW\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.scale(-1, 1)\n        break\n      case 6:\n        // 90\u00b0 Rotate CCW\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.translate(-sourceWidth, 0)\n        break\n      case 7:\n        // Vertical flip + 90\u00b0 Rotate CCW\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.translate(-sourceWidth, sourceHeight)\n        ctx.scale(1, -1)\n        break\n      case 8:\n        // 90\u00b0 Rotate CW\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(0, -sourceHeight)\n        break\n    }\n    // Some orientation combinations require additional rotation by 180\u00b0:\n    if (requiresRot180(orientation, autoOrientation)) {\n      ctx.translate(sourceWidth, sourceHeight)\n      ctx.rotate(Math.PI)\n    }\n    switch (orientation) {\n      case 2:\n        // Horizontal flip\n        ctx.translate(width, 0)\n        ctx.scale(-1, 1)\n        break\n      case 3:\n        // 180\u00b0 Rotate CCW\n        ctx.translate(width, height)\n        ctx.rotate(Math.PI)\n        break\n      case 4:\n        // Vertical flip\n        ctx.translate(0, height)\n        ctx.scale(1, -1)\n        break\n      case 5:\n        // Vertical flip + 90\u00b0 Rotate CW\n        ctx.rotate(0.5 * Math.PI)\n        ctx.scale(1, -1)\n        break\n      case 6:\n        // 90\u00b0 Rotate CW\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(0, -height)\n        break\n      case 7:\n        // Horizontal flip + 90\u00b0 Rotate CW\n        ctx.rotate(0.5 * Math.PI)\n        ctx.translate(width, -height)\n        ctx.scale(-1, 1)\n        break\n      case 8:\n        // 90\u00b0 Rotate CCW\n        ctx.rotate(-0.5 * Math.PI)\n        ctx.translate(-width, 0)\n        break\n    }\n  }\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale.js":"/*\n * JavaScript Load Image Scaling\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var originalTransform = loadImage.transform\n\n  loadImage.createCanvas = function (width, height, offscreen) {\n    if (offscreen && loadImage.global.OffscreenCanvas) {\n      return new OffscreenCanvas(width, height)\n    }\n    var canvas = document.createElement('canvas')\n    canvas.width = width\n    canvas.height = height\n    return canvas\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    originalTransform.call(\n      loadImage,\n      loadImage.scale(img, options, data),\n      options,\n      callback,\n      file,\n      data\n    )\n  }\n\n  // Transform image coordinates, allows to override e.g.\n  // the canvas orientation based on the orientation option,\n  // gets canvas, options and data passed as arguments:\n  loadImage.transformCoordinates = function () {}\n\n  // Returns transformed options, allows to override e.g.\n  // maxWidth, maxHeight and crop options based on the aspectRatio.\n  // gets img, options, data passed as arguments:\n  loadImage.getTransformedOptions = function (img, options) {\n    var aspectRatio = options.aspectRatio\n    var newOptions\n    var i\n    var width\n    var height\n    if (!aspectRatio) {\n      return options\n    }\n    newOptions = {}\n    for (i in options) {\n      if (Object.prototype.hasOwnProperty.call(options, i)) {\n        newOptions[i] = options[i]\n      }\n    }\n    newOptions.crop = true\n    width = img.naturalWidth || img.width\n    height = img.naturalHeight || img.height\n    if (width / height > aspectRatio) {\n      newOptions.maxWidth = height * aspectRatio\n      newOptions.maxHeight = height\n    } else {\n      newOptions.maxWidth = width\n      newOptions.maxHeight = width / aspectRatio\n    }\n    return newOptions\n  }\n\n  // Canvas render method, allows to implement a different rendering algorithm:\n  loadImage.drawImage = function (\n    img,\n    canvas,\n    sourceX,\n    sourceY,\n    sourceWidth,\n    sourceHeight,\n    destWidth,\n    destHeight,\n    options\n  ) {\n    var ctx = canvas.getContext('2d')\n    if (options.imageSmoothingEnabled === false) {\n      ctx.msImageSmoothingEnabled = false\n      ctx.imageSmoothingEnabled = false\n    } else if (options.imageSmoothingQuality) {\n      ctx.imageSmoothingQuality = options.imageSmoothingQuality\n    }\n    ctx.drawImage(\n      img,\n      sourceX,\n      sourceY,\n      sourceWidth,\n      sourceHeight,\n      0,\n      0,\n      destWidth,\n      destHeight\n    )\n    return ctx\n  }\n\n  // Determines if the target image should be a canvas element:\n  loadImage.requiresCanvas = function (options) {\n    return options.canvas || options.crop || !!options.aspectRatio\n  }\n\n  // Scales and/or crops the given image (img or canvas HTML element)\n  // using the given options:\n  loadImage.scale = function (img, options, data) {\n    // eslint-disable-next-line no-param-reassign\n    options = options || {}\n    // eslint-disable-next-line no-param-reassign\n    data = data || {}\n    var useCanvas =\n      img.getContext ||\n      (loadImage.requiresCanvas(options) &&\n        !!loadImage.global.HTMLCanvasElement)\n    var width = img.naturalWidth || img.width\n    var height = img.naturalHeight || img.height\n    var destWidth = width\n    var destHeight = height\n    var maxWidth\n    var maxHeight\n    var minWidth\n    var minHeight\n    var sourceWidth\n    var sourceHeight\n    var sourceX\n    var sourceY\n    var pixelRatio\n    var downsamplingRatio\n    var tmp\n    var canvas\n    /**\n     * Scales up image dimensions\n     */\n    function scaleUp() {\n      var scale = Math.max(\n        (minWidth || destWidth) / destWidth,\n        (minHeight || destHeight) / destHeight\n      )\n      if (scale > 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    /**\n     * Scales down image dimensions\n     */\n    function scaleDown() {\n      var scale = Math.min(\n        (maxWidth || destWidth) / destWidth,\n        (maxHeight || destHeight) / destHeight\n      )\n      if (scale < 1) {\n        destWidth *= scale\n        destHeight *= scale\n      }\n    }\n    if (useCanvas) {\n      // eslint-disable-next-line no-param-reassign\n      options = loadImage.getTransformedOptions(img, options, data)\n      sourceX = options.left || 0\n      sourceY = options.top || 0\n      if (options.sourceWidth) {\n        sourceWidth = options.sourceWidth\n        if (options.right !== undefined && options.left === undefined) {\n          sourceX = width - sourceWidth - options.right\n        }\n      } else {\n        sourceWidth = width - sourceX - (options.right || 0)\n      }\n      if (options.sourceHeight) {\n        sourceHeight = options.sourceHeight\n        if (options.bottom !== undefined && options.top === undefined) {\n          sourceY = height - sourceHeight - options.bottom\n        }\n      } else {\n        sourceHeight = height - sourceY - (options.bottom || 0)\n      }\n      destWidth = sourceWidth\n      destHeight = sourceHeight\n    }\n    maxWidth = options.maxWidth\n    maxHeight = options.maxHeight\n    minWidth = options.minWidth\n    minHeight = options.minHeight\n    if (useCanvas && maxWidth && maxHeight && options.crop) {\n      destWidth = maxWidth\n      destHeight = maxHeight\n      tmp = sourceWidth / sourceHeight - maxWidth / maxHeight\n      if (tmp < 0) {\n        sourceHeight = (maxHeight * sourceWidth) / maxWidth\n        if (options.top === undefined && options.bottom === undefined) {\n          sourceY = (height - sourceHeight) / 2\n        }\n      } else if (tmp > 0) {\n        sourceWidth = (maxWidth * sourceHeight) / maxHeight\n        if (options.left === undefined && options.right === undefined) {\n          sourceX = (width - sourceWidth) / 2\n        }\n      }\n    } else {\n      if (options.contain || options.cover) {\n        minWidth = maxWidth = maxWidth || minWidth\n        minHeight = maxHeight = maxHeight || minHeight\n      }\n      if (options.cover) {\n        scaleDown()\n        scaleUp()\n      } else {\n        scaleUp()\n        scaleDown()\n      }\n    }\n    if (useCanvas) {\n      pixelRatio = options.pixelRatio\n      if (\n        pixelRatio > 1 &&\n        // Check if the image has not yet had the device pixel ratio applied:\n        !(\n          img.style.width &&\n          Math.floor(parseFloat(img.style.width, 10)) ===\n            Math.floor(width / pixelRatio)\n        )\n      ) {\n        destWidth *= pixelRatio\n        destHeight *= pixelRatio\n      }\n      // Check if workaround for Chromium orientation crop bug is required:\n      // https://bugs.chromium.org/p/chromium/issues/detail?id=1074354\n      if (\n        loadImage.orientationCropBug &&\n        !img.getContext &&\n        (sourceX || sourceY || sourceWidth !== width || sourceHeight !== height)\n      ) {\n        // Write the complete source image to an intermediate canvas first:\n        tmp = img\n        // eslint-disable-next-line no-param-reassign\n        img = loadImage.createCanvas(width, height, true)\n        loadImage.drawImage(\n          tmp,\n          img,\n          0,\n          0,\n          width,\n          height,\n          width,\n          height,\n          options\n        )\n      }\n      downsamplingRatio = options.downsamplingRatio\n      if (\n        downsamplingRatio > 0 &&\n        downsamplingRatio < 1 &&\n        destWidth < sourceWidth &&\n        destHeight < sourceHeight\n      ) {\n        while (sourceWidth * downsamplingRatio > destWidth) {\n          canvas = loadImage.createCanvas(\n            sourceWidth * downsamplingRatio,\n            sourceHeight * downsamplingRatio,\n            true\n          )\n          loadImage.drawImage(\n            img,\n            canvas,\n            sourceX,\n            sourceY,\n            sourceWidth,\n            sourceHeight,\n            canvas.width,\n            canvas.height,\n            options\n          )\n          sourceX = 0\n          sourceY = 0\n          sourceWidth = canvas.width\n          sourceHeight = canvas.height\n          // eslint-disable-next-line no-param-reassign\n          img = canvas\n        }\n      }\n      canvas = loadImage.createCanvas(destWidth, destHeight)\n      loadImage.transformCoordinates(canvas, options, data)\n      if (pixelRatio > 1) {\n        canvas.style.width = canvas.width / pixelRatio + 'px'\n      }\n      loadImage\n        .drawImage(\n          img,\n          canvas,\n          sourceX,\n          sourceY,\n          sourceWidth,\n          sourceHeight,\n          destWidth,\n          destHeight,\n          options\n        )\n        .setTransform(1, 0, 0, 1, 0, 0) // reset to the identity matrix\n      return canvas\n    }\n    img.width = destWidth\n    img.height = destHeight\n    return img\n  }\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image.js":"/*\n * JavaScript Load Image\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, Promise */\n\n;(function ($) {\n  'use strict'\n\n  var urlAPI = $.URL || $.webkitURL\n\n  /**\n   * Creates an object URL for a given File object.\n   *\n   * @param {Blob} blob Blob object\n   * @returns {string|boolean} Returns object URL if API exists, else false.\n   */\n  function createObjectURL(blob) {\n    return urlAPI ? urlAPI.createObjectURL(blob) : false\n  }\n\n  /**\n   * Revokes a given object URL.\n   *\n   * @param {string} url Blob object URL\n   * @returns {undefined|boolean} Returns undefined if API exists, else false.\n   */\n  function revokeObjectURL(url) {\n    return urlAPI ? urlAPI.revokeObjectURL(url) : false\n  }\n\n  /**\n   * Helper function to revoke an object URL\n   *\n   * @param {string} url Blob Object URL\n   * @param {object} [options] Options object\n   */\n  function revokeHelper(url, options) {\n    if (url && url.slice(0, 5) === 'blob:' && !(options && options.noRevoke)) {\n      revokeObjectURL(url)\n    }\n  }\n\n  /**\n   * Loads a given File object via FileReader interface.\n   *\n   * @param {Blob} file Blob object\n   * @param {Function} onload Load event callback\n   * @param {Function} [onerror] Error/Abort event callback\n   * @param {string} [method=readAsDataURL] FileReader method\n   * @returns {FileReader|boolean} Returns FileReader if API exists, else false.\n   */\n  function readFile(file, onload, onerror, method) {\n    if (!$.FileReader) return false\n    var reader = new FileReader()\n    reader.onload = function () {\n      onload.call(reader, this.result)\n    }\n    if (onerror) {\n      reader.onabort = reader.onerror = function () {\n        onerror.call(reader, this.error)\n      }\n    }\n    var readerMethod = reader[method || 'readAsDataURL']\n    if (readerMethod) {\n      readerMethod.call(reader, file)\n      return reader\n    }\n  }\n\n  /**\n   * Cross-frame instanceof check.\n   *\n   * @param {string} type Instance type\n   * @param {object} obj Object instance\n   * @returns {boolean} Returns true if the object is of the given instance.\n   */\n  function isInstanceOf(type, obj) {\n    // Cross-frame instanceof check\n    return Object.prototype.toString.call(obj) === '[object ' + type + ']'\n  }\n\n  /**\n   * @typedef { HTMLImageElement|HTMLCanvasElement } Result\n   */\n\n  /**\n   * Loads an image for a given File object.\n   *\n   * @param {Blob|string} file Blob object or image URL\n   * @param {Function|object} [callback] Image load event callback or options\n   * @param {object} [options] Options object\n   * @returns {HTMLImageElement|FileReader|Promise<Result>} Object\n   */\n  function loadImage(file, callback, options) {\n    /**\n     * Promise executor\n     *\n     * @param {Function} resolve Resolution function\n     * @param {Function} reject Rejection function\n     * @returns {HTMLImageElement|FileReader} Object\n     */\n    function executor(resolve, reject) {\n      var img = document.createElement('img')\n      var url\n      /**\n       * Callback for the fetchBlob call.\n       *\n       * @param {HTMLImageElement|HTMLCanvasElement} img Error object\n       * @param {object} data Data object\n       * @returns {undefined} Undefined\n       */\n      function resolveWrapper(img, data) {\n        if (resolve === reject) {\n          // Not using Promises\n          if (resolve) resolve(img, data)\n          return\n        } else if (img instanceof Error) {\n          reject(img)\n          return\n        }\n        data = data || {} // eslint-disable-line no-param-reassign\n        data.image = img\n        resolve(data)\n      }\n      /**\n       * Callback for the fetchBlob call.\n       *\n       * @param {Blob} blob Blob object\n       * @param {Error} err Error object\n       */\n      function fetchBlobCallback(blob, err) {\n        if (err && $.console) console.log(err) // eslint-disable-line no-console\n        if (blob && isInstanceOf('Blob', blob)) {\n          file = blob // eslint-disable-line no-param-reassign\n          url = createObjectURL(file)\n        } else {\n          url = file\n          if (options && options.crossOrigin) {\n            img.crossOrigin = options.crossOrigin\n          }\n        }\n        img.src = url\n      }\n      img.onerror = function (event) {\n        revokeHelper(url, options)\n        if (reject) reject.call(img, event)\n      }\n      img.onload = function () {\n        revokeHelper(url, options)\n        var data = {\n          originalWidth: img.naturalWidth || img.width,\n          originalHeight: img.naturalHeight || img.height\n        }\n        try {\n          loadImage.transform(img, options, resolveWrapper, file, data)\n        } catch (error) {\n          if (reject) reject(error)\n        }\n      }\n      if (typeof file === 'string') {\n        if (loadImage.requiresMetaData(options)) {\n          loadImage.fetchBlob(file, fetchBlobCallback, options)\n        } else {\n          fetchBlobCallback()\n        }\n        return img\n      } else if (isInstanceOf('Blob', file) || isInstanceOf('File', file)) {\n        url = createObjectURL(file)\n        if (url) {\n          img.src = url\n          return img\n        }\n        return readFile(\n          file,\n          function (url) {\n            img.src = url\n          },\n          reject\n        )\n      }\n    }\n    if ($.Promise && typeof callback !== 'function') {\n      options = callback // eslint-disable-line no-param-reassign\n      return new Promise(executor)\n    }\n    return executor(callback, callback)\n  }\n\n  // Determines if metadata should be loaded automatically.\n  // Requires the load image meta extension to load metadata.\n  loadImage.requiresMetaData = function (options) {\n    return options && options.meta\n  }\n\n  // If the callback given to this function returns a blob, it is used as image\n  // source instead of the original url and overrides the file argument used in\n  // the onload and onerror event callbacks:\n  loadImage.fetchBlob = function (url, callback) {\n    callback()\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    callback(img, data)\n  }\n\n  loadImage.global = $\n  loadImage.readFile = readFile\n  loadImage.isInstanceOf = isInstanceOf\n  loadImage.createObjectURL = createObjectURL\n  loadImage.revokeObjectURL = revokeObjectURL\n\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return loadImage\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = loadImage\n  } else {\n    $.loadImage = loadImage\n  }\n})((typeof window !== 'undefined' && window) || this)\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/index.js":"/* global module, require */\n\nmodule.exports = require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image')\n\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-scale')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-fetch')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-exif-map')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc-map')\nrequire('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-orientation')\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc-map.js":"/*\n * JavaScript Load Image IPTC Map\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * Copyright 2018, Dave Bevan\n *\n * IPTC tags mapping based on\n * https://iptc.org/standards/photo-metadata\n * https://exiftool.org/TagNames/IPTC.html\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image', 'Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'), require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-iptc'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var IptcMapProto = loadImage.IptcMap.prototype\n\n  IptcMapProto.tags = {\n    0: 'ApplicationRecordVersion',\n    3: 'ObjectTypeReference',\n    4: 'ObjectAttributeReference',\n    5: 'ObjectName',\n    7: 'EditStatus',\n    8: 'EditorialUpdate',\n    10: 'Urgency',\n    12: 'SubjectReference',\n    15: 'Category',\n    20: 'SupplementalCategories',\n    22: 'FixtureIdentifier',\n    25: 'Keywords',\n    26: 'ContentLocationCode',\n    27: 'ContentLocationName',\n    30: 'ReleaseDate',\n    35: 'ReleaseTime',\n    37: 'ExpirationDate',\n    38: 'ExpirationTime',\n    40: 'SpecialInstructions',\n    42: 'ActionAdvised',\n    45: 'ReferenceService',\n    47: 'ReferenceDate',\n    50: 'ReferenceNumber',\n    55: 'DateCreated',\n    60: 'TimeCreated',\n    62: 'DigitalCreationDate',\n    63: 'DigitalCreationTime',\n    65: 'OriginatingProgram',\n    70: 'ProgramVersion',\n    75: 'ObjectCycle',\n    80: 'Byline',\n    85: 'BylineTitle',\n    90: 'City',\n    92: 'Sublocation',\n    95: 'State',\n    100: 'CountryCode',\n    101: 'Country',\n    103: 'OriginalTransmissionReference',\n    105: 'Headline',\n    110: 'Credit',\n    115: 'Source',\n    116: 'CopyrightNotice',\n    118: 'Contact',\n    120: 'Caption',\n    121: 'LocalCaption',\n    122: 'Writer',\n    125: 'RasterizedCaption',\n    130: 'ImageType',\n    131: 'ImageOrientation',\n    135: 'LanguageIdentifier',\n    150: 'AudioType',\n    151: 'AudioSamplingRate',\n    152: 'AudioSamplingResolution',\n    153: 'AudioDuration',\n    154: 'AudioOutcue',\n    184: 'JobID',\n    185: 'MasterDocumentID',\n    186: 'ShortDocumentID',\n    187: 'UniqueDocumentID',\n    188: 'OwnerID',\n    200: 'ObjectPreviewFileFormat',\n    201: 'ObjectPreviewFileVersion',\n    202: 'ObjectPreviewData',\n    221: 'Prefs',\n    225: 'ClassifyState',\n    228: 'SimilarityIndex',\n    230: 'DocumentNotes',\n    231: 'DocumentHistory',\n    232: 'ExifCameraInfo',\n    255: 'CatalogSets'\n  }\n\n  IptcMapProto.stringValues = {\n    10: {\n      0: '0 (reserved)',\n      1: '1 (most urgent)',\n      2: '2',\n      3: '3',\n      4: '4',\n      5: '5 (normal urgency)',\n      6: '6',\n      7: '7',\n      8: '8 (least urgent)',\n      9: '9 (user-defined priority)'\n    },\n    75: {\n      a: 'Morning',\n      b: 'Both Morning and Evening',\n      p: 'Evening'\n    },\n    131: {\n      L: 'Landscape',\n      P: 'Portrait',\n      S: 'Square'\n    }\n  }\n\n  IptcMapProto.getText = function (id) {\n    var value = this.get(id)\n    var tagCode = this.map[id]\n    var stringValue = this.stringValues[tagCode]\n    if (stringValue) return stringValue[value]\n    return String(value)\n  }\n\n  IptcMapProto.getAll = function () {\n    var map = {}\n    var prop\n    var name\n    for (prop in this) {\n      if (Object.prototype.hasOwnProperty.call(this, prop)) {\n        name = this.tags[prop]\n        if (name) map[name] = this.getText(name)\n      }\n    }\n    return map\n  }\n\n  IptcMapProto.getName = function (tagCode) {\n    return this.tags[tagCode]\n  }\n\n  // Extend the map of tag names to tag codes:\n  ;(function () {\n    var tags = IptcMapProto.tags\n    var map = IptcMapProto.map || {}\n    var prop\n    // Map the tag names to tags:\n    for (prop in tags) {\n      if (Object.prototype.hasOwnProperty.call(tags, prop)) {\n        map[tags[prop]] = Number(prop)\n      }\n    }\n  })()\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image-meta.js":"/*\n * JavaScript Load Image Meta\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * Image metadata handling implementation\n * based on the help and contribution of\n * Achim St\u00f6hr.\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, module, require, Promise, DataView, Uint8Array, ArrayBuffer */\n\n;(function (factory) {\n  'use strict'\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'], factory)\n  } else if (typeof module === 'object' && module.exports) {\n    factory(require('Mageplaza_Core/lib/fileUploader/vendor/blueimp-load-image/js/load-image'))\n  } else {\n    // Browser globals:\n    factory(window.loadImage)\n  }\n})(function (loadImage) {\n  'use strict'\n\n  var global = loadImage.global\n  var originalTransform = loadImage.transform\n\n  var blobSlice =\n    global.Blob &&\n    (Blob.prototype.slice ||\n      Blob.prototype.webkitSlice ||\n      Blob.prototype.mozSlice)\n\n  var bufferSlice =\n    (global.ArrayBuffer && ArrayBuffer.prototype.slice) ||\n    function (begin, end) {\n      // Polyfill for IE10, which does not support ArrayBuffer.slice\n      // eslint-disable-next-line no-param-reassign\n      end = end || this.byteLength - begin\n      var arr1 = new Uint8Array(this, begin, end)\n      var arr2 = new Uint8Array(end)\n      arr2.set(arr1)\n      return arr2.buffer\n    }\n\n  var metaDataParsers = {\n    jpeg: {\n      0xffe1: [], // APP1 marker\n      0xffed: [] // APP13 marker\n    }\n  }\n\n  /**\n   * Parses image metadata and calls the callback with an object argument\n   * with the following property:\n   * - imageHead: The complete image head as ArrayBuffer\n   * The options argument accepts an object and supports the following\n   * properties:\n   * - maxMetaDataSize: Defines the maximum number of bytes to parse.\n   * - disableImageHead: Disables creating the imageHead property.\n   *\n   * @param {Blob} file Blob object\n   * @param {Function} [callback] Callback function\n   * @param {object} [options] Parsing options\n   * @param {object} [data] Result data object\n   * @returns {Promise<object>|undefined} Returns Promise if no callback given.\n   */\n  function parseMetaData(file, callback, options, data) {\n    var that = this\n    /**\n     * Promise executor\n     *\n     * @param {Function} resolve Resolution function\n     * @param {Function} reject Rejection function\n     * @returns {undefined} Undefined\n     */\n    function executor(resolve, reject) {\n      if (\n        !(\n          global.DataView &&\n          blobSlice &&\n          file &&\n          file.size >= 12 &&\n          file.type === 'image/jpeg'\n        )\n      ) {\n        // Nothing to parse\n        return resolve(data)\n      }\n      // 256 KiB should contain all EXIF/ICC/IPTC segments:\n      var maxMetaDataSize = options.maxMetaDataSize || 262144\n      if (\n        !loadImage.readFile(\n          blobSlice.call(file, 0, maxMetaDataSize),\n          function (buffer) {\n            // Note on endianness:\n            // Since the marker and length bytes in JPEG files are always\n            // stored in big endian order, we can leave the endian parameter\n            // of the DataView methods undefined, defaulting to big endian.\n            var dataView = new DataView(buffer)\n            // Check for the JPEG marker (0xffd8):\n            if (dataView.getUint16(0) !== 0xffd8) {\n              return reject(\n                new Error('Invalid JPEG file: Missing JPEG marker.')\n              )\n            }\n            var offset = 2\n            var maxOffset = dataView.byteLength - 4\n            var headLength = offset\n            var markerBytes\n            var markerLength\n            var parsers\n            var i\n            while (offset < maxOffset) {\n              markerBytes = dataView.getUint16(offset)\n              // Search for APPn (0xffeN) and COM (0xfffe) markers,\n              // which contain application-specific metadata like\n              // Exif, ICC and IPTC data and text comments:\n              if (\n                (markerBytes >= 0xffe0 && markerBytes <= 0xffef) ||\n                markerBytes === 0xfffe\n              ) {\n                // The marker bytes (2) are always followed by\n                // the length bytes (2), indicating the length of the\n                // marker segment, which includes the length bytes,\n                // but not the marker bytes, so we add 2:\n                markerLength = dataView.getUint16(offset + 2) + 2\n                if (offset + markerLength > dataView.byteLength) {\n                  // eslint-disable-next-line no-console\n                  console.log('Invalid JPEG metadata: Invalid segment size.')\n                  break\n                }\n                parsers = metaDataParsers.jpeg[markerBytes]\n                if (parsers && !options.disableMetaDataParsers) {\n                  for (i = 0; i < parsers.length; i += 1) {\n                    parsers[i].call(\n                      that,\n                      dataView,\n                      offset,\n                      markerLength,\n                      data,\n                      options\n                    )\n                  }\n                }\n                offset += markerLength\n                headLength = offset\n              } else {\n                // Not an APPn or COM marker, probably safe to\n                // assume that this is the end of the metadata\n                break\n              }\n            }\n            // Meta length must be longer than JPEG marker (2)\n            // plus APPn marker (2), followed by length bytes (2):\n            if (!options.disableImageHead && headLength > 6) {\n              data.imageHead = bufferSlice.call(buffer, 0, headLength)\n            }\n            resolve(data)\n          },\n          reject,\n          'readAsArrayBuffer'\n        )\n      ) {\n        // No support for the FileReader interface, nothing to parse\n        resolve(data)\n      }\n    }\n    options = options || {} // eslint-disable-line no-param-reassign\n    if (global.Promise && typeof callback !== 'function') {\n      options = callback || {} // eslint-disable-line no-param-reassign\n      data = options // eslint-disable-line no-param-reassign\n      return new Promise(executor)\n    }\n    data = data || {} // eslint-disable-line no-param-reassign\n    return executor(callback, callback)\n  }\n\n  /**\n   * Replaces the head of a JPEG Blob\n   *\n   * @param {Blob} blob Blob object\n   * @param {ArrayBuffer} oldHead Old JPEG head\n   * @param {ArrayBuffer} newHead New JPEG head\n   * @returns {Blob} Combined Blob\n   */\n  function replaceJPEGHead(blob, oldHead, newHead) {\n    if (!blob || !oldHead || !newHead) return null\n    return new Blob([newHead, blobSlice.call(blob, oldHead.byteLength)], {\n      type: 'image/jpeg'\n    })\n  }\n\n  /**\n   * Replaces the image head of a JPEG blob with the given one.\n   * Returns a Promise or calls the callback with the new Blob.\n   *\n   * @param {Blob} blob Blob object\n   * @param {ArrayBuffer} head New JPEG head\n   * @param {Function} [callback] Callback function\n   * @returns {Promise<Blob|null>|undefined} Combined Blob\n   */\n  function replaceHead(blob, head, callback) {\n    var options = { maxMetaDataSize: 256, disableMetaDataParsers: true }\n    if (!callback && global.Promise) {\n      return parseMetaData(blob, options).then(function (data) {\n        return replaceJPEGHead(blob, data.imageHead, head)\n      })\n    }\n    parseMetaData(\n      blob,\n      function (data) {\n        callback(replaceJPEGHead(blob, data.imageHead, head))\n      },\n      options\n    )\n  }\n\n  loadImage.transform = function (img, options, callback, file, data) {\n    if (loadImage.requiresMetaData(options)) {\n      data = data || {} // eslint-disable-line no-param-reassign\n      parseMetaData(\n        file,\n        function (result) {\n          if (result !== data) {\n            // eslint-disable-next-line no-console\n            if (global.console) console.log(result)\n            result = data // eslint-disable-line no-param-reassign\n          }\n          originalTransform.call(\n            loadImage,\n            img,\n            options,\n            callback,\n            file,\n            result\n          )\n        },\n        options,\n        data\n      )\n    } else {\n      originalTransform.apply(loadImage, arguments)\n    }\n  }\n\n  loadImage.blobSlice = blobSlice\n  loadImage.bufferSlice = bufferSlice\n  loadImage.replaceHead = replaceHead\n  loadImage.parseMetaData = parseMetaData\n  loadImage.metaDataParsers = metaDataParsers\n})\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-canvas-to-blob/js/canvas-to-blob.js":"/*\n * JavaScript Canvas to Blob\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on stackoverflow user Stoive's code snippet:\n * http://stackoverflow.com/q/4998908\n */\n\n/* global define, Uint8Array, ArrayBuffer, module */\n\n;(function (window) {\n  'use strict'\n\n  var CanvasPrototype =\n    window.HTMLCanvasElement && window.HTMLCanvasElement.prototype\n  var hasBlobConstructor =\n    window.Blob &&\n    (function () {\n      try {\n        return Boolean(new Blob())\n      } catch (e) {\n        return false\n      }\n    })()\n  var hasArrayBufferViewSupport =\n    hasBlobConstructor &&\n    window.Uint8Array &&\n    (function () {\n      try {\n        return new Blob([new Uint8Array(100)]).size === 100\n      } catch (e) {\n        return false\n      }\n    })()\n  var BlobBuilder =\n    window.BlobBuilder ||\n    window.WebKitBlobBuilder ||\n    window.MozBlobBuilder ||\n    window.MSBlobBuilder\n  var dataURIPattern = /^data:((.*?)(;charset=.*?)?)(;base64)?,/\n  var dataURLtoBlob =\n    (hasBlobConstructor || BlobBuilder) &&\n    window.atob &&\n    window.ArrayBuffer &&\n    window.Uint8Array &&\n    function (dataURI) {\n      var matches,\n        mediaType,\n        isBase64,\n        dataString,\n        byteString,\n        arrayBuffer,\n        intArray,\n        i,\n        bb\n      // Parse the dataURI components as per RFC 2397\n      matches = dataURI.match(dataURIPattern)\n      if (!matches) {\n        throw new Error('invalid data URI')\n      }\n      // Default to text/plain;charset=US-ASCII\n      mediaType = matches[2]\n        ? matches[1]\n        : 'text/plain' + (matches[3] || ';charset=US-ASCII')\n      isBase64 = !!matches[4]\n      dataString = dataURI.slice(matches[0].length)\n      if (isBase64) {\n        // Convert base64 to raw binary data held in a string:\n        byteString = atob(dataString)\n      } else {\n        // Convert base64/URLEncoded data component to raw binary:\n        byteString = decodeURIComponent(dataString)\n      }\n      // Write the bytes of the string to an ArrayBuffer:\n      arrayBuffer = new ArrayBuffer(byteString.length)\n      intArray = new Uint8Array(arrayBuffer)\n      for (i = 0; i < byteString.length; i += 1) {\n        intArray[i] = byteString.charCodeAt(i)\n      }\n      // Write the ArrayBuffer (or ArrayBufferView) to a blob:\n      if (hasBlobConstructor) {\n        return new Blob([hasArrayBufferViewSupport ? intArray : arrayBuffer], {\n          type: mediaType\n        })\n      }\n      bb = new BlobBuilder()\n      bb.append(arrayBuffer)\n      return bb.getBlob(mediaType)\n    }\n  if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {\n    if (CanvasPrototype.mozGetAsFile) {\n      CanvasPrototype.toBlob = function (callback, type, quality) {\n        var self = this\n        setTimeout(function () {\n          if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {\n            callback(dataURLtoBlob(self.toDataURL(type, quality)))\n          } else {\n            callback(self.mozGetAsFile('blob', type))\n          }\n        })\n      }\n    } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {\n      if (CanvasPrototype.msToBlob) {\n        CanvasPrototype.toBlob = function (callback, type, quality) {\n          var self = this\n          setTimeout(function () {\n            if (\n              ((type && type !== 'image/png') || quality) &&\n              CanvasPrototype.toDataURL &&\n              dataURLtoBlob\n            ) {\n              callback(dataURLtoBlob(self.toDataURL(type, quality)))\n            } else {\n              callback(self.msToBlob(type))\n            }\n          })\n        }\n      } else {\n        CanvasPrototype.toBlob = function (callback, type, quality) {\n          var self = this\n          setTimeout(function () {\n            callback(dataURLtoBlob(self.toDataURL(type, quality)))\n          })\n        }\n      }\n    }\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return dataURLtoBlob\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = dataURLtoBlob\n  } else {\n    window.dataURLtoBlob = dataURLtoBlob\n  }\n})(window)\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/runtime.js":"/*\n * JavaScript Templates Runtime\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define */\n\n/* eslint-disable strict */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (id, data) {\n    var f = tmpl.cache[id]\n    return data\n      ? f(data, tmpl)\n      : function (data) {\n          return f(data, tmpl)\n        }\n  }\n  tmpl.cache = {}\n  tmpl.encReg = /[<>&\"'\\x00]/g // eslint-disable-line no-control-regex\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    // eslint-disable-next-line eqeqeq\n    return (s == null ? '' : '' + s).replace(tmpl.encReg, function (c) {\n      return tmpl.encMap[c] || ''\n    })\n  }\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n})(this)\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/tmpl.js":"/*\n * JavaScript Templates\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Inspired by John Resig's JavaScript Micro-Templating:\n * http://ejohn.org/blog/javascript-micro-templating/\n */\n\n/* global define */\n\n/* eslint-disable strict */\n\n;(function ($) {\n  'use strict'\n  var tmpl = function (str, data) {\n    var f = !/[^\\w\\-.:]/.test(str)\n      ? (tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str)))\n      : new Function( // eslint-disable-line no-new-func\n          tmpl.arg + ',tmpl',\n          'var _e=tmpl.encode' +\n            tmpl.helper +\n            \",_s='\" +\n            str.replace(tmpl.regexp, tmpl.func) +\n            \"';return _s;\"\n        )\n    return data\n      ? f(data, tmpl)\n      : function (data) {\n          return f(data, tmpl)\n        }\n  }\n  tmpl.cache = {}\n  tmpl.load = function (id) {\n    return document.getElementById(id).innerHTML\n  }\n  tmpl.regexp = /([\\s'\\\\])(?!(?:[^{]|\\{(?!%))*%\\})|(?:\\{%(=|#)([\\s\\S]+?)%\\})|(\\{%)|(%\\})/g\n  tmpl.func = function (s, p1, p2, p3, p4, p5) {\n    if (p1) {\n      // whitespace, quote and backspace in HTML context\n      return (\n        {\n          '\\n': '\\\\n',\n          '\\r': '\\\\r',\n          '\\t': '\\\\t',\n          ' ': ' '\n        }[p1] || '\\\\' + p1\n      )\n    }\n    if (p2) {\n      // interpolation: {%=prop%}, or unescaped: {%#prop%}\n      if (p2 === '=') {\n        return \"'+_e(\" + p3 + \")+'\"\n      }\n      return \"'+(\" + p3 + \"==null?'':\" + p3 + \")+'\"\n    }\n    if (p4) {\n      // evaluation start tag: {%\n      return \"';\"\n    }\n    if (p5) {\n      // evaluation end tag: %}\n      return \"_s+='\"\n    }\n  }\n  tmpl.encReg = /[<>&\"'\\x00]/g // eslint-disable-line no-control-regex\n  tmpl.encMap = {\n    '<': '&lt;',\n    '>': '&gt;',\n    '&': '&amp;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  }\n  tmpl.encode = function (s) {\n    // eslint-disable-next-line eqeqeq\n    return (s == null ? '' : '' + s).replace(tmpl.encReg, function (c) {\n      return tmpl.encMap[c] || ''\n    })\n  }\n  tmpl.arg = 'o'\n  tmpl.helper =\n    \",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}\" +\n    ',include=function(s,d){_s+=tmpl(s,d);}'\n  if (typeof define === 'function' && define.amd) {\n    define(function () {\n      return tmpl\n    })\n  } else if (typeof module === 'object' && module.exports) {\n    module.exports = tmpl\n  } else {\n    $.tmpl = tmpl\n  }\n})(this)\n","Mageplaza_Core/lib/fileUploader/vendor/blueimp-tmpl/js/compile.js":"#!/usr/bin/env node\n/*\n * JavaScript Templates Compiler\n * https://github.com/blueimp/JavaScript-Templates\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* eslint-disable strict */\n/* eslint-disable no-console */\n\n;(function () {\n  'use strict'\n  var path = require('path')\n  var tmpl = require(path.join(__dirname, 'tmpl.js'))\n  var fs = require('fs')\n  // Retrieve the content of the minimal runtime:\n  var runtime = fs.readFileSync(path.join(__dirname, 'runtime.js'), 'utf8')\n  // A regular expression to parse templates from script tags in a HTML page:\n  var regexp = /<script( id=\"([\\w-]+)\")? type=\"text\\/x-tmpl\"( id=\"([\\w-]+)\")?>([\\s\\S]+?)<\\/script>/gi\n  // A regular expression to match the helper function names:\n  var helperRegexp = new RegExp(\n    tmpl.helper.match(/\\w+(?=\\s*=\\s*function\\s*\\()/g).join('\\\\s*\\\\(|') +\n      '\\\\s*\\\\('\n  )\n  // A list to store the function bodies:\n  var list = []\n  var code\n  // Extend the Templating engine with a print method for the generated functions:\n  tmpl.print = function (str) {\n    // Only add helper functions if they are used inside of the template:\n    var helper = helperRegexp.test(str) ? tmpl.helper : ''\n    var body = str.replace(tmpl.regexp, tmpl.func)\n    if (helper || /_e\\s*\\(/.test(body)) {\n      helper = '_e=tmpl.encode' + helper + ','\n    }\n    return (\n      'function(' +\n      tmpl.arg +\n      ',tmpl){' +\n      ('var ' + helper + \"_s='\" + body + \"';return _s;\")\n        .split(\"_s+='';\")\n        .join('') +\n      '}'\n    )\n  }\n  // Loop through the command line arguments:\n  process.argv.forEach(function (file, index) {\n    var listLength = list.length\n    var stats\n    var content\n    var result\n    var id\n    // Skip the first two arguments, which are \"node\" and the script:\n    if (index > 1) {\n      stats = fs.statSync(file)\n      if (!stats.isFile()) {\n        console.error(file + ' is not a file.')\n        return\n      }\n      content = fs.readFileSync(file, 'utf8')\n      // eslint-disable-next-line no-constant-condition\n      while (true) {\n        // Find templates in script tags:\n        result = regexp.exec(content)\n        if (!result) {\n          break\n        }\n        id = result[2] || result[4]\n        list.push(\"'\" + id + \"':\" + tmpl.print(result[5]))\n      }\n      if (listLength === list.length) {\n        // No template script tags found, use the complete content:\n        id = path.basename(file, path.extname(file))\n        list.push(\"'\" + id + \"':\" + tmpl.print(content))\n      }\n    }\n  })\n  if (!list.length) {\n    console.error('Missing input file.')\n    return\n  }\n  // Combine the generated functions as cache of the minimal runtime:\n  code = runtime.replace('{}', '{' + list.join(',') + '}')\n  // Print the resulting code to the console output:\n  console.log(code)\n})()\n","Mageplaza_Core/lib/fileUploader/cors/jquery.postmessage-transport.js":"/*\n * jQuery postMessage Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n */\n\n/* global define, require */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(require('jquery'));\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})(function ($) {\n  'use strict';\n\n  var counter = 0,\n    names = [\n      'accepts',\n      'cache',\n      'contents',\n      'contentType',\n      'crossDomain',\n      'data',\n      'dataType',\n      'headers',\n      'ifModified',\n      'mimeType',\n      'password',\n      'processData',\n      'timeout',\n      'traditional',\n      'type',\n      'url',\n      'username'\n    ],\n    convert = function (p) {\n      return p;\n    };\n\n  $.ajaxSetup({\n    converters: {\n      'postmessage text': convert,\n      'postmessage json': convert,\n      'postmessage html': convert\n    }\n  });\n\n  $.ajaxTransport('postmessage', function (options) {\n    if (options.postMessage && window.postMessage) {\n      var iframe,\n        loc = $('<a></a>').prop('href', options.postMessage)[0],\n        target = loc.protocol + '//' + loc.host,\n        xhrUpload = options.xhr().upload;\n      // IE always includes the port for the host property of a link\n      // element, but not in the location.host or origin property for the\n      // default http port 80 and https port 443, so we strip it:\n      if (/^(http:\\/\\/.+:80)|(https:\\/\\/.+:443)$/.test(target)) {\n        target = target.replace(/:(80|443)$/, '');\n      }\n      return {\n        send: function (_, completeCallback) {\n          counter += 1;\n          var message = {\n              id: 'postmessage-transport-' + counter\n            },\n            eventName = 'message.' + message.id;\n          iframe = $(\n            '<iframe style=\"display:none;\" src=\"' +\n              options.postMessage +\n              '\" name=\"' +\n              message.id +\n              '\"></iframe>'\n          )\n            .on('load', function () {\n              $.each(names, function (i, name) {\n                message[name] = options[name];\n              });\n              message.dataType = message.dataType.replace('postmessage ', '');\n              $(window).on(eventName, function (event) {\n                var e = event.originalEvent;\n                var data = e.data;\n                var ev;\n                if (e.origin === target && data.id === message.id) {\n                  if (data.type === 'progress') {\n                    ev = document.createEvent('Event');\n                    ev.initEvent(data.type, false, true);\n                    $.extend(ev, data);\n                    xhrUpload.dispatchEvent(ev);\n                  } else {\n                    completeCallback(\n                      data.status,\n                      data.statusText,\n                      { postmessage: data.result },\n                      data.headers\n                    );\n                    iframe.remove();\n                    $(window).off(eventName);\n                  }\n                }\n              });\n              iframe[0].contentWindow.postMessage(message, target);\n            })\n            .appendTo(document.body);\n        },\n        abort: function () {\n          if (iframe) {\n            iframe.remove();\n          }\n        }\n      };\n    }\n  });\n});\n","Mageplaza_Core/lib/fileUploader/cors/jquery.xdr-transport.js":"/*\n * jQuery XDomainRequest Transport Plugin\n * https://github.com/blueimp/jQuery-File-Upload\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on Julian Aubourg's ajaxHooks xdr.js:\n * https://github.com/jaubourg/ajaxHooks/\n */\n\n/* global define, require, XDomainRequest */\n\n(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // Register as an anonymous AMD module:\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS:\n    factory(require('jquery'));\n  } else {\n    // Browser globals:\n    factory(window.jQuery);\n  }\n})(function ($) {\n  'use strict';\n  if (window.XDomainRequest && !$.support.cors) {\n    $.ajaxTransport(function (s) {\n      if (s.crossDomain && s.async) {\n        if (s.timeout) {\n          s.xdrTimeout = s.timeout;\n          delete s.timeout;\n        }\n        var xdr;\n        return {\n          send: function (headers, completeCallback) {\n            var addParamChar = /\\?/.test(s.url) ? '&' : '?';\n            /**\n             * Callback wrapper function\n             *\n             * @param {number} status HTTP status code\n             * @param {string} statusText HTTP status text\n             * @param {object} [responses] Content-type specific responses\n             * @param {string} [responseHeaders] Response headers string\n             */\n            function callback(status, statusText, responses, responseHeaders) {\n              xdr.onload = xdr.onerror = xdr.ontimeout = $.noop;\n              xdr = null;\n              completeCallback(status, statusText, responses, responseHeaders);\n            }\n            xdr = new XDomainRequest();\n            // XDomainRequest only supports GET and POST:\n            if (s.type === 'DELETE') {\n              s.url = s.url + addParamChar + '_method=DELETE';\n              s.type = 'POST';\n            } else if (s.type === 'PUT') {\n              s.url = s.url + addParamChar + '_method=PUT';\n              s.type = 'POST';\n            } else if (s.type === 'PATCH') {\n              s.url = s.url + addParamChar + '_method=PATCH';\n              s.type = 'POST';\n            }\n            xdr.open(s.type, s.url);\n            xdr.onload = function () {\n              callback(\n                200,\n                'OK',\n                { text: xdr.responseText },\n                'Content-Type: ' + xdr.contentType\n              );\n            };\n            xdr.onerror = function () {\n              callback(404, 'Not Found');\n            };\n            if (s.xdrTimeout) {\n              xdr.ontimeout = function () {\n                callback(0, 'timeout');\n              };\n              xdr.timeout = s.xdrTimeout;\n            }\n            xdr.send((s.hasContent && s.data) || null);\n          },\n          abort: function () {\n            if (xdr) {\n              xdr.onerror = $.noop();\n              xdr.abort();\n            }\n          }\n        };\n      }\n    });\n  }\n});\n","Magento_Catalog/product/view/validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'mage/validation/validation'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.validation', $.mage.validation, {\n        options: {\n            radioCheckboxClosest: 'ul, ol'\n        },\n\n        /**\n         * @param {*} error\n         * @param {HTMLElement} element\n         */\n        errorPlacement: function (error, element) {\n            var messageBox,\n                dataValidate;\n\n            if ($(element).hasClass('datetime-picker')) {\n                element = $(element).parent();\n\n                if (element.parent().find('.mage-error').length) {\n                    return;\n                }\n            }\n\n            if (element.attr('data-errors-message-box')) {\n                messageBox = $(element.attr('data-errors-message-box'));\n                messageBox.html(error);\n\n                return;\n            }\n\n            dataValidate = element.attr('data-validate');\n\n            if (dataValidate && dataValidate.indexOf('validate-one-checkbox-required-by-name') > 0) {\n                error.appendTo('#links-advice-container');\n            } else if (element.is(':radio, :checkbox')) {\n                element.closest(this.radioCheckboxClosest).after(error);\n            } else {\n                element.after(error);\n            }\n        },\n\n        /**\n         * @param {HTMLElement} element\n         * @param {String} errorClass\n         */\n        highlight: function (element, errorClass) {\n            var dataValidate = $(element).attr('data-validate');\n\n            if (dataValidate && dataValidate.indexOf('validate-required-datetime') > 0) {\n                $(element).parent().find('.datetime-picker').each(function () {\n                    $(this).removeClass(errorClass);\n\n                    if ($(this).val().length === 0) {\n                        $(this).addClass(errorClass);\n                    }\n                });\n            } else if ($(element).is(':radio, :checkbox')) {\n                $(element).closest(this.radioCheckboxClosest).addClass(errorClass);\n            } else {\n                $(element).addClass(errorClass);\n            }\n        },\n\n        /**\n         * @param {HTMLElement} element\n         * @param {String} errorClass\n         */\n        unhighlight: function (element, errorClass) {\n            var dataValidate = $(element).attr('data-validate');\n\n            if (dataValidate && dataValidate.indexOf('validate-required-datetime') > 0) {\n                $(element).parent().find('.datetime-picker').removeClass(errorClass);\n            } else if ($(element).is(':radio, :checkbox')) {\n                $(element).closest(this.radioCheckboxClosest).removeClass(errorClass);\n            } else {\n                $(element).removeClass(errorClass);\n            }\n        }\n    });\n\n    return $.mage.validation;\n});\n","Magento_Catalog/js/price-box.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'Magento_Catalog/js/price-utils',\n    'underscore',\n    'mage/template',\n    'jquery-ui-modules/widget'\n], function ($, utils, _, mageTemplate) {\n    'use strict';\n\n    var globalOptions = {\n        productId: null,\n        priceConfig: null,\n        prices: {},\n        priceTemplate: '<span class=\"price\"><%- data.formatted %></span>'\n    };\n\n    $.widget('mage.priceBox', {\n        options: globalOptions,\n        qtyInfo: '#qty',\n\n        /**\n         * Widget initialisation.\n         * Every time when option changed prices also can be changed. So\n         * changed options.prices -> changed cached prices -> recalculation -> redraw price box\n         */\n        _init: function initPriceBox() {\n            var box = this.element;\n\n            box.trigger('updatePrice');\n            this.cache.displayPrices = utils.deepClone(this.options.prices);\n        },\n\n        /**\n         * Widget creating.\n         */\n        _create: function createPriceBox() {\n            var box = this.element;\n\n            this.cache = {};\n            this._setDefaultsFromPriceConfig();\n            this._setDefaultsFromDataSet();\n\n            box.on('reloadPrice', this.reloadPrice.bind(this));\n            box.on('updatePrice', this.onUpdatePrice.bind(this));\n            $(this.qtyInfo).on('input', this.updateProductTierPrice.bind(this));\n            box.trigger('price-box-initialized');\n        },\n\n        /**\n         * Call on event updatePrice. Proxy to updatePrice method.\n         * @param {Event} event\n         * @param {Object} prices\n         */\n        onUpdatePrice: function onUpdatePrice(event, prices) {\n            return this.updatePrice(prices);\n        },\n\n        /**\n         * Updates price via new (or additional values).\n         * It expects object like this:\n         * -----\n         *   \"option-hash\":\n         *      \"price-code\":\n         *         \"amount\": 999.99999,\n         *         ...\n         * -----\n         * Empty option-hash object or empty price-code object treats as zero amount.\n         * @param {Object} newPrices\n         */\n        updatePrice: function updatePrice(newPrices) {\n            var prices = this.cache.displayPrices,\n                additionalPrice = {},\n                pricesCode = [],\n                priceValue, origin, finalPrice;\n\n            this.cache.additionalPriceObject = this.cache.additionalPriceObject || {};\n\n            if (newPrices) {\n                $.extend(this.cache.additionalPriceObject, newPrices);\n            }\n\n            if (!_.isEmpty(additionalPrice)) {\n                pricesCode = _.keys(additionalPrice);\n            } else if (!_.isEmpty(prices)) {\n                pricesCode = _.keys(prices);\n            }\n\n            _.each(this.cache.additionalPriceObject, function (additional) {\n                if (additional && !_.isEmpty(additional)) {\n                    pricesCode = _.keys(additional);\n                }\n                _.each(pricesCode, function (priceCode) {\n                    priceValue = additional[priceCode] || {};\n                    priceValue.amount = +priceValue.amount || 0;\n                    priceValue.adjustments = priceValue.adjustments || {};\n\n                    additionalPrice[priceCode] = additionalPrice[priceCode] || {\n                        'amount': 0,\n                        'adjustments': {}\n                    };\n                    additionalPrice[priceCode].amount =  0 + (additionalPrice[priceCode].amount || 0) +\n                        priceValue.amount;\n                    _.each(priceValue.adjustments, function (adValue, adCode) {\n                        additionalPrice[priceCode].adjustments[adCode] = 0 +\n                            (additionalPrice[priceCode].adjustments[adCode] || 0) + adValue;\n                    });\n                });\n            });\n\n            if (_.isEmpty(additionalPrice)) {\n                this.cache.displayPrices = utils.deepClone(this.options.prices);\n            } else {\n                _.each(additionalPrice, function (option, priceCode) {\n                    origin = this.options.prices[priceCode] || {};\n                    finalPrice = prices[priceCode] || {};\n                    option.amount = option.amount || 0;\n                    origin.amount = origin.amount || 0;\n                    origin.adjustments = origin.adjustments || {};\n                    finalPrice.adjustments = finalPrice.adjustments || {};\n\n                    finalPrice.amount = 0 + origin.amount + option.amount;\n                    _.each(option.adjustments, function (pa, paCode) {\n                        finalPrice.adjustments[paCode] = 0 + (origin.adjustments[paCode] || 0) + pa;\n                    });\n                }, this);\n            }\n\n            this.element.trigger('priceUpdated', this.cache.displayPrices);\n            this.element.trigger('reloadPrice');\n        },\n\n        /*eslint-disable no-extra-parens*/\n        /**\n         * Render price unit block.\n         */\n        reloadPrice: function reDrawPrices() {\n            var priceFormat = (this.options.priceConfig && this.options.priceConfig.priceFormat) || {},\n                priceTemplate = mageTemplate(this.options.priceTemplate);\n\n            _.each(this.cache.displayPrices, function (price, priceCode) {\n                price.final = _.reduce(price.adjustments, function (memo, amount) {\n                    return memo + amount;\n                }, price.amount);\n\n                price.formatted = utils.formatPriceLocale(price.final, priceFormat);\n\n                $('[data-price-type=\"' + priceCode + '\"]', this.element).html(priceTemplate({\n                    data: price\n                }));\n            }, this);\n        },\n\n        /*eslint-enable no-extra-parens*/\n        /**\n         * Overwrites initial (default) prices object.\n         * @param {Object} prices\n         */\n        setDefault: function setDefaultPrices(prices) {\n            this.cache.displayPrices = utils.deepClone(prices);\n            this.options.prices = utils.deepClone(prices);\n        },\n\n        /**\n         * Custom behavior on getting options:\n         * now widget able to deep merge of accepted configuration.\n         * @param  {Object} options\n         * @return {mage.priceBox}\n         */\n        _setOptions: function setOptions(options) {\n            $.extend(true, this.options, options);\n\n            if ('disabled' in options) {\n                this._setOption('disabled', options.disabled);\n            }\n\n            return this;\n        },\n\n        /**\n         * setDefaultsFromDataSet\n         */\n        _setDefaultsFromDataSet: function _setDefaultsFromDataSet() {\n            var box = this.element,\n                priceHolders = $('[data-price-type]', box),\n                prices = this.options.prices;\n\n            this.options.productId = box.data('productId');\n\n            if (_.isEmpty(prices)) {\n                priceHolders.each(function (index, element) {\n                    var type = $(element).data('priceType'),\n                        amount = parseFloat($(element).data('priceAmount'));\n\n                    if (type && !_.isNaN(amount)) {\n                        prices[type] = {\n                            amount: amount\n                        };\n                    }\n                });\n            }\n        },\n\n        /**\n         * setDefaultsFromPriceConfig\n         */\n        _setDefaultsFromPriceConfig: function _setDefaultsFromPriceConfig() {\n            var config = this.options.priceConfig;\n\n            if (config && config.prices) {\n                this.options.prices = config.prices;\n            }\n        },\n\n        /**\n         * Updates product final and base price according to tier prices\n         */\n        updateProductTierPrice: function updateProductTierPrice() {\n            var originalPrice,\n                prices = {'prices': {}};\n\n            if (this.options.prices.finalPrice) {\n                originalPrice = this.options.prices.finalPrice.amount;\n                prices.prices.finalPrice = {'amount': this.getPrice('price') - originalPrice};\n            }\n\n            if (this.options.prices.basePrice) {\n                originalPrice = this.options.prices.basePrice.amount;\n                prices.prices.basePrice = {'amount': this.getPrice('basePrice') - originalPrice};\n            }\n\n            this.updatePrice(prices);\n        },\n\n        /**\n         * Returns price.\n         *\n         * @param {String} priceKey\n         * @returns {Number}\n         */\n        getPrice: function (priceKey) {\n            var productQty = $(this.qtyInfo).val(),\n                result,\n                tierPriceItem,\n                i;\n\n            for (i = 0; i < this.options.priceConfig.tierPrices.length; i++) {\n                tierPriceItem = this.options.priceConfig.tierPrices[i];\n                if (productQty >= tierPriceItem.qty && tierPriceItem[priceKey]) {\n                    result = tierPriceItem[priceKey];\n                }\n            }\n\n            return result;\n        }\n    });\n\n    return $.mage.priceBox;\n});\n","Magento_Catalog/js/price-option-file.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.priceOptionFile', {\n        options: {\n            fileName: '',\n            fileNamed: '',\n            fieldNameAction: '',\n            changeFileSelector: '',\n            deleteFileSelector: ''\n        },\n\n        /**\n         * Creates instance of widget\n         * @private\n         */\n        _create: function () {\n            this.fileDeleteFlag = this.fileChangeFlag = false;\n            this.inputField = this.element.find('input[name=' + this.options.fileName + ']')[0];\n            this.inputFieldAction = this.element.find('input[name=' + this.options.fieldNameAction + ']')[0];\n            this.fileNameSpan = this.element.parent('dd').find('.' + this.options.fileNamed);\n\n            $(this.options.changeFileSelector).on('click', $.proxy(function () {\n                this._toggleFileChange();\n            }, this));\n            $(this.options.deleteFileSelector).on('click', $.proxy(function () {\n                this._toggleFileDelete();\n            }, this));\n        },\n\n        /**\n         * Toggles whether the current file is being changed or not. If the file is being deleted\n         * then the option to change the file is disabled.\n         * @private\n         */\n        _toggleFileChange: function () {\n            this.element.toggle();\n            this.fileChangeFlag = !this.fileChangeFlag;\n\n            if (!this.fileDeleteFlag) {\n                $(this.inputFieldAction).attr('value', this.fileChangeFlag ? 'save_new' : 'save_old');\n                this.inputField.disabled = !this.fileChangeFlag;\n            }\n        },\n\n        /**\n         * Toggles whether the file is to be deleted. When the file is being deleted, the name of\n         * the file is decorated with strike-through text and the option to change the file is\n         * disabled.\n         * @private\n         */\n        _toggleFileDelete: function () {\n            this.fileDeleteFlag = $(this.options.deleteFileSelector + ':checked').val();\n            $(this.inputFieldAction).attr('value',\n                this.fileDeleteFlag ? '' : this.fileChangeFlag ? 'save_new' : 'save_old');\n            this.inputField.disabled = this.fileDeleteFlag || !this.fileChangeFlag;\n            this.fileNameSpan.css('text-decoration', this.fileDeleteFlag ? 'line-through' : 'none');\n        }\n    });\n\n    return $.mage.priceOptionFile;\n});\n","Magento_Catalog/js/validate-product.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'mage/mage',\n    'Magento_Catalog/product/view/validation',\n    'catalogAddToCart'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.productValidate', {\n        options: {\n            bindSubmit: false,\n            radioCheckboxClosest: '.nested',\n            addToCartButtonSelector: '.action.tocart'\n        },\n\n        /**\n         * Uses Magento's validation widget for the form object.\n         * @private\n         */\n        _create: function () {\n            var bindSubmit = this.options.bindSubmit;\n\n            this.element.validation({\n                radioCheckboxClosest: this.options.radioCheckboxClosest,\n\n                /**\n                 * Uses catalogAddToCart widget as submit handler.\n                 * @param {Object} form\n                 * @returns {Boolean}\n                 */\n                submitHandler: function (form) {\n                    var jqForm = $(form).catalogAddToCart({\n                        bindSubmit: bindSubmit\n                    });\n\n                    jqForm.catalogAddToCart('submitForm', jqForm);\n\n                    return false;\n                }\n            });\n            $(this.options.addToCartButtonSelector).attr('disabled', false);\n        }\n    });\n\n    return $.mage.productValidate;\n});\n","Magento_Catalog/js/price-option-date.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'priceUtils',\n    'priceOptions',\n    'jquery-ui-modules/widget'\n], function ($, utils) {\n    'use strict';\n\n    var globalOptions = {\n            fromSelector: 'form',\n            dropdownsSelector: '[data-role=calendar-dropdown]'\n        },\n        optionHandler = {};\n\n    optionHandler.optionHandlers = {};\n\n    /**\n     * Custom handler for Date-with-Dropdowns option type.\n     * @param  {jQuery} siblings\n     * @return {Function} function that return object { optionHash : optionAdditionalPrice }\n     */\n    function onCalendarDropdownChange(siblings) {\n        return function (element, optionConfig) {\n            var changes = {},\n                optionId = utils.findOptionId(element),\n                overhead = optionConfig[optionId].prices,\n                isNeedToUpdate = true,\n                optionHash = 'price-option-calendar-' + optionId;\n\n            siblings.each(function (index, el) {\n                isNeedToUpdate = isNeedToUpdate && !!$(el).val();\n            });\n\n            overhead = isNeedToUpdate ? overhead : {};\n            changes[optionHash] = overhead;\n\n            return changes;\n        };\n    }\n\n    /**\n     * Returns number of days for special month and year\n     * @param  {Number} month\n     * @param  {Number} year\n     * @return {Number}\n     */\n    function getDaysInMonth(month, year) {\n        return new Date(year, month, 0).getDate();\n    }\n\n    /**\n     * Adjusts the number of days in the day option element based on which month or year\n     * is selected (changed). Adjusts the days to 28, 29, 30, or 31 typically.\n     * @param {jQuery} dropdowns\n     */\n    function onDateChange(dropdowns) {\n        var daysNodes,\n            curMonth, curYear, expectedDays,\n            options, needed,\n            month = dropdowns.filter('[data-calendar-role=month]'),\n            year = dropdowns.filter('[data-calendar-role=year]');\n\n        if (month.length && year.length) {\n            daysNodes = dropdowns.filter('[data-calendar-role=day]').find('option');\n\n            curMonth = month.val() || '01';\n            curYear = year.val() || '2000';\n            expectedDays = getDaysInMonth(curMonth, curYear);\n\n            if (daysNodes.length - 1 > expectedDays) { // remove unnecessary option nodes\n                daysNodes.each(function (i, e) {\n                    if (e.value > expectedDays) {\n                        $(e).remove();\n                    }\n                });\n            } else if (daysNodes.length - 1 < expectedDays) { // add missing option nodes\n                options = [];\n                needed = expectedDays - daysNodes.length + 1;\n\n                while (needed--) { //eslint-disable-line max-depth\n                    options.push(\n                        '<option value=\"' + (expectedDays - needed) + '\">' + (expectedDays - needed) + '</option>'\n                    );\n                }\n                $(options.join('')).insertAfter(daysNodes.last());\n            }\n        }\n    }\n\n    $.widget('mage.priceOptionDate', {\n        options: globalOptions,\n\n        /**\n         * Function-initializer of priceOptionDate widget\n         * @private\n         */\n        _create: function initOptionDate() {\n            var field = this.element,\n                form = field.closest(this.options.fromSelector),\n                dropdowns = $(this.options.dropdownsSelector, field),\n                dateOptionId;\n\n            if (dropdowns.length) {\n                dateOptionId = this.options.dropdownsSelector + dropdowns.attr('name');\n\n                optionHandler.optionHandlers[dateOptionId] = onCalendarDropdownChange(dropdowns);\n\n                form.priceOptions(optionHandler);\n\n                dropdowns.data('role', dateOptionId);\n                dropdowns.on('change', onDateChange.bind(this, dropdowns));\n            }\n        }\n    });\n\n    return $.mage.priceOptionDate;\n});\n","Magento_Catalog/js/upsell-products.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.upsellProducts', {\n        options: {\n            elementsSelector: '.item.product'\n        },\n\n        /**\n         * Bind events to the appropriate handlers.\n         * @private\n         */\n        _create: function () {\n            if (this.element.data('shuffle')) {\n                this._shuffle(this.element.find(this.options.elementsSelector));\n            }\n            this._showUpsellProducts(\n                this.element.find(this.options.elementsSelector),\n                this.element.data('limit'),\n                this.element.data('shuffle-weighted')\n            );\n        },\n\n        /* jscs:disable */\n        /* eslint-disable */\n        /**\n         * Show upsell products according to limit. Shuffle if needed.\n         * @param {*} elements\n         * @param {Number} limit\n         * @param {Boolean} weightedRandom\n         * @private\n         */\n        _showUpsellProducts: function (elements, limit, weightedRandom) {\n            var index, weights = [], random = [], weight = 2, shown = 0, $element, currentGroup, prevGroup;\n\n            if (limit === 0) {\n                limit = elements.length;\n            }\n\n            if (weightedRandom && limit > 0 && limit < elements.length) {\n                for (index = 0; index < limit; index++) {\n                    $element = $(elements[index]);\n                    if ($element.data('shuffle-group') !== '') {\n                        break;\n                    }\n                    $element.show();\n                    shown++;\n                }\n                limit -= shown;\n                for (index = elements.length - 1; index >= 0; index--) {\n                    $element = $(elements[index]);\n                    currentGroup = $element.data('shuffle-group');\n                    if (currentGroup !== '') {\n                        weights.push([index, Math.log(weight)]);\n                        if (typeof prevGroup !== 'undefined' && prevGroup !== currentGroup) {\n                            weight += 2;\n                        }\n                        prevGroup = currentGroup;\n                    }\n                }\n\n                if (weights.length === 0) {\n                    return;\n                }\n\n                for (index = 0; index < weights.length; index++) {\n                    random.push([weights[index][0], Math.pow(Math.random(), 1 / weights[index][1])]);\n                }\n\n                random.sort(function(a, b) {\n                    a = a[1];\n                    b = b[1];\n                    return a < b ? 1 : (a > b ? -1 : 0);\n                });\n                index = 0;\n                while (limit) {\n                    $(elements[random[index][0]]).show();\n                    limit--;\n                    index++\n                }\n                return;\n            }\n\n            for (index = 0; index < limit; index++) {\n                $(elements[index]).show();\n            }\n        },\n\n        /* jscs:disable */\n        /* eslint-disable */\n        /**\n         * Shuffle an array\n         * @param elements\n         * @returns {*}\n         */\n        _shuffle: function shuffle(elements){ //v1.0\n            var parent, child, lastSibling;\n            if (elements.length) {\n                parent = $(elements[0]).parent();\n            }\n            while (elements.length) {\n                child = elements.splice(Math.floor(Math.random() *  elements.length), 1)[0];\n                lastSibling = parent.find('[data-shuffle-group=\"' + $(child).data('shuffle-group') + '\"]').last();\n                lastSibling.after(child);\n            }\n        }\n\n        /* jscs:disable */\n        /* eslint:disable */\n    });\n\n    return $.mage.upsellProducts;\n});\n","Magento_Catalog/js/gallery.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.gallery', {\n        options: {\n            minWidth: 300, // Minimum width of the gallery image.\n            widthOffset: 90, // Offset added to the width of the gallery image.\n            heightOffset: 210, // Offset added to the height of the gallery image.\n            closeWindow: 'div.buttons-set a[role=\"close-window\"]' // Selector for closing the gallery popup window.\n        },\n\n        /**\n         * Bind click handler for closing the popup window and resize the popup based on the image size.\n         * @private\n         */\n        _create: function () {\n            $(this.options.closeWindow).on('click', function () {\n                window.close();\n            });\n            this._resizeWindow();\n        },\n\n        /**\n         * Resize the gallery image popup window based on the image's dimensions.\n         * @private\n         */\n        _resizeWindow: function () {\n            var img = this.element,\n                width = img.width() < this.options.minWidth ? this.options.minWidth : img.width();\n\n            window.resizeTo(width + this.options.widthOffset, img.height() + this.options.heightOffset);\n        }\n    });\n\n    return $.mage.gallery;\n});\n","Magento_Catalog/js/related-products.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'mage/translate'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.relatedProducts', {\n        options: {\n            relatedCheckbox: '.related-checkbox', // Class name for a related product's input checkbox.\n            relatedProductsCheckFlag: false, // Related products checkboxes are initially unchecked.\n            relatedProductsField: '#related-products-field', // Hidden input field that stores related products.\n            selectAllMessage: $.mage.__('select all'),\n            unselectAllMessage: $.mage.__('unselect all'),\n            selectAllLink: '[data-role=\"select-all\"]',\n            elementsSelector: '.item.product'\n        },\n\n        /**\n         * Bind events to the appropriate handlers.\n         * @private\n         */\n        _create: function () {\n            $(this.options.selectAllLink, this.element).on('click', $.proxy(this._selectAllRelated, this));\n            $(this.options.relatedCheckbox, this.element).on('click', $.proxy(this._addRelatedToProduct, this));\n\n            if (this.element.data('shuffle')) {\n                this._shuffle(this.element.find(this.options.elementsSelector));\n            }\n            this._showRelatedProducts(\n                this.element.find(this.options.elementsSelector),\n                this.element.data('limit'),\n                this.element.data('shuffle-weighted')\n            );\n        },\n\n        /**\n         * This method either checks all checkboxes for a product's set of related products (select all)\n         * or unchecks them (unselect all).\n         * @private\n         * @param {jQuery.Event} e - Click event on either the \"select all\" link or the \"unselect all\" link.\n         * @return {Boolean} - Prevent default event action and event propagation.\n         */\n        _selectAllRelated: function (e) {\n            var innerHTML = this.options.relatedProductsCheckFlag ?\n                this.options.selectAllMessage : this.options.unselectAllMessage;\n\n            $(e.target).html(innerHTML);\n            $(this.options.relatedCheckbox + ':visible').attr(\n                'checked',\n                this.options.relatedProductsCheckFlag = !this.options.relatedProductsCheckFlag\n            );\n            this._addRelatedToProduct();\n\n            return false;\n        },\n\n        /**\n         * This method iterates through each checkbox for all related products and collects only those products\n         * whose checkbox has been checked. The selected related products are stored in a hidden input field.\n         * @private\n         */\n        _addRelatedToProduct: function () {\n            $(this.options.relatedProductsField).val(\n                $(this.options.relatedCheckbox + ':checked').map(function () {\n                    return this.value;\n                }).get().join(',')\n            );\n        },\n\n        /* jscs:disable */\n        /* eslint-disable */\n        /**\n         * Show related products according to limit. Shuffle if needed.\n         * @param {*} elements\n         * @param {*} limit\n         * @param weightedRandom\n         * @private\n         */\n        _showRelatedProducts: function (elements, limit, weightedRandom) {\n            var index, weights = [], random = [], weight = 2, shown = 0, $element, currentGroup, prevGroup;\n\n            if (limit === 0) {\n                limit = elements.length;\n            }\n\n            if (weightedRandom && limit > 0 && limit < elements.length) {\n                for (index = 0; index < limit; index++) {\n                    $element = $(elements[index]);\n                    if ($element.data('shuffle-group') !== '') {\n                        break;\n                    }\n                    $element.show();\n                    shown++;\n                }\n                limit -= shown;\n                for (index = elements.length - 1; index >= 0; index--) {\n                    $element = $(elements[index]);\n                    currentGroup = $element.data('shuffle-group');\n                    if (currentGroup !== '') {\n                        weights.push([index, Math.log(weight)]);\n                        if (typeof prevGroup !== 'undefined' && prevGroup !== currentGroup) {\n                            weight += 2;\n                        }\n                        prevGroup = currentGroup;\n                    }\n                }\n\n                if (weights.length === 0) {\n                    return;\n                }\n\n                for (index = 0; index < weights.length; index++) {\n                    random.push([weights[index][0], Math.pow(Math.random(), 1 / weights[index][1])]);\n                }\n\n                random.sort(function(a, b) {\n                    a = a[1];\n                    b = b[1];\n                    return a < b ? 1 : (a > b ? -1 : 0);\n                });\n                index = 0;\n                while (limit) {\n                    $(elements[random[index][0]]).show();\n                    limit--;\n                    index++\n                }\n                return;\n            }\n\n            for (index = 0; index < limit; index++) {\n                $(elements[index]).show();\n            }\n        },\n\n        /* jscs:disable */\n        /* eslint-disable */\n        /**\n         * Shuffle an array\n         * @param {Array} elements\n         * @returns {*}\n         */\n        _shuffle: function shuffle(elements) {\n            var parent, child, lastSibling;\n            if (elements.length) {\n                parent = $(elements[0]).parent();\n            }\n            while (elements.length) {\n                child = elements.splice(Math.floor(Math.random() *  elements.length), 1)[0];\n                lastSibling = parent.find('[data-shuffle-group=\"' + $(child).data('shuffle-group') + '\"]').last();\n                lastSibling.after(child);\n            }\n        }\n\n        /* jscs:disable */\n        /* eslint:disable */\n    });\n\n    return $.mage.relatedProducts;\n});\n","Magento_Catalog/js/list.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.compareList', {\n\n        /** @inheritdoc */\n        _create: function () {\n            var elem = this.element,\n                products = $('thead td', elem),\n                headings;\n\n            if (products.length > this.options.productsInRow) {\n                headings = $('<table></table>')\n                    .addClass('comparison headings data table')\n                    .insertBefore(elem.closest('.container'));\n\n                elem.addClass('scroll');\n\n                $('th', elem).each(function () {\n                    var th = $(this),\n                        thCopy = th.clone();\n\n                    th.animate({\n                        top: '+=0'\n                    }, 50, function () {\n                        var height = th.height();\n\n                        thCopy.css('height', height)\n                            .appendTo(headings)\n                            .wrap('<tr></tr>');\n                    });\n                });\n            }\n\n            $(this.options.windowPrintSelector).on('click', function (e) {\n                e.preventDefault();\n                window.print();\n            });\n        }\n    });\n\n    return $.mage.compareList;\n});\n","Magento_Catalog/js/catalog-add-to-cart.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/translate',\n    'underscore',\n    'Magento_Catalog/js/product/view/product-ids-resolver',\n    'Magento_Catalog/js/product/view/product-info-resolver',\n    'jquery-ui-modules/widget'\n], function ($, $t, _, idsResolver, productInfoResolver) {\n    'use strict';\n\n    $.widget('mage.catalogAddToCart', {\n        options: {\n            processStart: null,\n            processStop: null,\n            bindSubmit: true,\n            minicartSelector: '[data-block=\"minicart\"]',\n            messagesSelector: '[data-placeholder=\"messages\"]',\n            productStatusSelector: '.stock.available',\n            addToCartButtonSelector: '.action.tocart',\n            addToCartButtonDisabledClass: 'disabled',\n            addToCartButtonTextWhileAdding: '',\n            addToCartButtonTextAdded: '',\n            addToCartButtonTextDefault: '',\n            productInfoResolver: productInfoResolver\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            if (this.options.bindSubmit) {\n                this._bindSubmit();\n            }\n            $(this.options.addToCartButtonSelector).prop('disabled', false);\n        },\n\n        /**\n         * @private\n         */\n        _bindSubmit: function () {\n            var self = this;\n\n            if (this.element.data('catalog-addtocart-initialized')) {\n                return;\n            }\n\n            this.element.data('catalog-addtocart-initialized', 1);\n            this.element.on('submit', function (e) {\n                e.preventDefault();\n                self.submitForm($(this));\n            });\n        },\n\n        /**\n         * @private\n         */\n        _redirect: function (url) {\n            var urlParts, locationParts, forceReload;\n\n            urlParts = url.split('#');\n            locationParts = window.location.href.split('#');\n            forceReload = urlParts[0] === locationParts[0];\n\n            window.location.assign(url);\n\n            if (forceReload) {\n                window.location.reload();\n            }\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isLoaderEnabled: function () {\n            return this.options.processStart && this.options.processStop;\n        },\n\n        /**\n         * Handler for the form 'submit' event\n         *\n         * @param {jQuery} form\n         */\n        submitForm: function (form) {\n            this.ajaxSubmit(form);\n        },\n\n        /**\n         * @param {jQuery} form\n         */\n        ajaxSubmit: function (form) {\n            var self = this,\n                productIds = idsResolver(form),\n                productInfo = self.options.productInfoResolver(form),\n                formData;\n\n            $(self.options.minicartSelector).trigger('contentLoading');\n            self.disableAddToCartButton(form);\n            formData = new FormData(form[0]);\n\n            $.ajax({\n                url: form.prop('action'),\n                data: formData,\n                type: 'post',\n                dataType: 'json',\n                cache: false,\n                contentType: false,\n                processData: false,\n\n                /** @inheritdoc */\n                beforeSend: function () {\n                    if (self.isLoaderEnabled()) {\n                        $('body').trigger(self.options.processStart);\n                    }\n                },\n\n                /** @inheritdoc */\n                success: function (res) {\n                    var eventData, parameters;\n\n                    $(document).trigger('ajax:addToCart', {\n                        'sku': form.data().productSku,\n                        'productIds': productIds,\n                        'productInfo': productInfo,\n                        'form': form,\n                        'response': res\n                    });\n\n                    if (self.isLoaderEnabled()) {\n                        $('body').trigger(self.options.processStop);\n                    }\n\n                    if (res.backUrl) {\n                        eventData = {\n                            'form': form,\n                            'redirectParameters': []\n                        };\n                        // trigger global event, so other modules will be able add parameters to redirect url\n                        $('body').trigger('catalogCategoryAddToCartRedirect', eventData);\n\n                        if (eventData.redirectParameters.length > 0 &&\n                            window.location.href.split(/[?#]/)[0] === res.backUrl\n                        ) {\n                            parameters = res.backUrl.split('#');\n                            parameters.push(eventData.redirectParameters.join('&'));\n                            res.backUrl = parameters.join('#');\n                        }\n\n                        self._redirect(res.backUrl);\n\n                        return;\n                    }\n\n                    if (res.messages) {\n                        $(self.options.messagesSelector).html(res.messages);\n                    }\n\n                    if (res.minicart) {\n                        $(self.options.minicartSelector).replaceWith(res.minicart);\n                        $(self.options.minicartSelector).trigger('contentUpdated');\n                    }\n\n                    if (res.product && res.product.statusText) {\n                        $(self.options.productStatusSelector)\n                            .removeClass('available')\n                            .addClass('unavailable')\n                            .find('span')\n                            .html(res.product.statusText);\n                    }\n                    self.enableAddToCartButton(form);\n                },\n\n                /** @inheritdoc */\n                error: function (res) {\n                    $(document).trigger('ajax:addToCart:error', {\n                        'sku': form.data().productSku,\n                        'productIds': productIds,\n                        'productInfo': productInfo,\n                        'form': form,\n                        'response': res\n                    });\n                },\n\n                /** @inheritdoc */\n                complete: function (res) {\n                    if (res.state() === 'rejected') {\n                        location.reload();\n                    }\n                }\n            });\n        },\n\n        /**\n         * @param {String} form\n         */\n        disableAddToCartButton: function (form) {\n            var addToCartButtonTextWhileAdding = this.options.addToCartButtonTextWhileAdding || $t('Adding...'),\n                addToCartButton = $(form).find(this.options.addToCartButtonSelector);\n\n            addToCartButton.addClass(this.options.addToCartButtonDisabledClass);\n            addToCartButton.find('span').text(addToCartButtonTextWhileAdding);\n            addToCartButton.prop('title', addToCartButtonTextWhileAdding);\n        },\n\n        /**\n         * @param {String} form\n         */\n        enableAddToCartButton: function (form) {\n            var addToCartButtonTextAdded = this.options.addToCartButtonTextAdded || $t('Added'),\n                self = this,\n                addToCartButton = $(form).find(this.options.addToCartButtonSelector);\n\n            addToCartButton.find('span').text(addToCartButtonTextAdded);\n            addToCartButton.prop('title', addToCartButtonTextAdded);\n\n            setTimeout(function () {\n                var addToCartButtonTextDefault = self.options.addToCartButtonTextDefault || $t('Add to Cart');\n\n                addToCartButton.removeClass(self.options.addToCartButtonDisabledClass);\n                addToCartButton.find('span').text(addToCartButtonTextDefault);\n                addToCartButton.prop('title', addToCartButtonTextDefault);\n            }, 1000);\n        }\n    });\n\n    return $.mage.catalogAddToCart;\n});\n","Magento_Catalog/js/storage-manager.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiElement',\n    'mageUtils',\n    'Magento_Catalog/js/product/storage/storage-service',\n    'Magento_Customer/js/section-config',\n    'jquery'\n], function (_, Element, utils, storage, sectionConfig, $) {\n    'use strict';\n\n    /**\n     * Flush events, that are clones of the same customer data sections\n     * Events listener\n     */\n    $(document).on('submit', function (event) {\n        var sections;\n\n        if (event.target.method.match(/post|put|delete/i)) {\n            sections = sectionConfig.getAffectedSections(event.target.action);\n\n            if (sections && window.localStorage) {\n                _.each(sections, function (section) {\n                    window.localStorage.removeItem(section);\n                });\n            }\n        }\n    });\n\n    return Element.extend({\n        defaults: {\n            defaultNamespace: {\n                lifetime: 1000\n            },\n            storagesConfiguration: {\n                'recently_viewed_product': {\n                    namespace: 'recently_viewed_product',\n                    className: 'IdsStorage',\n                    lifetime: '${ $.defaultNamespace.lifetime }',\n                    requestConfig: {\n                        typeId: '${ $.storagesConfiguration.recently_viewed_product.namespace }'\n                    },\n                    savePrevious: {\n                        namespace: '${ $.storagesConfiguration.recently_viewed_product.namespace }' + '_previous',\n                        className: '${ $.storagesConfiguration.recently_viewed_product.className }'\n                    },\n                    allowToSendRequest: 0\n                },\n                'recently_compared_product': {\n                    namespace: 'recently_compared_product',\n                    className: 'IdsStorageCompare',\n                    provider: 'compare-products',\n                    lifetime: '${ $.defaultNamespace.lifetime }',\n                    requestConfig: {\n                        typeId: '${ $.storagesConfiguration.recently_compared_product.namespace }'\n                    },\n                    savePrevious: {\n                        namespace: '${ $.storagesConfiguration.recently_compared_product.namespace }' + '_previous',\n                        className: '${ $.storagesConfiguration.recently_compared_product.className }'\n                    },\n                    allowToSendRequest: 0\n                },\n                'product_data_storage': {\n                    namespace: 'product_data_storage',\n                    className: 'DataStorage',\n                    allowToSendRequest: 0,\n                    updateRequestConfig: {\n                        url: '',\n                        method: 'GET',\n                        dataType: 'json'\n                    }\n                }\n            },\n            requestConfig: {\n                method: 'POST',\n                dataType: 'json',\n                ajaxSaveType: 'default',\n                ignoreProcessEvents: true\n            },\n            requestSent: 0\n        },\n\n        /**\n         * Initializes provider component.\n         *\n         * @returns {Object} Chainable.\n         */\n        initialize: function () {\n            this._super()\n                .prepareStoragesConfig()\n                .initStorages()\n                .initStartData()\n                .initUpdateStorageDataListener();\n\n            return this;\n        },\n\n        /**\n         * Initializes storages.\n         *\n         * @returns {Object} Chainable.\n         */\n        initStorages: function () {\n            _.each(this.storagesNamespace, function (name) {\n                this[name] = storage.createStorage(this.storagesConfiguration[name]);\n\n                if (this.storagesConfiguration[name].savePrevious) {\n                    this[name].previous = storage.createStorage(this.storagesConfiguration[name].savePrevious);\n                }\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Initializes start data.\n         *\n         * @returns {Object} Chainable.\n         */\n        initStartData: function () {\n            _.each(this.storagesNamespace, function (name) {\n                this.updateDataHandler(name, this[name].get());\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Prepare storages congfig.\n         *\n         * @returns {Object} Chainable.\n         */\n        prepareStoragesConfig: function () {\n            this.storagesNamespace = _.keys(this.storagesConfiguration);\n\n            _.each(this.storagesNamespace, function (name) {\n                this.storagesConfiguration[name].requestConfig = _.extend(\n                    utils.copy(this.requestConfig),\n                    this.storagesConfiguration[name].requestConfig\n                );\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Prepare date in UTC format (in GMT), and calculate unix timestamp based in seconds\n         *\n         * @returns {Number}\n         * @private\n         */\n        getUtcTime: function () {\n            return new Date().getTime() / 1000;\n        },\n\n        /**\n         * Initializes listeners to storages \"data\" property.\n         */\n        initUpdateStorageDataListener: function () {\n            _.each(this.storagesNamespace, function (name) {\n                if (this[name].data) {\n                    this[name].data.subscribe(this.updateDataHandler.bind(this, name));\n                }\n            }.bind(this));\n        },\n\n        /**\n         * Handlers for storages \"data\" property\n         */\n        updateDataHandler: function (name, data) {\n            var previousData = this[name].previous ? this[name].previous.get() : false;\n\n            if (!_.isEmpty(previousData) &&\n                !_.isEmpty(data) &&\n                !utils.compare(data, previousData).equal) {\n                this[name].set(data);\n                this[name].previous.set(data);\n                this.sendRequest(name, data);\n            } else if (\n                _.isEmpty(previousData) &&\n                !_.isEmpty(data)\n            ) {\n                this[name].set(data);\n                this.sendRequest(name, data);\n            }\n        },\n\n        /**\n         * Gets last updated time\n         *\n         * @param {String} name - storage name\n         */\n        getLastUpdate: function (name) {\n            return window.localStorage.getItem(this[name].namespace + '_last_update');\n        },\n\n        /**\n         * Sets last updated time\n         *\n         * @param {String} name - storage name\n         */\n        setLastUpdate: function (name) {\n            window.localStorage.setItem(this[name].namespace + '_last_update', this.getUtcTime());\n        },\n\n        /**\n         * Request handler\n         *\n         * @param {String} name - storage name\n         */\n        requestHandler: function (name) {\n            this.setLastUpdate(name);\n            this.requestSent = 1;\n        },\n\n        /**\n         * Sends request to server to gets data\n         *\n         * @param {String} name - storage name\n         * @param {Object} data - ids\n         */\n        sendRequest: function (name, data) {\n            var params  = utils.copy(this.storagesConfiguration[name].requestConfig),\n                url = params.syncUrl,\n                typeId = params.typeId;\n\n            if (this.requestSent || !~~this.storagesConfiguration[name].allowToSendRequest) {\n                return;\n            }\n\n            delete params.typeId;\n            delete params.url;\n            this.requestSent = 1;\n\n            return utils.ajaxSubmit({\n                url: url,\n                data: {\n                    ids: data,\n                    'type_id': typeId\n                }\n            }, params).done(this.requestHandler.bind(this, name));\n        }\n    });\n});\n","Magento_Catalog/js/price-options.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'mage/template',\n    'priceUtils',\n    'priceBox',\n    'jquery-ui-modules/widget'\n], function ($, _, mageTemplate, utils) {\n    'use strict';\n\n    var globalOptions = {\n        productId: null,\n        priceHolderSelector: '.price-box', //data-role=\"priceBox\"\n        optionsSelector: '.product-custom-option',\n        optionConfig: {},\n        optionHandlers: {},\n        optionTemplate: '<%= data.label %>' +\n        '<% if (data.finalPrice.value > 0) { %>' +\n        ' +<%- data.finalPrice.formatted %>' +\n        '<% } else if (data.finalPrice.value < 0) { %>' +\n        ' <%- data.finalPrice.formatted %>' +\n        '<% } %>',\n        controlContainer: 'dd'\n    };\n\n    /**\n     * Custom option preprocessor\n     * @param  {jQuery} element\n     * @param  {Object} optionsConfig - part of config\n     * @return {Object}\n     */\n    function defaultGetOptionValue(element, optionsConfig) {\n        var changes = {},\n            optionValue = element.val(),\n            optionId = utils.findOptionId(element[0]),\n            optionName = element.prop('name'),\n            optionType = element.prop('type'),\n            optionConfig = optionsConfig[optionId],\n            optionHash = optionName;\n\n        switch (optionType) {\n            case 'text':\n            case 'textarea':\n                changes[optionHash] = optionValue ? optionConfig.prices : {};\n                break;\n\n            case 'radio':\n                if (element.is(':checked')) {\n                    changes[optionHash] = optionConfig[optionValue] && optionConfig[optionValue].prices || {};\n                }\n                break;\n\n            case 'select-one':\n                changes[optionHash] = optionConfig[optionValue] && optionConfig[optionValue].prices || {};\n                break;\n\n            case 'select-multiple':\n                _.each(optionConfig, function (row, optionValueCode) {\n                    optionHash = optionName + '##' + optionValueCode;\n                    changes[optionHash] = _.contains(optionValue, optionValueCode) ? row.prices : {};\n                });\n                break;\n\n            case 'checkbox':\n                optionHash = optionName + '##' + optionValue;\n                changes[optionHash] = element.is(':checked') ? optionConfig[optionValue].prices : {};\n                break;\n\n            case 'file':\n                // Checking for 'disable' property equal to checking DOMNode with id*=\"change-\"\n                changes[optionHash] = optionValue || element.prop('disabled') ? optionConfig.prices : {};\n                break;\n        }\n\n        return changes;\n    }\n\n    $.widget('mage.priceOptions', {\n        options: globalOptions,\n\n        /**\n         * @private\n         */\n        _init: function initPriceBundle() {\n            $(this.options.optionsSelector, this.element).trigger('change');\n        },\n\n        /**\n         * Widget creating method.\n         * Triggered once.\n         * @private\n         */\n        _create: function createPriceOptions() {\n            var form = this.element,\n                options = $(this.options.optionsSelector, form),\n                priceBox = $(this.options.priceHolderSelector, $(this.options.optionsSelector).element);\n\n            if (priceBox.data('magePriceBox') &&\n                priceBox.priceBox('option') &&\n                priceBox.priceBox('option').priceConfig\n            ) {\n                if (priceBox.priceBox('option').priceConfig.optionTemplate) {\n                    this._setOption('optionTemplate', priceBox.priceBox('option').priceConfig.optionTemplate);\n                }\n                this._setOption('priceFormat', priceBox.priceBox('option').priceConfig.priceFormat);\n            }\n\n            this._applyOptionNodeFix(options);\n\n            options.on('change', this._onOptionChanged.bind(this));\n        },\n\n        /**\n         * Custom option change-event handler\n         * @param {Event} event\n         * @private\n         */\n        _onOptionChanged: function onOptionChanged(event) {\n            var changes,\n                option = $(event.target),\n                handler = this.options.optionHandlers[option.data('role')];\n\n            option.data('optionContainer', option.closest(this.options.controlContainer));\n\n            if (handler && handler instanceof Function) {\n                changes = handler(option, this.options.optionConfig, this);\n            } else {\n                changes = defaultGetOptionValue(option, this.options.optionConfig);\n            }\n            $(this.options.priceHolderSelector).trigger('updatePrice', changes);\n        },\n\n        /**\n         * Helper to fix issue with option nodes:\n         *  - you can't place any html in option ->\n         *    so you can't style it via CSS\n         * @param {jQuery} options\n         * @private\n         */\n        _applyOptionNodeFix: function applyOptionNodeFix(options) {\n            var config = this.options,\n                format = config.priceFormat,\n                template = config.optionTemplate;\n\n            template = mageTemplate(template);\n            options.filter('select').each(function (index, element) {\n                var $element = $(element),\n                    optionId = utils.findOptionId($element),\n                    optionConfig = config.optionConfig && config.optionConfig[optionId];\n\n                $element.find('option').each(function (idx, option) {\n                    var $option,\n                        optionValue,\n                        toTemplate,\n                        prices;\n\n                    $option = $(option);\n                    optionValue = $option.val();\n\n                    if (!optionValue && optionValue !== 0) {\n                        return;\n                    }\n\n                    toTemplate = {\n                        data: {\n                            label: optionConfig[optionValue] && optionConfig[optionValue].name\n                        }\n                    };\n                    prices = optionConfig[optionValue] ? optionConfig[optionValue].prices : null;\n\n                    if (prices) {\n                        _.each(prices, function (price, type) {\n                            var value = +price.amount;\n\n                            value += _.reduce(price.adjustments, function (sum, x) { //eslint-disable-line\n                                return sum + x;\n                            }, 0);\n                            toTemplate.data[type] = {\n                                value: value,\n                                formatted: utils.formatPriceLocale(value, format)\n                            };\n                        });\n\n                        $option.text(template(toTemplate));\n                    }\n                });\n            });\n        },\n\n        /**\n         * Custom behavior on getting options:\n         * now widget able to deep merge accepted configuration with instance options.\n         * @param  {Object}  options\n         * @return {$.Widget}\n         * @private\n         */\n        _setOptions: function setOptions(options) {\n            $.extend(true, this.options, options);\n            this._super(options);\n\n            return this;\n        }\n    });\n\n    return $.mage.priceOptions;\n});\n","Magento_Catalog/js/price-utils.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore'\n], function ($, _) {\n    'use strict';\n\n    var globalPriceFormat = {\n        requiredPrecision: 2,\n        integerRequired: 1,\n        decimalSymbol: ',',\n        groupSymbol: ',',\n        groupLength: ','\n    };\n\n    /**\n     * Repeats {string} {times} times\n     * @param  {String} string\n     * @param  {Number} times\n     * @return {String}\n     */\n    function stringPad(string, times) {\n        return new Array(times + 1).join(string);\n    }\n\n    /**\n     * Format the price with the compliance to the specified locale\n     *\n     * @param {Number} amount\n     * @param {Object} format\n     * @param  {Boolean} isShowSign\n     */\n    function formatPriceLocale(amount, format, isShowSign)\n    {\n        var s = '',\n            precision, pattern, locale, r;\n\n        format = _.extend(globalPriceFormat, format);\n        precision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision;\n        pattern = format.pattern || '%s';\n        locale = window.LOCALE || 'en-US';\n        if (isShowSign === undefined || isShowSign === true) {\n            s = amount < 0 ? '-' : isShowSign ? '+' : '';\n        } else if (isShowSign === false) {\n            s = '';\n        }\n        pattern = pattern.indexOf('{sign}') < 0 ? s + pattern : pattern.replace('{sign}', s);\n        amount = Number(Math.round(Math.abs(+amount || 0) + 'e+' + precision) + ('e-' + precision));\n        r = amount.toLocaleString(locale, {minimumFractionDigits: precision});\n\n        return pattern.replace('%s', r).replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    /**\n     * Formatter for price amount\n     * @param  {Number}  amount\n     * @param  {Object}  format\n     * @param  {Boolean} isShowSign\n     * @return {String}              Formatted value\n     * @deprecated\n     */\n    function formatPrice(amount, format, isShowSign) {\n        var s = '',\n            precision, integerRequired, decimalSymbol, groupSymbol, groupLength, pattern, i, pad, j, re, r, am;\n\n        format = _.extend(globalPriceFormat, format);\n\n        // copied from price-option.js | Could be refactored with varien/js.js\n\n        precision = isNaN(format.requiredPrecision = Math.abs(format.requiredPrecision)) ? 2 : format.requiredPrecision;\n        integerRequired = isNaN(format.integerRequired = Math.abs(format.integerRequired)) ? 1 : format.integerRequired;\n        decimalSymbol = format.decimalSymbol === undefined ? ',' : format.decimalSymbol;\n        groupSymbol = format.groupSymbol === undefined ? '.' : format.groupSymbol;\n        groupLength = format.groupLength === undefined ? 3 : format.groupLength;\n        pattern = format.pattern || '%s';\n\n        if (isShowSign === undefined || isShowSign === true) {\n            s = amount < 0 ? '-' : isShowSign ? '+' : '';\n        } else if (isShowSign === false) {\n            s = '';\n        }\n        pattern = pattern.indexOf('{sign}') < 0 ? s + pattern : pattern.replace('{sign}', s);\n\n        // we're avoiding the usage of to fixed, and using round instead with the e representation to address\n        // numbers like 1.005 = 1.01. Using ToFixed to only provide trailing zeroes in case we have a whole number\n        i = parseInt(\n                amount = Number(Math.round(Math.abs(+amount || 0) + 'e+' + precision) + ('e-' + precision)),\n                10\n            ) + '';\n        pad = i.length < integerRequired ? integerRequired - i.length : 0;\n\n        i = stringPad('0', pad) + i;\n\n        j = i.length > groupLength ? i.length % groupLength : 0;\n        re = new RegExp('(\\\\d{' + groupLength + '})(?=\\\\d)', 'g');\n\n        // replace(/-/, 0) is only for fixing Safari bug which appears\n        // when Math.abs(0).toFixed() executed on '0' number.\n        // Result is '0.-0' :(\n\n        am = Number(Math.round(Math.abs(amount - i) + 'e+' + precision) + ('e-' + precision));\n        r = (j ? i.substr(0, j) + groupSymbol : '') +\n            i.substr(j).replace(re, '$1' + groupSymbol) +\n            (precision ? decimalSymbol + am.toFixed(precision).replace(/-/, 0).slice(2) : '');\n\n        return pattern.replace('%s', r).replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    }\n\n    /**\n     * Deep clone of Object. Doesn't support functions\n     * @param {Object} obj\n     * @return {Object}\n     */\n    function objectDeepClone(obj) {\n        return JSON.parse(JSON.stringify(obj));\n    }\n\n    /**\n     * Helper to find ID in name attribute\n     * @param   {jQuery} element\n     * @returns {undefined|String}\n     */\n    function findOptionId(element) {\n        var re, id, name;\n\n        if (!element) {\n            return id;\n        }\n        name = $(element).attr('name');\n\n        if (name.indexOf('[') !== -1) {\n            re = /\\[([^\\]]+)?\\]/;\n        } else {\n            re = /_([^\\]]+)?_/; // just to support file-type-option\n        }\n        id = re.exec(name) && re.exec(name)[1];\n\n        if (id) {\n            return id;\n        }\n    }\n\n    return {\n        formatPriceLocale: formatPriceLocale,\n        formatPrice: formatPrice,\n        deepClone: objectDeepClone,\n        strPad: stringPad,\n        findOptionId: findOptionId\n    };\n});\n","Magento_Catalog/js/product/uenc-processor.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([], function () {\n        'use strict';\n\n        /**\n         * Check data to JSON.\n         *\n         * @returns {Boolean}\n         */\n        function _isJSON(data) {\n            try {\n                JSON.parse(data);\n            } catch (e) {\n                return false;\n            }\n\n            return true;\n        }\n\n        /**\n         * Processes data.\n         *\n         * @param {Object} data\n         * @param {String} placeholder\n         * @param {String} uenc\n         *\n         * @returns {String}\n         */\n        function _stringProcessor(data, placeholder, uenc) {\n            if (data && ~data.indexOf(placeholder)) {\n                return data.replace(placeholder, uenc);\n            }\n\n            return data;\n        }\n\n        /**\n         * Processes data.\n         *\n         * @param {Object} data\n         * @param {String} placeholder\n         * @param {String} uenc\n         *\n         * @returns {String}\n         */\n        function _objectProcessor(data, placeholder, uenc) {\n            data = JSON.parse(data);\n\n            if (data.hasOwnProperty('action')) {\n                data.action = _stringProcessor(data.action, placeholder, uenc);\n            }\n\n            if (data.hasOwnProperty('data') && data.data.hasOwnProperty('uenc')) {\n                data.data.uenc = uenc;\n            }\n\n            return JSON.stringify(data);\n        }\n\n        /**\n         * Processes data.\n         *\n         * @param {Object} data\n         * @param {String} placeholder\n         *\n         * @returns {String}\n         */\n        return function (data, placeholder) {\n            var uenc = btoa(window.location.href).replace('+/=', '-_,');\n\n            placeholder = placeholder || encodeURI('%uenc%');\n\n            return _isJSON(data) ?\n                _objectProcessor(data, placeholder, uenc) :\n                _stringProcessor(data, placeholder, uenc);\n\n        };\n    }\n);\n","Magento_Catalog/js/product/provider-compared.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    './provider',\n    'Magento_Catalog/js/product/storage/storage-service',\n    'Magento_Customer/js/customer-data'\n], function (_, Provider, storage, customerData) {\n    'use strict';\n\n    return Provider.extend({\n\n        /**\n         * Ids update handler\n         *\n         * @param {Object} data\n         */\n        idsHandler: function (data) {\n            this.productStorage.setIds(this.data.currency, this.data.store, this.dataFilter(data));\n        },\n\n        /**\n         * Filters data by provider\n         *\n         * @param {Object} data\n         *\n         * @returns {Object}\n         */\n        dataFilter: function (data) {\n            var providerData = this.idsStorage.prepareData(customerData.get(this.identifiersConfig.provider)().items),\n                result = {},\n                productCurrentScope,\n                scopeId;\n\n            if (typeof this.data.productCurrentScope !== 'undefined' && window.checkout && window.checkout.baseUrl) {\n                productCurrentScope = this.data.productCurrentScope;\n                scopeId = productCurrentScope === 'store' ? window.checkout.storeId :\n                    productCurrentScope === 'group' ? window.checkout.storeGroupId :\n                        window.checkout.websiteId;\n                _.each(data, function (value, key) {\n                    if (!providerData[productCurrentScope + '-' + scopeId + '-' + key]) {\n                        result[key] = value;\n                    }\n                });\n            } else {\n                _.each(data, function (value, key) {\n                    if (!providerData[key]) {\n                        result[key] = value;\n                    }\n                });\n            }\n\n            return result;\n        },\n\n        /**\n         * Filters data from product storage by ids\n         *\n         * @param {Object} data\n         *\n         * @returns {Object}\n         */\n        filterData: function (data) {\n            var result = {},\n                i = 0,\n                ids = _.keys(this.dataFilter(this.ids())),\n                length = ids.length;\n\n            for (i; i < length; i++) {\n                if (ids[i] && data[ids[i]]) {\n                    result[ids[i]] = data[ids[i]];\n                }\n            }\n\n            return result;\n        }\n    });\n});\n","Magento_Catalog/js/product/addtocompare-button.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/columns/column',\n    'Magento_Catalog/js/product/uenc-processor',\n    'Magento_Catalog/js/product/list/column-status-validator'\n], function (Column, uencProcessor, columnStatusValidator) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            label: ''\n        },\n\n        /**\n         * Prepare Data-Post data that will be used in data-mage-init\n         *\n         * @param {Object} row\n         * @returns {Array}\n         */\n        getDataPost: function (row) {\n            return uencProcessor(row['add_to_compare_button'].url ||\n                    row['add_to_compare_button']['post_data']);\n        },\n\n        /**\n         * Depends on this option, \"Add to compare\" button can be shown or hide. Depends on  backend configuration\n         *\n         * @returns {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'add_to_compare', 'show_buttons');\n        },\n\n        /**\n         * Get button label.\n         *\n         * @return {String}\n         */\n        getLabel: function () {\n            return this.label;\n        }\n    });\n});\n","Magento_Catalog/js/product/breadcrumbs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Theme/js/model/breadcrumb-list'\n], function ($, breadcrumbList) {\n    'use strict';\n\n    return function (widget) {\n\n        $.widget('mage.breadcrumbs', widget, {\n            options: {\n                categoryUrlSuffix: '',\n                useCategoryPathInUrl: false,\n                product: '',\n                categoryItemSelector: '.category-item',\n                menuContainer: '[data-action=\"navigation\"] > ul'\n            },\n\n            /** @inheritdoc */\n            _render: function () {\n                this._appendCatalogCrumbs();\n                this._super();\n            },\n\n            /**\n             * Append category and product crumbs.\n             *\n             * @private\n             */\n            _appendCatalogCrumbs: function () {\n                var categoryCrumbs = this._resolveCategoryCrumbs();\n\n                categoryCrumbs.forEach(function (crumbInfo) {\n                    breadcrumbList.push(crumbInfo);\n                });\n\n                if (this.options.product) {\n                    breadcrumbList.push(this._getProductCrumb());\n                }\n            },\n\n            /**\n             * Resolve categories crumbs.\n             *\n             * @return Array\n             * @private\n             */\n            _resolveCategoryCrumbs: function () {\n                var menuItem = this._resolveCategoryMenuItem(),\n                    categoryCrumbs = [];\n\n                if (menuItem !== null && menuItem.length) {\n                    categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));\n\n                    while ((menuItem = this._getParentMenuItem(menuItem)) !== null) {\n                        categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));\n                    }\n                }\n\n                return categoryCrumbs;\n            },\n\n            /**\n             * Returns crumb data.\n             *\n             * @param {Object} menuItem\n             * @return {Object}\n             * @private\n             */\n            _getCategoryCrumb: function (menuItem) {\n                return {\n                    'name': 'category',\n                    'label': menuItem.text(),\n                    'link': menuItem.attr('href'),\n                    'title': ''\n                };\n            },\n\n            /**\n             * Returns product crumb.\n             *\n             * @return {Object}\n             * @private\n             */\n            _getProductCrumb: function () {\n                return {\n                    'name': 'product',\n                    'label': this.options.product,\n                    'link': '',\n                    'title': ''\n                };\n            },\n\n            /**\n             * Find parent menu item for current.\n             *\n             * @param {Object} menuItem\n             * @return {Object|null}\n             * @private\n             */\n            _getParentMenuItem: function (menuItem) {\n                var classes,\n                    classNav,\n                    parentClass,\n                    parentMenuItem = null;\n\n                if (!menuItem) {\n                    return null;\n                }\n\n                classes = menuItem.parent().attr('class');\n                classNav = classes.match(/(nav\\-)[0-9]+(\\-[0-9]+)+/gi);\n\n                if (classNav) {\n                    classNav = classNav[0];\n                    parentClass = classNav.substr(0, classNav.lastIndexOf('-'));\n\n                    if (parentClass.lastIndexOf('-') !== -1) {\n                        parentMenuItem = $(this.options.menuContainer).find('.' + parentClass + ' > a');\n                        parentMenuItem = parentMenuItem.length ? parentMenuItem : null;\n                    }\n                }\n\n                return parentMenuItem;\n            },\n\n            /**\n             * Returns category menu item.\n             *\n             * Tries to resolve category from url or from referrer as fallback and\n             * find menu item from navigation menu by category url.\n             *\n             * @return {Object|null}\n             * @private\n             */\n            _resolveCategoryMenuItem: function () {\n                var categoryUrl = this._resolveCategoryUrl(),\n                    menu = $(this.options.menuContainer),\n                    categoryMenuItem = null;\n\n                if (categoryUrl && menu.length) {\n                    categoryMenuItem = menu.find(\n                        this.options.categoryItemSelector +\n                        ' > a[href=\"' + categoryUrl + '\"]'\n                    );\n                }\n\n                return categoryMenuItem;\n            },\n\n            /**\n             * Returns category url.\n             *\n             * @return {String}\n             * @private\n             */\n            _resolveCategoryUrl: function () {\n                var categoryUrl;\n\n                if (this.options.useCategoryPathInUrl) {\n                    // In case category path is used in product url - resolve category url from current url.\n                    categoryUrl = window.location.href.split('?')[0];\n                    categoryUrl = categoryUrl.substring(0, categoryUrl.lastIndexOf('/')) +\n                        this.options.categoryUrlSuffix;\n                } else {\n                    // In other case - try to resolve it from referrer (without parameters).\n                    categoryUrl = document.referrer;\n\n                    if (categoryUrl.indexOf('?') > 0) {\n                        categoryUrl = categoryUrl.substr(0, categoryUrl.indexOf('?'));\n                    }\n                }\n\n                return categoryUrl;\n            }\n        });\n\n        return $.mage.breadcrumbs;\n    };\n});\n","Magento_Catalog/js/product/provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'jquery',\n    'mageUtils',\n    'uiElement',\n    'Magento_Catalog/js/product/storage/storage-service',\n    'Magento_Customer/js/customer-data',\n    'Magento_Catalog/js/product/view/product-ids-resolver'\n], function (_, $, utils, Element, storage, customerData, productResolver) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            identifiersConfig: {\n                namespace: ''\n            },\n            productStorageConfig: {\n                namespace: 'product_data_storage',\n                customerDataProvider: 'product_data_storage',\n                updateRequestConfig: {\n                    url: '',\n                    method: 'GET',\n                    dataType: 'json'\n                },\n                className: 'DataStorage'\n            },\n            ids: {},\n            listens: {\n                ids: 'idsHandler'\n            }\n        },\n\n        /**\n         * Initializes provider component.\n         *\n         * @returns {Provider} Chainable.\n         */\n        initialize: function () {\n            this._super()\n                .initIdsStorage();\n\n            return this;\n        },\n\n        /**\n         * Calls 'initObservable' of parent\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super();\n            this.observe('ids');\n\n            return this;\n        },\n\n        /**\n         * Initializes ids storage.\n         *\n         * @returns {Provider} Chainable.\n         */\n        initIdsStorage: function () {\n            storage.onStorageInit(this.identifiersConfig.namespace, this.idsStorageHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Initializes ids storage handler.\n         *\n         * @param {Object} idsStorage\n         */\n        idsStorageHandler: function (idsStorage) {\n            this.idsStorage = idsStorage;\n            this.productStorage = storage.createStorage(this.productStorageConfig);\n            this.productStorage.data.subscribe(this.dataCollectionHandler.bind(this));\n\n            if (~~this.idsStorage.allowToSendRequest) {\n                customerData.reload([idsStorage.namespace]).done(this._resolveDataByIds.bind(this));\n            } else {\n                this._resolveDataByIds();\n            }\n        },\n\n        /**\n         * Callback, which load by ids from ids-storage product data\n         *\n         * @private\n         */\n        _resolveDataByIds: function () {\n            if (!window.checkout || !window.checkout.baseUrl) {\n                // We need data that the minicart provdes to determine storeId/websiteId\n                return;\n            }\n\n            // Filter initial ids to remove \"out of scope\" and \"outdated\" data\n            this.ids(\n                this.filterIds(this.ids())\n            );\n            this.initIdsListener();\n            this.idsMerger(\n                this.idsStorage.get(),\n                this.prepareDataFromCustomerData(customerData.get(this.identifiersConfig.namespace)())\n            );\n        },\n\n        /**\n         * Init ids storage listener.\n         */\n        initIdsListener: function () {\n            customerData.get(this.identifiersConfig.namespace).subscribe(function (data) {\n                this.idsMerger(this.prepareDataFromCustomerData(data));\n            }.bind(this));\n            this.idsStorage.data.subscribe(this.idsMerger.bind(this));\n        },\n\n        /**\n         * Prepare data from customerData.\n         *\n         * @param {Object} data\n         *\n         * @returns {Object}\n         */\n        prepareDataFromCustomerData: function (data) {\n            data = data.items ? data.items : data;\n\n            return data;\n        },\n\n        /**\n         * Filter ids by their lifetime in order to show only hot ids :)\n         *\n         * @param {Object} ids\n         * @returns {Array}\n         */\n        filterIds: function (ids) {\n            var _ids = {},\n                currentTime = new Date().getTime() / 1000,\n                currentProductIds = productResolver($('#product_addtocart_form')),\n                productCurrentScope = this.data.productCurrentScope,\n                scopeId = productCurrentScope === 'store' ? window.checkout.storeId :\n                productCurrentScope === 'group' ? window.checkout.storeGroupId :\n                    window.checkout.websiteId;\n\n            _.each(ids, function (id, key) {\n                if (\n                    currentTime - ids[key]['added_at'] < ~~this.idsStorage.lifetime &&\n                    !_.contains(currentProductIds, ids[key]['product_id']) &&\n                    (!id.hasOwnProperty('scope_id') || ids[key]['scope_id'] === scopeId)\n                ) {\n                    _ids[id['product_id']] = id;\n\n                }\n            }, this);\n\n            return _ids;\n        },\n\n        /**\n         * Merges id from storage and customer data\n         *\n         * @param {Object} data\n         * @param {Object} optionalData\n         */\n        idsMerger: function (data, optionalData) {\n            if (data && optionalData) {\n                data = _.extend(data, optionalData);\n            }\n\n            if (!_.isEmpty(data)) {\n                this.ids(\n                    this.filterIds(_.extend(utils.copy(this.ids()), data))\n                );\n            }\n        },\n\n        /**\n         * Ids update handler\n         *\n         * @param {Object} data\n         */\n        idsHandler: function (data) {\n            this.productStorage.setIds(this.data.currency, this.data.store, data);\n        },\n\n        /**\n         * Process data\n         *\n         * @param {Object} data\n         */\n        processData: function (data) {\n            var curData = utils.copy(this.data),\n                ids = this.ids();\n\n            delete data['data_id'];\n            data = _.values(data);\n\n            _.each(data, function (record, index) {\n                record._rowIndex = index;\n                record['added_at'] = ids[record.id]['added_at'];\n            }, this);\n\n            curData.items = data;\n            this.set('data', curData);\n        },\n\n        /**\n         * Product storage data handler\n         *\n         * @param {Object} data\n         */\n        dataCollectionHandler: function (data) {\n            data = this.filterData(data);\n            this.processData(data);\n        },\n\n        /**\n         * Filters data from product storage by ids\n         *\n         * @param {Object} data\n         *\n         * @returns {Object}\n         */\n        filterData: function (data) {\n            var result = {},\n                i = 0,\n                ids = _.keys(this.ids()),\n                length = ids.length;\n\n            for (i; i < length; i++) {\n                if (ids[i] && data[ids[i]]) {\n                    result[ids[i]] = data[ids[i]];\n                }\n            }\n\n            return result;\n        }\n    });\n});\n","Magento_Catalog/js/product/name.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/grid/columns/column',\n    'Magento_Catalog/js/product/list/column-status-validator',\n    'escaper'\n], function (Column, columnStatusValidator, escaper) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            allowedTags: ['div', 'span', 'b', 'strong', 'i', 'em', 'u', 'a']\n        },\n\n        /**\n         * Depends on this option, product name can be shown or hide. Depends on  backend configuration\n         *\n         * @returns {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'name', 'show_attributes');\n        },\n\n        /**\n         * Name column.\n         *\n         * @param {String} label\n         * @returns {String}\n         */\n        getNameUnsanitizedHtml: function (label) {\n            return escaper.escapeHtml(label, this.allowedTags);\n        }\n    });\n});\n","Magento_Catalog/js/product/addtocart-button.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/columns/column',\n    'Magento_Catalog/js/product/uenc-processor',\n    'Magento_Catalog/js/product/list/column-status-validator'\n], function (Element, uencProcessor, columnStatusValidator) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            label: ''\n        },\n\n        /**\n         * Prepare data, that will be inserted as data-mage-init attribute into button. With help of this attribute\n         * Add To * buttons can understand post data and urls\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getDataMageInit: function (row) {\n            return '{\"redirectUrl\": { \"url\" : \"'  + uencProcessor(row['add_to_cart_button'].url) + '\"}}';\n        },\n\n        /**\n         * Prepare Data-Post data that will be used in data-mage-init\n         *\n         * @param {Object} row\n         * @return {String}\n         */\n        getDataPost: function (row) {\n            return uencProcessor(row['add_to_cart_button']['post_data']);\n        },\n\n        /**\n         * Check if product has required options.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        hasRequiredOptions: function (row) {\n            return row['add_to_cart_button']['required_options'];\n        },\n\n        /**\n         * Depends on this option, \"Add to cart\" button can be shown or hide\n         *\n         * @param {Object} row\n         * @returns {Boolean}\n         */\n        isSalable: function (row) {\n            return row['is_salable'];\n        },\n\n        /**\n         * Depends on this option, stock status text can be \"In stock\" or \"Out Of Stock\"\n         *\n         * @param {Object} row\n         * @returns {Boolean}\n         */\n        isAvailable: function (row) {\n            return row['is_available'];\n        },\n\n        /**\n         * Depends on this option, \"Add to cart\" button can be shown or hide. Depends on  backend configuration\n         *\n         * @returns {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'add_to_cart', 'show_buttons');\n        },\n\n        /**\n         * Get button label.\n         *\n         * @return {String}\n         */\n        getLabel: function () {\n            return this.label;\n        }\n    });\n});\n","Magento_Catalog/js/product/learn-more.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/columns/column',\n    'Magento_Catalog/js/product/list/column-status-validator'\n], function (Column, columnStatusValidator) {\n    'use strict';\n\n    return Column.extend({\n        /**\n         * Depends on this option, \"Learn More\" link can be shown or hide. Depends on  backend configuration\n         *\n         * @returns {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'learn_more', 'show_attributes');\n        }\n    });\n});\n","Magento_Catalog/js/product/query-builder.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n        'underscore'\n    ], function (_) {\n        'use strict';\n\n        return {\n\n            /**\n             * Build query to get id\n             *\n             * @param {Object} data\n             */\n            buildQuery: function (data) {\n                var filters = [];\n\n                _.each(data, function (value, key) {\n                    filters.push({\n                        field: key,\n                        value: value,\n                        'condition_type': 'in'\n                    });\n                });\n\n                return {\n                    searchCriteria: {\n                        filterGroups: [\n                            {\n                                filters: filters\n                            }\n                        ]\n                    }\n                };\n            }\n        };\n    }\n);\n","Magento_Catalog/js/product/remaining-characters.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/translate',\n    'jquery-ui-modules/widget'\n], function ($, $t) {\n    'use strict';\n\n    $.widget('mage.remainingCharacters', {\n        options: {\n            remainingText: $t('remaining'),\n            tooManyText: $t('too many'),\n            errorClass: 'mage-error',\n            noDisplayClass: 'no-display'\n        },\n\n        /**\n         * Initializes custom option component\n         *\n         * @private\n         */\n        _create: function () {\n            this.note = $(this.options.noteSelector);\n            this.counter = $(this.options.counterSelector);\n\n            this.updateCharacterCount();\n            this.element.on('change keyup paste', this.updateCharacterCount.bind(this));\n        },\n\n        /**\n         * Updates counter message\n         */\n        updateCharacterCount: function () {\n            var length = this.element.val().length,\n                diff = this.options.maxLength - length;\n\n            this.counter.text(this._formatMessage(diff));\n            this.counter.toggleClass(this.options.noDisplayClass, length === 0);\n            this.note.toggleClass(this.options.errorClass, diff < 0);\n        },\n\n        /**\n         * Format remaining characters message\n         *\n         * @param {int} diff\n         * @returns {String}\n         * @private\n         */\n        _formatMessage: function (diff) {\n            var count = Math.abs(diff),\n                qualifier = diff < 0 ? this.options.tooManyText : this.options.remainingText;\n\n            return '(' + count + ' ' + qualifier + ')';\n        }\n    });\n\n    return $.mage.remainingCharacters;\n});\n","Magento_Catalog/js/product/view/product-ids.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko'\n], function (ko) {\n    'use strict';\n\n    return ko.observableArray([]);\n});\n","Magento_Catalog/js/product/view/product-ids-resolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'Magento_Catalog/js/product/view/product-ids'\n], function (_, productIds) {\n    'use strict';\n\n    /**\n     * Returns id's of products in form.\n     *\n     * @param {jQuery} $form\n     * @return {Array}\n     */\n    return function ($form) {\n        var idSet = productIds(),\n            product = _.findWhere($form.serializeArray(), {\n            name: 'product'\n        });\n\n        if (!_.isUndefined(product)) {\n            idSet.push(product.value);\n        }\n\n        return _.uniq(idSet);\n    };\n});\n","Magento_Catalog/js/product/view/product-info.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko'\n], function (ko) {\n    'use strict';\n\n    return ko.observableArray([]);\n});\n","Magento_Catalog/js/product/view/product-info-resolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'Magento_Catalog/js/product/view/product-info'\n], function (_, productInfo) {\n    'use strict';\n\n    /**\n     * Returns info about products in form.\n     *\n     * @param {jQuery} $form\n     * @return {Array}\n     */\n    return function ($form) {\n        var product = _.findWhere($form.serializeArray(), {\n                name: 'product'\n            });\n\n        if (!_.isUndefined(product)) {\n            productInfo().push(\n                {\n                    'id': product.value\n                }\n            );\n        }\n\n        return _.uniq(productInfo(), function (item) {\n            return item.id;\n        });\n    };\n});\n\n","Magento_Catalog/js/product/view/provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiElement',\n    'Magento_Catalog/js/product/storage/storage-service'\n], function (_, Element, storage) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            identifiersConfig: {\n                namespace: 'recently_viewed_product'\n            },\n            productStorageConfig: {\n                namespace: 'product_data_storage',\n                updateRequestConfig: {\n                    method: 'GET',\n                    dataType: 'json'\n                },\n                className: 'DataStorage'\n            }\n        },\n\n        /**\n         * Initializes\n         *\n         * @returns {Object} Chainable.\n         */\n        initialize: function () {\n            this._super();\n\n            if (window.checkout && window.checkout.baseUrl) {\n                this.initIdsStorage();\n            }\n\n            this.initDataStorage();\n\n            return this;\n        },\n\n        /**\n         * Init ids storage\n         *\n         * @returns {Object} Chainable.\n         */\n        initIdsStorage: function () {\n            storage.onStorageInit(this.identifiersConfig.namespace, this.idsStorageHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Init data storage\n         *\n         * @returns {Object} Chainable.\n         */\n        initDataStorage: function () {\n            storage.onStorageInit(this.productStorageConfig.namespace, this.dataStorageHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Init data storage handler\n         *\n         * @param {Object} dataStorage - storage instance\n         */\n        dataStorageHandler: function (dataStorage) {\n            this.productStorage = dataStorage;\n            this.productStorage.add(this.data.items);\n        },\n\n        /**\n         * Init ids storage handler\n         *\n         * @param {Object} idsStorage - storage instance\n         */\n        idsStorageHandler: function (idsStorage) {\n            this.idsStorage = idsStorage;\n            this.idsStorage.add(this.getIdentifiers());\n        },\n\n        /**\n         * Gets ids from items\n         *\n         * @returns {Object}\n         */\n        getIdentifiers: function () {\n            var result = {},\n                productCurrentScope = this.data.productCurrentScope,\n                scopeId = productCurrentScope === 'store' ? window.checkout.storeId :\n                    productCurrentScope === 'group' ? window.checkout.storeGroupId :\n                        window.checkout.websiteId;\n\n            _.each(this.data.items, function (item, key) {\n                result[productCurrentScope + '-' + scopeId + '-' + key] = {\n                    'added_at': new Date().getTime() / 1000,\n                    'product_id': key,\n                    'scope_id': scopeId\n                };\n            }, this);\n\n            return result;\n        }\n    });\n});\n","Magento_Catalog/js/product/storage/data-storage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'ko',\n    'mageUtils',\n    'Magento_Catalog/js/product/query-builder',\n    'Magento_Customer/js/customer-data',\n    'jquery/jquery-storageapi'\n], function ($, _, ko, utils, queryBuilder, customerData) {\n    'use strict';\n\n    /**\n     * Process data from API request\n     *\n     * @param {Object} data\n     * @returns {Object}\n     */\n    function getParsedDataFromServer(data) {\n        var result = {};\n\n        _.each(data.items, function (item) {\n                if (item.id) {\n                    result[item.id] = item;\n                }\n            }\n        );\n\n        return {\n            items: result\n        };\n    }\n\n    /**\n     * Set data to localStorage with support check.\n     *\n     * @param {String} namespace\n     * @param {Object} data\n     */\n    function setLocalStorageItem(namespace, data) {\n        try {\n            window.localStorage.setItem(namespace, JSON.stringify(data));\n        } catch (e) {\n            console.warn('localStorage is unavailable - skipping local caching of product data');\n            console.error(e);\n        }\n    }\n\n    return {\n\n        /**\n         * Class name\n         */\n        name: 'DataStorage',\n        request: {},\n        customerDataProvider: 'product_data_storage',\n\n        /**\n         * Initialize class\n         *\n         * @return Chainable.\n         */\n        initialize: function () {\n            if (!this.data) {\n                this.data = ko.observable({});\n            }\n\n            this.initLocalStorage()\n                .initCustomerDataReloadListener()\n                .cachesDataFromLocalStorage()\n                .initDataListener()\n                .initProvideStorage()\n                .initProviderListener();\n\n            return this;\n        },\n\n        /**\n         * Initialize listener to customer data reload\n         *\n         * @return Chainable.\n         */\n        initCustomerDataReloadListener: function () {\n            $(document).on('customer-data-invalidate', this._flushProductStorage.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Flush product storage\n         *\n         * @private\n         * @return void\n         */\n        _flushProductStorage: function (event, sections) {\n            if (_.isEmpty(sections) || _.contains(sections, 'product_data_storage')) {\n                this.localStorage.removeAll();\n            }\n        },\n\n        /**\n         * Initialize listener to data property\n         *\n         * @return Chainable.\n         */\n        initDataListener: function () {\n            this.data.subscribe(this.dataHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Initialize provider storage\n         *\n         * @return Chainable.\n         */\n        initProvideStorage: function () {\n            this.providerHandler(customerData.get(this.customerDataProvider)());\n\n            return this;\n        },\n\n        /**\n         * Handler to update \"data\" property.\n         * Sets data to localStorage\n         *\n         * @param {Object} data\n         */\n        dataHandler: function (data) {\n            if (_.isEmpty(data)) {\n                this.localStorage.removeAll();\n            } else {\n                setLocalStorageItem(this.namespace, data);\n            }\n        },\n\n        /**\n         * Handler to update data in provider.\n         *\n         * @param {Object} data\n         */\n        providerHandler: function (data) {\n            var currentData = utils.copy(this.data()),\n                ids = _.keys(data.items);\n\n            if (data.items && ids.length) {\n                //we can extend only items\n                data = data.items;\n                this.data(_.extend(currentData, data));\n            }\n        },\n\n        /**\n         * Sets data ids\n         *\n         * @param {String} currency\n         * @param {String} store\n         * @param {Object} ids\n         */\n        setIds: function (currency, store, ids) {\n            if (!this.hasInCache(currency, store, ids)) {\n                this.loadDataFromServer(currency, store, ids);\n            } else {\n                this.data.valueHasMutated();\n            }\n        },\n\n        /**\n         * Gets data from \"data\" property by identifiers\n         *\n         * @param {String} currency\n         * @param {String} store\n         * @param {Object} productIdentifiers\n         *\n         * @return {Object} data.\n         */\n        getDataByIdentifiers: function (currency, store, productIdentifiers) {\n            var data = {},\n                dataCollection = this.data(),\n                id;\n\n            for (id in productIdentifiers) {\n                if (productIdentifiers.hasOwnProperty(id)) {\n                    data[id] = dataCollection[id];\n                }\n            }\n\n            return data;\n        },\n\n        /**\n         * Checks has cached data or not\n         *\n         * @param {String} currency\n         * @param {String} store\n         * @param {Object} ids\n         *\n         * @return {Boolean}\n         */\n        hasInCache: function (currency, store, ids) {\n            var data = this.data(),\n                id;\n\n            for (id in ids) {\n                if (!data.hasOwnProperty(id) ||\n                    data[id]['currency_code'] !== currency ||\n                    ~~data[id]['store_id'] !== ~~store\n                ) {\n                    return false;\n                }\n            }\n\n            return true;\n        },\n\n        /**\n         * Load data from server by ids\n         *\n         * @param {String} currency\n         * @param {String} store\n         * @param {Object} ids\n         *\n         * @return void\n         */\n        loadDataFromServer: function (currency, store, ids) {\n            var idsArray = _.keys(ids),\n                prepareAjaxParams = {\n                    'entity_id': idsArray.join(',')\n                };\n\n            if (this.request.sent && this.hasIdsInSentRequest(ids)) {\n                return;\n            }\n\n            this.request = {\n                sent: true,\n                data: ids\n            };\n\n            this.updateRequestConfig.data = queryBuilder.buildQuery(prepareAjaxParams);\n            this.updateRequestConfig.data['store_id'] = store;\n            this.updateRequestConfig.data['currency_code'] = currency;\n            $.ajax(this.updateRequestConfig).done(function (data) {\n                this.request = {};\n                this.providerHandler(getParsedDataFromServer(data));\n            }.bind(this));\n        },\n\n        /**\n         * Each product page consist product cache data,\n         * this function prepare those data to appropriate view, and save it\n         *\n         * @param {Object} data\n         */\n        addDataFromPageCache: function (data) {\n            this.providerHandler(getParsedDataFromServer(data));\n        },\n\n        /**\n         * @param {Object} ids\n         * @returns {Boolean}\n         */\n        hasIdsInSentRequest: function (ids) {\n            var sentDataIds,\n                currentDataIds;\n\n            if (this.request.data) {\n                sentDataIds = _.keys(this.request.data);\n                currentDataIds = _.keys(ids);\n\n                return _.every(currentDataIds, function (id) {\n                    return _.lastIndexOf(sentDataIds, id) !== -1;\n                });\n            }\n\n            return false;\n        },\n\n        /**\n         * Initialize provider listener\n         *\n         * @return Chainable.\n         */\n        initProviderListener: function () {\n            customerData.get(this.customerDataProvider).subscribe(this.providerHandler.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Caches data from local storage to local scope\n         *\n         * @return Chainable.\n         */\n        cachesDataFromLocalStorage: function () {\n            this.data(this.getDataFromLocalStorage());\n\n            return this;\n        },\n\n        /**\n         * Gets data from local storage by current namespace\n         *\n         * @return {Object}.\n         */\n        getDataFromLocalStorage: function () {\n            return this.localStorage.get();\n        },\n\n        /**\n         * Initialize localStorage\n         *\n         * @return Chainable.\n         */\n        initLocalStorage: function () {\n            this.localStorage = $.initNamespaceStorage(this.namespace).localStorage;\n\n            return this;\n        }\n    };\n});\n","Magento_Catalog/js/product/storage/ids-storage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'ko',\n    'mageUtils',\n    'jquery/jquery-storageapi'\n], function ($, _, ko, utils) {\n    'use strict';\n\n    /**\n     * Set data to localStorage with support check.\n     *\n     * @param {String} namespace\n     * @param {Object} data\n     */\n    function setLocalStorageItem(namespace, data) {\n        try {\n            window.localStorage.setItem(namespace, JSON.stringify(data));\n        } catch (e) {\n            console.warn('localStorage is unavailable - skipping local caching of product data');\n            console.error(e);\n        }\n    }\n\n    return {\n\n        /**\n         * Class name\n         */\n        name: 'IdsStorage',\n\n        /**\n         * Initializes class\n         *\n         * @return Chainable.\n         */\n        initialize: function () {\n            if (!this.data) {\n                this.data = ko.observable({});\n            }\n\n            this.initCustomerDataReloadListener()\n                .initLocalStorage()\n                .cachesDataFromLocalStorage()\n                .initDataListener();\n\n            return this;\n        },\n\n        /**\n         * Gets data from local storage by current namespace\n         *\n         * @return {Object}.\n         */\n        getDataFromLocalStorage: function () {\n            return this.localStorage.get();\n        },\n\n        /**\n         * Caches data from local storage to local scope\n         *\n         * @return Chainable.\n         */\n        cachesDataFromLocalStorage: function () {\n            this.data(this.getDataFromLocalStorage());\n\n            return this;\n        },\n\n        /**\n         * Initialize localStorage\n         *\n         * @return Chainable.\n         */\n        initLocalStorage: function () {\n            this.localStorage = $.initNamespaceStorage(this.namespace).localStorage;\n\n            return this;\n        },\n\n        /**\n         * Initializes listener to \"data\" property\n         */\n        initDataListener: function () {\n            this.data.subscribe(this.internalDataHandler.bind(this));\n        },\n\n        /**\n         * Initialize listener to customer data reload\n         *\n         * @return Chainable.\n         */\n        initCustomerDataReloadListener: function () {\n            $(document).on('customer-data-reload', function (event, sections) {\n                if ((_.isEmpty(sections) || _.contains(sections, this.namespace)) && ~~this.allowToSendRequest) {\n                    this.localStorage.removeAll();\n                    this.data();\n                }\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Initializes handler to \"data\" property update\n         */\n        internalDataHandler: function (data) {\n            setLocalStorageItem(this.namespace, data);\n        },\n\n        /**\n         * Initializes handler to storage update\n         */\n        externalDataHandler: function (data) {\n            data = data.items ? data.items : data;\n\n            this.set(_.extend(utils.copy(this.data()), data));\n        }\n    };\n});\n\n","Magento_Catalog/js/product/storage/ids-storage-compare.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'ko',\n    'mageUtils',\n    'Magento_Customer/js/customer-data',\n    'Magento_Catalog/js/product/storage/ids-storage'\n], function (_, ko, utils, customerData, idsStorage) {\n    'use strict';\n\n    return _.extend(utils.copy(idsStorage), {\n\n        /**\n         * Class name\n         */\n        name: 'IdsStorageCompare',\n\n        /**\n         * Initializes class\n         *\n         * @return Chainable.\n         */\n        initialize: function () {\n            if (!this.data) {\n                this.data = ko.observable({});\n            }\n\n            if (this.provider && window.checkout && window.checkout.baseUrl) {\n                this.providerDataHandler(customerData.get(this.provider)());\n                this.initProviderListener();\n            }\n\n            this.initLocalStorage()\n                .cachesDataFromLocalStorage()\n                .initDataListener();\n\n            return this;\n        },\n\n        /**\n         * Initializes listener for external data provider\n         */\n        initProviderListener: function () {\n            customerData.get(this.provider).subscribe(this.providerDataHandler.bind(this));\n        },\n\n        /**\n         * Initializes handler for external data provider update\n         *\n         * @param {Object} data\n         */\n        providerDataHandler: function (data) {\n            data = data.items || data;\n            data = this.prepareData(data);\n\n            this.add(data);\n        },\n\n        /**\n         * Prepares data to correct interface\n         *\n         * @param {Object} data\n         *\n         * @returns {Object} data\n         */\n        prepareData: function (data) {\n            var result = {},\n                scopeId;\n\n            _.each(data, function (item) {\n                if (typeof item.productScope !== 'undefined') {\n                    scopeId = item.productScope === 'store' ? window.checkout.storeId :\n                        item.productScope === 'group' ? window.checkout.storeGroupId :\n                            window.checkout.websiteId;\n\n                    result[item.productScope + '-' + scopeId + '-' + item.id] = {\n                        'added_at': new Date().getTime() / 1000,\n                        'product_id': item.id,\n                        'scope_id': scopeId\n                    };\n                } else {\n                    result[item.id] = {\n                        'added_at': new Date().getTime() / 1000,\n                        'product_id': item.id\n                    };\n                }\n            });\n\n            return result;\n        }\n    });\n});\n","Magento_Catalog/js/product/storage/storage-service.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'mageUtils',\n    'mage/translate',\n    'Magento_Catalog/js/product/storage/ids-storage',\n    'Magento_Catalog/js/product/storage/data-storage',\n    'Magento_Catalog/js/product/storage/ids-storage-compare'\n], function ($, _, utils, $t, IdsStorage, DataStore, IdsStorageCompare) {\n    'use strict';\n\n    return (function () {\n\n        var /**\n             * {Object} storages - list of storages\n             */\n            storages = {},\n\n            /**\n             * {Object} classes - list of classes\n             */\n            classes = {},\n\n            /**\n             * {Object} prototype - methods that will be added to all storage classes to prototype property.\n             */\n            prototype = {\n\n                /**\n                 * Sets data to storage\n                 *\n                 * @param {*} data\n                 */\n                set: function (data) {\n                    if (!utils.compare(data, this.data()).equal) {\n                        this.data(data);\n                    }\n                },\n\n                /**\n                 * Adds some data to current storage data\n                 *\n                 * @param {*} data\n                 */\n                add: function (data) {\n                    if (!_.isEmpty(data)) {\n                        this.data(_.extend(utils.copy(this.data()), data));\n                    }\n                },\n\n                /**\n                 * Gets current storage data\n                 *\n                 * @returns {*} data\n                 */\n                get: function () {\n                    return this.data();\n                }\n            },\n\n            /**\n             * Required properties to storage\n             */\n            storagesInterface =  {\n                data: 'function',\n                initialize: 'function',\n                namespace: 'string'\n            },\n\n            /**\n             * Private service methods\n             */\n            _private = {\n\n                /**\n                 * Overrides class method and add ability use _super to call parent method\n                 *\n                 * @param {Object} extensionMethods\n                 * @param {Object} originInstance\n                 */\n                overrideClassMethods: function (extensionMethods, originInstance) {\n                    var methodsName = _.keys(extensionMethods),\n                        i = 0,\n                        length = methodsName.length;\n\n                    for (i; i < length; i++) {\n                        if (_.isFunction(originInstance[methodsName[i]])) {\n                            originInstance[methodsName[i]] = extensionMethods[methodsName[i]];\n                        }\n                    }\n\n                    return originInstance;\n                },\n\n                /**\n                 * Checks is storage implement interface\n                 *\n                 * @param {Object} classInstance\n                 *\n                 * @returns {Boolean}\n                 */\n                isImplementInterface: function (classInstance) {\n                    _.each(storagesInterface, function (key, value) {\n                        if (typeof classInstance[key] !== value) {\n                            return false;\n                        }\n                    });\n\n                    return true;\n                }\n            },\n\n            /**\n             * Subscribers list\n             */\n            subsctibers = {};\n\n        (function () {\n            /**\n             * @param {Object} config\n             * @return void\n             */\n            classes[IdsStorage.name] = function (config) {\n                _.extend(this, IdsStorage, config);\n            };\n\n            /**\n             * @param {Object} config\n             * @return void\n             */\n            classes[IdsStorageCompare.name] = function (config) {\n                _.extend(this, IdsStorageCompare, config);\n            };\n\n            /**\n             * @param {Object} config\n             * @return void\n             */\n            classes[DataStore.name] = function (config) {\n                _.extend(this, DataStore, config);\n            };\n\n            _.each(classes, function (classItem) {\n                classItem.prototype = prototype;\n            });\n        })();\n\n        return {\n\n            /**\n             * Creates new storage or returns if storage with declared namespace exist\n             *\n             * @param {Object} config - storage config\n             * @throws {Error}\n             * @returns {Object} storage instance\n             */\n            createStorage: function (config) {\n                var instance,\n                    initialized;\n\n                if (storages[config.namespace]) {\n                    return storages[config.namespace];\n                }\n\n                instance = new classes[config.className](config);\n\n                if (_private.isImplementInterface(instance)) {\n                    initialized = storages[config.namespace] = instance.initialize();\n                    this.processSubscribers(initialized, config);\n\n                    return initialized;\n                }\n\n                throw new Error('Class ' + config.className + $t('does not implement Storage Interface'));\n            },\n\n            /**\n             * Process subscribers\n             *\n             * Differentiate subscribers by their namespaces: recently_viewed or recently_compared\n             * and process callbacks. Callbacks can be add through onStorageInit function\n             *\n             * @param {Object} initialized\n             * @param {Object} config\n             * @return void\n             */\n            processSubscribers: function (initialized, config) {\n                if (subsctibers[config.namespace]) {\n                    _.each(subsctibers[config.namespace], function (callback) {\n                        callback(initialized);\n                    });\n\n                    delete subsctibers[config.namespace];\n                }\n            },\n\n            /**\n             * Listens storage creating by namespace\n             *\n             * @param {String} namespace\n             * @param {Function} callback\n             * @return void\n             */\n            onStorageInit: function (namespace, callback) {\n                if (storages[namespace]) {\n                    callback(storages[namespace]);\n                } else {\n                    subsctibers[namespace] ?\n                        subsctibers[namespace].push(callback) :\n                        subsctibers[namespace] = [callback];\n                }\n            },\n\n            /**\n             * Gets storage by namespace\n             *\n             * @param {String} namespace\n             *\n             * @returns {Object} storage insance\n             */\n            getStorage: function (namespace) {\n                return storages[namespace];\n            }\n        };\n    })();\n});\n\n","Magento_Catalog/js/product/list/listing.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore',\n    'Magento_Ui/js/grid/listing'\n], function (ko, _, Listing) {\n    'use strict';\n\n    return Listing.extend({\n        defaults: {\n            additionalClasses: '',\n            filteredRows: {},\n            limit: 5,\n            listens: {\n                elems: 'filterRowsFromCache',\n                '${ $.provider }:data.items': 'filterRowsFromServer'\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.filteredRows = ko.observable();\n            this.initProductsLimit();\n            this.hideLoader();\n        },\n\n        /**\n         * Initialize product limit\n         * Product limit can be configured through Ui component.\n         * Product limit are present in widget form\n         *\n         * @returns {exports}\n         */\n        initProductsLimit: function () {\n            if (this.source['page_size']) {\n                this.limit = this.source['page_size'];\n            }\n\n            return this;\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Listing} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track({\n                    rows: []\n                });\n\n            return this;\n        },\n\n        /**\n         * Sort and filter rows, that are already in magento storage cache\n         *\n         * @return void\n         */\n        filterRowsFromCache: function () {\n            this._filterRows(this.rows);\n        },\n\n        /**\n         * Sort and filter rows, that are come from backend\n         *\n         * @param {Object} rows\n         */\n        filterRowsFromServer: function (rows) {\n            this._filterRows(rows);\n        },\n\n        /**\n         * Filter rows by limit and sort them\n         *\n         * @param {Array} rows\n         * @private\n         */\n        _filterRows: function (rows) {\n            this.filteredRows(_.sortBy(rows, 'added_at').reverse().slice(0, this.limit));\n        },\n\n        /**\n         * Can retrieve product url\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getUrl: function (row) {\n            return row.url;\n        },\n\n        /**\n         * Get product attribute by code.\n         *\n         * @param {String} code\n         * @return {Object}\n         */\n        getComponentByCode: function (code) {\n            var elems = this.elems() ? this.elems() : ko.getObservable(this, 'elems'),\n                component;\n\n            component = _.filter(elems, function (elem) {\n                return elem.index === code;\n            }, this).pop();\n\n            return component;\n        }\n    });\n});\n","Magento_Catalog/js/product/list/column-status-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore'\n], function (_) {\n    'use strict';\n\n    return _.extend({\n        /**\n         * Check whether we can show column depends on server settings or not\n         *\n         * @param {Object} source\n         * @param {String} attributeCode\n         * @param {String} type\n         * @returns {Boolean}\n         */\n        isValid: function (source, attributeCode, type) {\n            var attributes;\n\n            if (!source[type]) {\n                return false;\n            }\n\n            attributes = source[type].split(',');\n\n            return _.contains(attributes, attributeCode);\n        }\n    });\n});\n","Magento_Catalog/js/product/list/toolbar.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    /**\n     * ProductListToolbarForm Widget - this widget is setting cookie and submitting form according to toolbar controls\n     */\n    $.widget('mage.productListToolbarForm', {\n\n        options: {\n            modeControl: '[data-role=\"mode-switcher\"]',\n            directionControl: '[data-role=\"direction-switcher\"]',\n            orderControl: '[data-role=\"sorter\"]',\n            limitControl: '[data-role=\"limiter\"]',\n            mode: 'product_list_mode',\n            direction: 'product_list_dir',\n            order: 'product_list_order',\n            limit: 'product_list_limit',\n            page: 'p',\n            modeDefault: 'grid',\n            directionDefault: 'asc',\n            orderDefault: 'position',\n            limitDefault: '9',\n            url: '',\n            formKey: '',\n            post: false\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this._bind(\n                $(this.options.modeControl, this.element),\n                this.options.mode,\n                this.options.modeDefault\n            );\n            this._bind(\n                $(this.options.directionControl, this.element),\n                this.options.direction,\n                this.options.directionDefault\n            );\n            this._bind(\n                $(this.options.orderControl, this.element),\n                this.options.order,\n                this.options.orderDefault\n            );\n            this._bind(\n                $(this.options.limitControl, this.element),\n                this.options.limit,\n                this.options.limitDefault\n            );\n        },\n\n        /** @inheritdoc */\n        _bind: function (element, paramName, defaultValue) {\n            if (element.is('select')) {\n                element.on('change', {\n                    paramName: paramName,\n                    'default': defaultValue\n                }, $.proxy(this._processSelect, this));\n            } else {\n                element.on('click', {\n                    paramName: paramName,\n                    'default': defaultValue\n                }, $.proxy(this._processLink, this));\n            }\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _processLink: function (event) {\n            event.preventDefault();\n            this.changeUrl(\n                event.data.paramName,\n                $(event.currentTarget).data('value'),\n                event.data.default\n            );\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _processSelect: function (event) {\n            this.changeUrl(\n                event.data.paramName,\n                event.currentTarget.options[event.currentTarget.selectedIndex].value,\n                event.data.default\n            );\n        },\n\n        /**\n         * @private\n         */\n        getUrlParams: function () {\n            var decode = window.decodeURIComponent,\n                urlPaths = this.options.url.split('?'),\n                urlParams = urlPaths[1] ? urlPaths[1].split('&') : [],\n                params = {},\n                parameters, i;\n\n            for (i = 0; i < urlParams.length; i++) {\n                parameters = urlParams[i].split('=');\n                params[decode(parameters[0])] = parameters[1] !== undefined ?\n                    decode(parameters[1].replace(/\\+/g, '%20')) :\n                    '';\n            }\n\n            return params;\n        },\n\n        /**\n         * @returns {String}\n         * @private\n         */\n        getCurrentLimit: function () {\n            return this.getUrlParams()[this.options.limit] || this.options.limitDefault;\n        },\n\n        /**\n         * @returns {String}\n         * @private\n         */\n        getCurrentPage: function () {\n            return this.getUrlParams()[this.options.page] || 1;\n        },\n\n        /**\n         * @param {String} paramName\n         * @param {*} paramValue\n         * @param {*} defaultValue\n         */\n        changeUrl: function (paramName, paramValue, defaultValue) {\n            var urlPaths = this.options.url.split('?'),\n                baseUrl = urlPaths[0],\n                paramData = this.getUrlParams(),\n                currentPage = this.getCurrentPage(),\n                form, params, key, input, formKey, newPage;\n\n            if (currentPage > 1 && paramName === this.options.mode) {\n                delete paramData[this.options.page];\n            }\n\n            if (currentPage > 1 && paramName === this.options.limit) {\n                newPage = Math.floor(this.getCurrentLimit() * (currentPage - 1) / paramValue) + 1;\n\n                if (newPage > 1) {\n                    paramData[this.options.page] = newPage;\n                } else {\n                    delete paramData[this.options.page];\n                }\n            }\n\n            paramData[paramName] = paramValue;\n\n            if (this.options.post) {\n                form = document.createElement('form');\n                params = [this.options.mode, this.options.direction, this.options.order, this.options.limit];\n\n                for (key in paramData) {\n                    if (params.indexOf(key) !== -1) { //eslint-disable-line max-depth\n                        input = document.createElement('input');\n                        input.name = key;\n                        input.value = paramData[key];\n                        form.appendChild(input);\n                        delete paramData[key];\n                    }\n                }\n                formKey = document.createElement('input');\n                formKey.name = 'form_key';\n                formKey.value = this.options.formKey;\n                form.appendChild(formKey);\n\n                paramData = $.param(paramData);\n                baseUrl += paramData.length ? '?' + paramData : '';\n\n                form.action = baseUrl;\n                form.method = 'POST';\n                document.body.appendChild(form);\n                form.submit();\n            } else {\n                if (paramValue == defaultValue) { //eslint-disable-line eqeqeq\n                    delete paramData[paramName];\n                }\n\n                paramData = $.param(paramData);\n                location.href = baseUrl + (paramData.length ? '?' + paramData : '');\n            }\n        }\n    });\n\n    return $.mage.productListToolbarForm;\n});\n","Magento_Catalog/js/product/list/columns/price-box.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'underscore',\n    'uiRegistry',\n    'mageUtils',\n    'uiCollection',\n    'Magento_Catalog/js/product/list/column-status-validator',\n    'uiLayout'\n], function (ko, _, registry, utils, Collection, columnStatusValidator, layout) {\n    'use strict';\n\n    return Collection.extend({\n        defaults: {\n            label: '',\n            hasSpecialPrice: false,\n            showMinimalPrice: false,\n            useLinkForAsLowAs: false,\n            visible: true,\n            headerTmpl: 'ui/grid/columns/text',\n            bodyTmpl: 'Magento_Catalog/product/price/price_box',\n            disableAction: false,\n            controlVisibility: true,\n            sortable: false,\n            sorting: false,\n            draggable: true,\n            fieldClass: {},\n            renders: {\n                default: {}\n            },\n            ignoreTmpls: {\n                fieldAction: true\n            },\n            statefull: {\n                visible: true,\n                sorting: true\n            },\n            imports: {\n                exportSorting: 'sorting'\n            },\n            listens: {\n                elems: ''\n            },\n            modules: {\n                source: '${ $.provider }'\n            },\n            pricesInit: {}\n        },\n\n        /**\n         * Sort prices api\n         *\n         * @returns {exports}\n         */\n        sort: function () {\n            return this;\n        },\n\n        /**\n         * Check whether is allowed to render price or not\n         *\n         * @returns {*}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'price', 'show_attributes');\n        },\n\n        /**\n         * Retrieve array of prices, that should be rendered for specific product\n         *\n         * @param {Array} row\n         * @return {Array}\n         */\n        getPrices: function (row) {\n            var elems = this.elems() ? this.elems() : ko.getObservable(this, 'elems'),\n                result;\n\n            //we cant take type of product from row\n            this.initPrices(row);\n            result = _.filter(elems, function (elem) {\n                return elem.productType === row.type;\n            });\n\n            return result;\n        },\n\n        /**\n         * Recursive Merging of objects\n         *\n         * @param {Array} target\n         * @param {Array} source\n         * @returns {Array}\n         * @private\n         */\n        _deepObjectExtend: function (target, source) {\n            var _target = utils.copy(target);\n\n            _.each(source, function (value, key) {\n                if (_.keys(value).length && typeof _target[key] !== 'undefined') {\n                    _target[key] = this._deepObjectExtend(_target[key], value);\n                } else {\n                    _target[key] = value;\n                }\n            }, this);\n\n            return _target;\n        },\n\n        /**\n         * Init price type box, in cases when product type has custom component or bodyTmpl\n         *\n         * @param {String} productType\n         * @private\n         */\n        _initPriceWithCustomMetaData: function (productType) {\n            var price = this._deepObjectExtend(\n                this.renders.prices['default'],\n                this.renders.prices[productType]\n            );\n\n            price.name = productType + '.default';\n            price.parent = this.name;\n            price.source = this.source;\n            price.productType = productType;\n            layout([price]);\n        },\n\n        /**\n         * Init Prices by product type and add them to layout\n         *\n         * @param {Array} _priceData\n         * @param {String} productType\n         * @private\n         */\n        _initPricesForProductType: function (_priceData, productType) {\n            var prices = [];\n\n            this._setPriceNamesToPrices(_priceData, productType);\n            _.sortBy(_priceData, this._comparePrices);\n\n            _.each(_priceData, function (priceData) {\n                if (!priceData.component) {\n                    return;\n                }\n\n                priceData.parent = this.name;\n                priceData.provider = this.provider;\n                priceData.productType = productType;\n                priceData = utils.template(priceData, this);\n                prices.push(priceData);\n            }, this);\n\n            layout(prices);\n        },\n\n        /**\n         * Init dynamic price components\n         *\n         * @param {Array} row\n         * @returns {void}\n         */\n        initPrices: function (row) {\n            var _priceData = [],\n                productType = row.type,\n                defaultPrice = this.renders.prices['default'];\n\n            if (this.pricesInit[productType]) {\n                return true;\n            }\n\n            this.pricesInit[productType] = true;\n\n            if (this.renders.prices[productType] && this._needToApplyCustomTemplate(this.renders.prices[productType])) {\n                return this._initPriceWithCustomMetaData(productType);\n            }\n\n            if (this.renders.prices[productType] && this.renders.prices[productType].children) {\n                _priceData = this._deepObjectExtend(defaultPrice.children, this.renders.prices[productType].children);\n            } else {\n                _priceData = defaultPrice.children;\n            }\n\n            return this._initPricesForProductType(_priceData, productType);\n        },\n\n        /**\n         * Set name to all price components\n         *\n         * @param {Array} prices\n         * @param {String} productType\n         * @private\n         */\n        _setPriceNamesToPrices: function (prices, productType) {\n            _.each(prices, function (price, name) {\n                price.priceType = name;\n                price.name = name + '.' + productType;\n            });\n\n            return prices;\n        },\n\n        /**\n         * Sort callback to compare prices by sort order\n         *\n         * @param {Number} firstPrice\n         * @param {Number} secondPrice\n         * @returns {Number}\n         * @private\n         */\n        _comparePrices: function (firstPrice, secondPrice) {\n            if (firstPrice.sortOrder < secondPrice.sortOrder) {\n                return -1;\n            }\n\n            if (firstPrice.sortOrder > secondPrice.sortOrder) {\n                return 1;\n            }\n\n            return 0;\n        },\n\n        /**\n         * Check whether metadata of product type prices was changed, and we should\n         * to apply custom template or custom component\n         *\n         * @param {Array} productData\n         * @returns {*}\n         * @private\n         */\n        _needToApplyCustomTemplate: function (productData) {\n            return productData.bodyTmpl || productData.component;\n        },\n\n        /**\n         * Returns path to the columns' body template.\n         *\n         * @returns {String}\n         */\n        getBody: function () {\n            return this.bodyTmpl;\n        },\n\n        /**\n         * Get price label.\n         *\n         * @returns {String}\n         */\n        getLabel: function () {\n            return this.label;\n        }\n    });\n});\n","Magento_Catalog/js/product/list/columns/final-price.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiRegistry',\n    'mageUtils',\n    'uiCollection'\n], function (_, registry, utils, Collection) {\n    'use strict';\n\n    return Collection.extend({\n        defaults: {\n            label: false,\n            headerTmpl: 'ui/grid/columns/text',\n            showMinimalPrice: false,\n            showMaximumPrice: false,\n            useLinkForAsLowAs: false,\n            bodyTmpl: 'Magento_Catalog/product/final_price',\n            priceWrapperCssClasses: '',\n            priceWrapperAttr: {}\n        },\n\n        /**\n         * Get product final price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} final price html\n         */\n        getPrice: function (row) {\n            return row['price_info']['formatted_prices']['final_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} final price html\n         */\n        getPriceUnsanitizedHtml: function (row) {\n            return this.getPrice(row);\n        },\n\n        /**\n         * Get product regular price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} regular price html\n         */\n        getRegularPrice: function (row) {\n            return row['price_info']['formatted_prices']['regular_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getRegularPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} regular price html\n         */\n        getRegularPriceUnsanitizedHtml: function (row) {\n            return this.getRegularPrice(row);\n        },\n\n        /**\n         * Check if product has a price range.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        hasPriceRange: function (row) {\n            return row['price_info']['max_regular_price'] !== row['price_info']['min_regular_price'];\n        },\n\n        /**\n         * Check if product has special price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} special price html\n         */\n        hasSpecialPrice: function (row) {\n            return row['price_info']['regular_price'] > row['price_info']['final_price'];\n        },\n\n        /**\n         * Check if product has minimal price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal price html\n         */\n        isMinimalPrice: function (row) {\n            return row['price_info']['minimal_price'] < row['price_info']['final_price'];\n        },\n\n        /**\n         * Get product minimal price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal price html\n         */\n        getMinimalPrice: function (row) {\n            return row['price_info']['formatted_prices']['minimal_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMinimalPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal price html\n         */\n        getMinimalPriceUnsanitizedHtml: function (row) {\n            return this.getMinimalPrice(row);\n        },\n\n        /**\n         * Check if product is salable.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        isSalable: function (row) {\n            return row['is_salable'];\n        },\n\n        /**\n         * Get product maximum price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} maximum price html\n         */\n        getMaxPrice: function (row) {\n            return row['price_info']['formatted_prices']['max_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMaxPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} maximum price html\n         */\n        getMaxPriceUnsanitizedHtml: function (row) {\n            return this.getMaxPrice(row);\n        },\n\n        /**\n         * Get product maximum regular price in case of price range and special price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} maximum regular price html\n         */\n        getMaxRegularPrice: function (row) {\n            return row['price_info']['formatted_prices']['max_regular_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMaxRegularPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} maximum regular price html\n         */\n        getMaxRegularPriceUnsanitizedHtml: function (row) {\n            return this.getMaxRegularPrice(row);\n        },\n\n        /**\n         * Get product minimal regular price in case of price range and special price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal regular price html\n         */\n        getMinRegularPrice: function (row) {\n            return row['price_info']['formatted_prices']['min_regular_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMinRegularPrice.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} minimal regular price html\n         */\n        getMinRegularPriceUnsanitizedHtml: function (row) {\n            return this.getMinRegularPrice(row);\n        },\n\n        /**\n         * Get adjustments names and return as string.\n         *\n         * @return {String} adjustments classes\n         */\n        getAdjustmentCssClasses: function () {\n            return _.pluck(this.getAdjustments(), 'index').join(' ');\n        },\n\n        /**\n         * Get product minimal price as number.\n         *\n         * @param {Object} row\n         * @return {Number} minimal price amount\n         */\n        getMinimalPriceAmount: function (row) {\n            return row['price_info']['minimal_price'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getMinimalPriceAmount\n         *\n         * @param {Object} row\n         * @return {Number} minimal price amount\n         */\n        getMinimalPriceAmountUnsanitizedHtml: function (row) {\n            return this.getMinimalPriceAmount(row);\n        },\n\n        /**\n         * Get product minimal regular price as number in case of special price.\n         *\n         * @param {Object} row\n         * @return {Number} minimal regular price amount\n         */\n        getMinimalRegularPriceAmount: function (row) {\n            return row['price_info']['min_regular_price'];\n        },\n\n        /**\n         * Get product maximum price as number.\n         *\n         * @param {Object} row\n         * @return {Number} maximum price amount\n         */\n        getMaximumPriceAmount: function (row) {\n            return row['price_info']['max_price'];\n        },\n\n        /**\n         * Get product maximum regular price as number in case of special price.\n         *\n         * @param {Object} row\n         * @return {Number} maximum regular price amount\n         */\n        getMaximumRegularPriceAmount: function (row) {\n            return row['price_info']['max_regular_price'];\n        },\n\n        /**\n         * Check if minimal regular price exist for product.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        showMinRegularPrice: function (row) {\n            return this.getMinimalPriceAmount(row) < this.getMinimalRegularPriceAmount(row);\n        },\n\n        /**\n         * Check if maximum regular price exist for product.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        showMaxRegularPrice: function (row) {\n            return this.getMaximumPriceAmount(row) < this.getMaximumRegularPriceAmount(row);\n        },\n\n        /**\n         * Get path to the columns' body template.\n         *\n         * @returns {String}\n         */\n        getBody: function () {\n            return this.bodyTmpl;\n        },\n\n        /**\n         * Get all price adjustments.\n         *\n         * @returns {Object}\n         */\n        getAdjustments: function () {\n            var adjustments = this.elems();\n\n            _.each(adjustments, function (adjustment) {\n                adjustment.setPriceType(this.priceType);\n                adjustment.source = this.source;\n            }, this);\n\n            return adjustments;\n        }\n    });\n});\n","Magento_Catalog/js/product/list/columns/pricetype-box.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'underscore',\n    'uiCollection'\n], function (ko, _, Collection) {\n    'use strict';\n\n    return Collection.extend({\n        /**\n         * Find from all price ui components, price with specific code, init source on it and set priceType\n         *\n         * @param {String} code\n         * @returns {*|T}\n         */\n        getPriceByCode: function (code) {\n            var elems = this.elems() ? this.elems() : ko.getObservable(this, 'elems'),\n                price;\n\n            price = _.filter(elems, function (elem) {\n                return elem.index.split('.').shift() === code;\n            }, this).pop();\n\n            price.source = this.source();\n            price.priceType = code;\n\n            return price;\n        },\n\n        /**\n         * Retrieve body template\n         *\n         * @returns {String}\n         */\n        getBody: function () {\n            return this.bodyTmpl;\n        },\n\n        /**\n         * Check whether price has price range, depends on different options, that can be choose\n         *\n         * @param {Object} row\n         * @returns {Boolean}\n         */\n        hasPriceRange: function (row) {\n            return row['price_info']['max_regular_price'] !== row['price_info']['min_regular_price'];\n        }\n    });\n});\n","Magento_Catalog/js/product/list/columns/image.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'Magento_Ui/js/grid/columns/column',\n    'Magento_Catalog/js/product/list/column-status-validator'\n], function (_, Element, columnStatusValidator) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            bodyTmpl: 'Magento_Catalog/product/list/columns/image',\n            imageCode: 'default',\n            image: {}\n        },\n\n        /**\n         * Find image by code in scope of images\n         *\n         * @param {Object} images\n         * @returns {*|T}\n         */\n        getImage: function (images) {\n            return _.filter(images, function (image) {\n                return this.imageCode === image.code;\n            }, this).pop();\n        },\n\n        /**\n         * Get image path.\n         *\n         * @param {Object} row\n         * @return {String}\n         */\n        getImageUrl: function (row) {\n            return this.getImage(row.images).url;\n        },\n\n        /**\n         * Get image box width.\n         *\n         * @param {Object} row\n         * @return {Number}\n         */\n        getWidth: function (row) {\n            return this.getImage(row.images).width;\n        },\n\n        /**\n         * Get image box height.\n         *\n         * @param {Object} row\n         * @return {Number}\n         */\n        getHeight: function (row) {\n            return this.getImage(row.images).height;\n        },\n\n        /**\n         * Get resized image width.\n         *\n         * @param {Object} row\n         * @return {Number}\n         */\n        getResizedImageWidth: function (row) {\n            return this.getImage(row.images)['resized_width'];\n        },\n\n        /**\n         * Get resized image height.\n         *\n         * @param {Object} row\n         * @return {Number}\n         */\n        getResizedImageHeight: function (row) {\n            return this.getImage(row.images)['resized_height'];\n        },\n\n        /**\n         * Get image alt text.\n         *\n         * @param {Object} row\n         * @return {String}\n         */\n        getLabel: function (row) {\n            if (!this.imageExists(row)) {\n                return this._super();\n            }\n\n            return this.getImage(row.images).label;\n        },\n\n        /**\n         * Check if image exist.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        imageExists: function (row) {\n            return this.getImage(row.images) !== 'undefined';\n        },\n\n        /**\n         * Check if component must be shown.\n         *\n         * @return {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'image', 'show_attributes');\n        }\n    });\n});\n","Magento_Catalog/js/view/compare-products.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Customer/js/customer-data',\n    'jquery',\n    'underscore',\n    'mage/mage',\n    'mage/decorate'\n], function (Component, customerData, $, _) {\n    'use strict';\n\n    var sidebarInitialized = false,\n        compareProductsReloaded = false;\n\n    /**\n     * Initialize sidebar\n     */\n    function initSidebar() {\n        if (sidebarInitialized) {\n            return;\n        }\n\n        sidebarInitialized = true;\n        $('[data-role=compare-products-sidebar]').decorate('list', true);\n    }\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.compareProducts = customerData.get('compare-products');\n            if (!compareProductsReloaded\n                && !_.isEmpty(this.compareProducts())\n                //Expired section names are reloaded on page load\n                && _.indexOf(customerData.getExpiredSectionNames(), 'compare-products') === -1\n                && window.checkout\n                && window.checkout.websiteId\n                && window.checkout.websiteId !== this.compareProducts().websiteId\n            ) {\n                //set count to 0 to prevent \"compared products\" blocks and count to show with wrong count and items\n                this.compareProducts().count = 0;\n                customerData.reload(['compare-products'], false);\n                compareProductsReloaded = true;\n            }\n            initSidebar();\n        }\n    });\n});\n","Magento_Catalog/js/view/image.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.template = window.checkout.imageTemplate || this.template;\n        }\n    });\n});\n","requirejs/domReady.js":"/**\n * @license RequireJS domReady 2.0.1 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/requirejs/domReady for details\n */\n/*jslint */\n/*global require: false, define: false, requirejs: false,\n  window: false, clearInterval: false, document: false,\n  self: false, setInterval: false */\n\n\ndefine(function () {\n    'use strict';\n\n    var isTop, testDiv, scrollIntervalId,\n        isBrowser = typeof window !== \"undefined\" && window.document,\n        isPageLoaded = !isBrowser,\n        doc = isBrowser ? document : null,\n        readyCalls = [];\n\n    function runCallbacks(callbacks) {\n        var i;\n        for (i = 0; i < callbacks.length; i += 1) {\n            callbacks[i](doc);\n        }\n    }\n\n    function callReady() {\n        var callbacks = readyCalls;\n\n        if (isPageLoaded) {\n            //Call the DOM ready callbacks\n            if (callbacks.length) {\n                readyCalls = [];\n                runCallbacks(callbacks);\n            }\n        }\n    }\n\n    /**\n     * Sets the page as loaded.\n     */\n    function pageLoaded() {\n        if (!isPageLoaded) {\n            isPageLoaded = true;\n            if (scrollIntervalId) {\n                clearInterval(scrollIntervalId);\n            }\n\n            callReady();\n        }\n    }\n\n    if (isBrowser) {\n        if (document.addEventListener) {\n            //Standards. Hooray! Assumption here that if standards based,\n            //it knows about DOMContentLoaded.\n            document.addEventListener(\"DOMContentLoaded\", pageLoaded, false);\n            window.addEventListener(\"load\", pageLoaded, false);\n        } else if (window.attachEvent) {\n            window.attachEvent(\"onload\", pageLoaded);\n\n            testDiv = document.createElement('div');\n            try {\n                isTop = window.frameElement === null;\n            } catch (e) {}\n\n            //DOMContentLoaded approximation that uses a doScroll, as found by\n            //Diego Perini: http://javascript.nwbox.com/IEContentLoaded/,\n            //but modified by other contributors, including jdalton\n            if (testDiv.doScroll && isTop && window.external) {\n                scrollIntervalId = setInterval(function () {\n                    try {\n                        testDiv.doScroll();\n                        pageLoaded();\n                    } catch (e) {}\n                }, 30);\n            }\n        }\n\n        //Check if document is no longer loading, and if so, just trigger page load\n        //listeners. Latest webkit browsers also use \"interactive\", and\n        //will fire the onDOMContentLoaded before \"interactive\" but not after\n        //entering \"interactive\" or \"complete\". More details:\n        //http://dev.w3.org/html5/spec/the-end.html#the-end\n        //http://stackoverflow.com/questions/3665561/document-readystate-of-interactive-vs-ondomcontentloaded\n        //Hmm, this is more complicated on further use, see \"firing too early\"\n        //bug: https://github.com/requirejs/domReady/issues/1\n        //so removing the || document.readyState === \"interactive\" test.\n        //There is still a window.onload binding that should get fired if\n        //DOMContentLoaded is missed.\n        if (document.readyState !== \"loading\") {\n            // Handle it asynchronously to allow scripts the opportunity to delay ready\n            setTimeout(pageLoaded);\n        }\n    }\n\n    /** START OF PUBLIC API **/\n\n    /**\n     * Registers a callback for DOM ready. If DOM is already ready, the\n     * callback is called immediately.\n     * @param {Function} callback\n     */\n    function domReady(callback) {\n        if (isPageLoaded) {\n            callback(doc);\n        } else {\n            readyCalls.push(callback);\n        }\n        return domReady;\n    }\n\n    domReady.version = '2.0.1';\n\n    /**\n     * Loader Plugin API method\n     */\n    domReady.load = function (name, req, onLoad, config) {\n        if (config.isBuild) {\n            onLoad(null);\n        } else {\n            domReady(onLoad);\n        }\n    };\n\n    /** END OF PUBLIC API **/\n\n    return domReady;\n});\n","Magento_OfflinePayments/js/view/payment/offline-payments.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'uiComponent',\n    'Magento_Checkout/js/model/payment/renderer-list'\n], function (Component, rendererList) {\n    'use strict';\n\n    rendererList.push(\n        {\n            type: 'checkmo',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method'\n        },\n        {\n            type: 'banktransfer',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/banktransfer-method'\n        },\n        {\n            type: 'cashondelivery',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method'\n        },\n        {\n            type: 'purchaseorder',\n            component: 'Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method'\n        }\n    );\n\n    /** Add view logic here if needed */\n    return Component.extend({});\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/checkmo'\n        },\n\n        /**\n         * Returns send check to info.\n         *\n         * @return {*}\n         */\n        getMailingAddress: function () {\n            return window.checkoutConfig.payment.checkmo.mailingAddress;\n        },\n\n        /**\n         * Returns payable to info.\n         *\n         * @return {*}\n         */\n        getPayableTo: function () {\n            return window.checkoutConfig.payment.checkmo.payableTo;\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default',\n    'jquery',\n    'mage/validation'\n], function (Component, $) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/purchaseorder-form',\n            purchaseOrderNumber: ''\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('purchaseOrderNumber');\n\n            return this;\n        },\n\n        /**\n         * @return {Object}\n         */\n        getData: function () {\n            return {\n                method: this.item.method,\n                'po_number': this.purchaseOrderNumber(),\n                'additional_data': null\n            };\n        },\n\n        /**\n         * @return {jQuery}\n         */\n        validate: function () {\n            var form = 'form[data-role=purchaseorder-form]';\n\n            return $(form).validation() && $(form).validation('isValid');\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/banktransfer-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'ko',\n    'Magento_Checkout/js/view/payment/default'\n], function (ko, Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/banktransfer'\n        },\n\n        /**\n         * Get value of instruction field.\n         * @returns {String}\n         */\n        getInstructions: function () {\n            return window.checkoutConfig.payment.instructions[this.item.method];\n        }\n    });\n});\n","Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* @api */\ndefine([\n    'Magento_Checkout/js/view/payment/default'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_OfflinePayments/payment/cashondelivery'\n        },\n\n        /**\n         * Returns payment method instructions.\n         *\n         * @return {*}\n         */\n        getInstructions: function () {\n            return window.checkoutConfig.payment.instructions[this.item.method];\n        }\n    });\n});\n","Magento_Weee/js/tax-toggle.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    /**\n     * @param {Object} config\n     * @param {jQuery.Event} e\n     */\n    function onToggle(config, e) {\n        var elem = $(e.currentTarget),\n            expandedClassName = config.expandedClassName || 'cart-tax-total-expanded';\n\n        elem.toggleClass(expandedClassName);\n\n        $(config.itemTaxId).toggle();\n    }\n\n    return function (data, el) {\n        $(el).on('click', onToggle.bind(null, data));\n    };\n});\n","Magento_Weee/js/price/adjustment.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/columns/column'\n], function (Element) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            bodyTmpl: 'Magento_Weee/price/adjustment',\n            dataSource: '${ $.parentName }.provider',\n            //Weee configuration constants can be configured from backend\n            inclFptWithDesc: 1,//show FPT and description\n            inclFpt: 0, //show FPT attribute\n            exclFpt: 2, //do not show FPT\n            bothFptPrices: 3 //show price without FPT and with FPT and with description\n        },\n\n        /**\n         * Get Weee attributes.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeAttributes: function (row) {\n            return row['price_info']['extension_attributes']['weee_attributes'];\n        },\n\n        /**\n         * Get Weee without Tax attributes.\n         *\n         * @param {Object} taxAmount\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeTaxWithoutTax: function (taxAmount) {\n            return taxAmount['amount_excl_tax'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getWeeeTaxWithoutTax.\n         *\n         * @param {Object} taxAmount\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeTaxWithoutTaxUnsanitizedHtml: function (taxAmount) {\n            return this.getWeeeTaxWithoutTax(taxAmount);\n        },\n\n        /**\n         * Get Weee with Tax attributes.\n         *\n         * @param {Object} taxAmount\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeTaxWithTax: function (taxAmount) {\n            return taxAmount['tax_amount_incl_tax'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getWeeeTaxWithTax.\n         *\n         * @param {Object} taxAmount\n         * @return {HTMLElement} Weee html\n         */\n        getWeeeTaxWithTaxUnsanitizedHtml: function (taxAmount) {\n            return this.getWeeeTaxWithTax(taxAmount);\n        },\n\n        /**\n         * Get Weee Tax name.\n         *\n         * @param {String} taxAmount\n         * @return {String} Weee name\n         */\n        getWeeTaxAttributeName: function (taxAmount) {\n            return taxAmount['attribute_code'];\n        },\n\n        /**\n         * Set price type.\n         *\n         * @param {String} priceType\n         * @return {Object}\n         */\n        setPriceType: function (priceType) {\n            this.taxPriceType = priceType;\n\n            return this;\n        },\n\n        /**\n         * Check if Weee Tax must be shown.\n         *\n         * @param {Object} row\n         * @return {Boolean}\n         */\n        isShown: function (row) {\n            return row['price_info']['extension_attributes']['weee_attributes'].length;\n        },\n\n        /**\n         * Get Weee final price.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} Weee final price html\n         */\n        getWeeeAdjustment: function (row) {\n            return row['price_info']['extension_attributes']['weee_adjustment'];\n        },\n\n        /**\n         * UnsanitizedHtml version of getWeeeAdjustment.\n         *\n         * @param {Object} row\n         * @return {HTMLElement} Weee final price html\n         */\n        getWeeeAdjustmentUnsanitizedHtml: function (row) {\n            return this.getWeeeAdjustment(row);\n        },\n\n        /**\n         * Return whether display setting is to display price including FPT only.\n         *\n         * @return {Boolean}\n         */\n        displayPriceInclFpt: function () {\n            return +this.source.data.displayWeee === this.inclFpt;\n        },\n\n        /**\n         * Return whether display setting is to display\n         * price including FPT and FPT description.\n         *\n         * @return {Boolean}\n         */\n        displayPriceInclFptDescr: function () {\n            return +this.source.data.displayWeee === this.inclFptWithDesc;\n        },\n\n        /**\n         * Return whether display setting is to display price\n         * excluding FPT but including FPT description and final price.\n         *\n         * @return {Boolean}\n         */\n        displayPriceExclFptDescr: function () {\n            return +this.source.data.displayWeee === this.exclFpt;\n        },\n\n        /**\n         * Return whether display setting is to display price excluding FPT.\n         *\n         * @return {Boolean}\n         */\n        displayPriceExclFpt: function () {\n            return +this.source.data.displayWeee === this.bothFptPrices;\n        },\n\n        /**\n         * Return whether display setting is to display price excluding tax.\n         *\n         * @return {Boolean}\n         */\n        displayPriceExclTax: function () {\n            return +this.source.data.displayTaxes === this.inclFptWithDesc;\n        },\n\n        /**\n         * Return whether display setting is to display price including tax.\n         *\n         * @return {Boolean}\n         */\n        displayPriceInclTax: function () {\n            return +this.source.data.displayTaxes === this.exclFpt;\n        },\n\n        /**\n         * Return whether display setting is to display\n         * both price including tax and price excluding tax.\n         *\n         * @return {Boolean}\n         */\n        displayBothPricesTax: function () {\n            return +this.source.data.displayTaxes === this.bothFptPrices;\n        }\n    });\n});\n","Magento_Weee/js/view/cart/totals/weee.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Weee/js/view/checkout/summary/weee'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n\n        /**\n         * @override\n         */\n        isFullMode: function () {\n            return true;\n        }\n    });\n});\n","Magento_Weee/js/view/checkout/summary/weee.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/model/totals',\n    'Magento_Catalog/js/price-utils'\n], function (Component, quote, totals) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Weee/checkout/summary/weee'\n        },\n        isIncludedInSubtotal: window.checkoutConfig.isIncludedInSubtotal,\n        totals: totals.totals,\n\n        /**\n         * @returns {Number}\n         */\n        getWeeeTaxSegment: function () {\n            var weee = totals.getSegment('weee_tax') || totals.getSegment('weee');\n\n            if (weee !== null && weee.hasOwnProperty('value')) {\n                return weee.value;\n            }\n\n            return 0;\n        },\n\n        /**\n         * Get weee value\n         * @returns {String}\n         */\n        getValue: function () {\n            return this.getFormattedPrice(this.getWeeeTaxSegment());\n        },\n\n        /**\n         * Weee display flag\n         * @returns {Boolean}\n         */\n        isDisplayed: function () {\n            return this.isFullMode() && this.getWeeeTaxSegment() > 0;\n        }\n    });\n});\n","Magento_Weee/js/view/checkout/summary/item/price/row_excl_tax.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Weee/js/view/checkout/summary/item/price/weee'\n], function (weee) {\n    'use strict';\n\n    return weee.extend({\n        defaults: {\n            template: 'Magento_Weee/checkout/summary/item/price/row_excl_tax'\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getFinalRowDisplayPriceExclTax: function (item) {\n            var rowTotalExclTax = parseFloat(item['row_total']);\n\n            if (!window.checkoutConfig.getIncludeWeeeFlag) {\n                rowTotalExclTax += parseFloat(item['qty']) *\n                    parseFloat(item['weee_tax_applied_amount']);\n            }\n\n            return rowTotalExclTax;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getRowDisplayPriceExclTax: function (item) {\n            var rowTotalExclTax = parseFloat(item['row_total']);\n\n            if (window.checkoutConfig.getIncludeWeeeFlag) {\n                rowTotalExclTax += this.getRowWeeeTaxExclTax(item);\n            }\n\n            return rowTotalExclTax;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getRowWeeeTaxExclTax: function (item) {\n            var totalWeeeTaxExclTaxApplied = 0,\n                weeeTaxAppliedAmounts;\n\n            if (item['weee_tax_applied']) {\n                weeeTaxAppliedAmounts = JSON.parse(item['weee_tax_applied']);\n                weeeTaxAppliedAmounts.forEach(function (weeeTaxAppliedAmount) {\n                    totalWeeeTaxExclTaxApplied += parseFloat(Math.max(weeeTaxAppliedAmount['row_amount'], 0));\n                });\n            }\n\n            return totalWeeeTaxExclTaxApplied;\n        }\n\n    });\n});\n","Magento_Weee/js/view/checkout/summary/item/price/weee.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Checkout/js/view/summary/abstract-total',\n    'Magento_Checkout/js/model/quote'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        /**\n         * @param {Object} item\n         * @return {Boolean}\n         */\n        isDisplayPriceWithWeeeDetails: function (item) {\n            if (!parseFloat(item['weee_tax_applied_amount']) || parseFloat(item['weee_tax_applied_amount'] <= 0)) {\n                return false;\n            }\n\n            return window.checkoutConfig.isDisplayPriceWithWeeeDetails;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Boolean}\n         */\n        isDisplayFinalPrice: function (item) {\n            if (!parseFloat(item['weee_tax_applied_amount'])) {\n                return false;\n            }\n\n            return window.checkoutConfig.isDisplayFinalPrice;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Array}\n         */\n        getWeeeTaxApplied: function (item) {\n            if (item['weee_tax_applied']) {\n                return JSON.parse(item['weee_tax_applied']);\n            }\n\n            return [];\n        }\n    });\n});\n","Magento_Weee/js/view/checkout/summary/item/price/row_incl_tax.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\n\ndefine([\n    'Magento_Weee/js/view/checkout/summary/item/price/weee'\n], function (weee) {\n    'use strict';\n\n    return weee.extend({\n        defaults: {\n            template: 'Magento_Weee/checkout/summary/item/price/row_incl_tax',\n            displayArea: 'row_incl_tax'\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getFinalRowDisplayPriceInclTax: function (item) {\n            var rowTotalInclTax = parseFloat(item['row_total_incl_tax']);\n\n            if (!window.checkoutConfig.getIncludeWeeeFlag) {\n                rowTotalInclTax += this.getRowWeeeTaxInclTax(item);\n            }\n\n            return rowTotalInclTax;\n        },\n\n        /**\n         * @param {Object} item\n         * @return {Number}\n         */\n        getRowDisplayPriceInclTax: function (item) {\n            var rowTotalInclTax = parseFloat(item['row_total_incl_tax']);\n\n            if (window.checkoutConfig.getIncludeWeeeFlag) {\n                rowTotalInclTax += this.getRowWeeeTaxInclTax(item);\n            }\n\n            return rowTotalInclTax;\n        },\n\n        /**\n         * @param {Object}item\n         * @return {Number}\n         */\n        getRowWeeeTaxInclTax: function (item) {\n            var totalWeeeTaxInclTaxApplied = 0,\n                weeeTaxAppliedAmounts;\n\n            if (item['weee_tax_applied']) {\n                weeeTaxAppliedAmounts = JSON.parse(item['weee_tax_applied']);\n                weeeTaxAppliedAmounts.forEach(function (weeeTaxAppliedAmount) {\n                    totalWeeeTaxInclTaxApplied += parseFloat(Math.max(weeeTaxAppliedAmount['row_amount_incl_tax'], 0));\n                });\n            }\n\n            return totalWeeeTaxInclTaxApplied;\n        }\n\n    });\n});\n","Magento_ReCaptchaPaypal/js/reCaptchaPaypal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(\n    [\n        'Magento_ReCaptchaFrontendUi/js/reCaptcha',\n        'jquery'\n    ],\n    function (Component, $) {\n        'use strict';\n\n        return Component.extend({\n\n            /**\n             * Recaptcha callback\n             * @param {String} token\n             */\n            reCaptchaCallback: function (token) {\n                this.tokenField.value = token;\n                this.$parentForm.trigger('captcha:endExecute');\n            },\n\n            /**\n             * Initialize parent form.\n             *\n             * @param {Object} parentForm\n             * @param {String} widgetId\n             */\n            initParentForm: function (parentForm, widgetId) {\n                var me = this;\n\n                parentForm.on('captcha:startExecute', function (event) {\n                    if (!me.tokenField.value && me.getIsInvisibleRecaptcha()) {\n                        // eslint-disable-next-line no-undef\n                        grecaptcha.execute(widgetId);\n                        event.preventDefault(event);\n                        event.stopImmediatePropagation();\n                    } else {\n                        me.$parentForm.trigger('captcha:endExecute');\n                    }\n                });\n\n                // Create a virtual token field\n                this.tokenField = $('<input type=\"text\" name=\"token\" style=\"display: none\" />')[0];\n                this.$parentForm = parentForm;\n                parentForm.append(this.tokenField);\n            }\n        });\n    }\n);\n","Magento_ReCaptchaPaypal/js/payflowpro-method-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'Magento_Checkout/js/model/payment/additional-validators'\n], function ($, additionalValidators) {\n    'use strict';\n\n    return function (originalComponent) {\n        return originalComponent.extend({\n            /**\n             * Initializes reCaptcha\n             */\n            placeOrder: function () {\n                var original = this._super.bind(this),\n                    // jscs:disable requireCamelCaseOrUpperCaseIdentifiers\n                    isEnabledForPaypal = window.checkoutConfig.recaptcha_paypal,\n                    // jscs:enable requireCamelCaseOrUpperCaseIdentifiers\n                    paymentFormSelector = $('#co-payment-form'),\n                    startEvent = 'captcha:startExecute',\n                    endEvent = 'captcha:endExecute';\n\n                if (!this.validateHandler() || !additionalValidators.validate() || !isEnabledForPaypal) {\n                    return original();\n                }\n\n                paymentFormSelector.off(endEvent).on(endEvent, function () {\n                    original();\n                    paymentFormSelector.off(endEvent);\n                });\n\n                paymentFormSelector.trigger(startEvent);\n            }\n        });\n    };\n});\n","Magento_SendFriend/requirejs-config.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\nvar config = {\n    map: {\n        '*': {\n            'Magento_SendFriend/back-event': 'Magento_SendFriend/js/back-event'\n        }\n    }\n};\n","Magento_SendFriend/js/back-event.js":"/**\n* Copyright \u00a9 Magento, Inc. All rights reserved.\n* See COPYING.txt for license details.\n*/\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    return function (config, element) {\n        $(element).on('click', function () {\n            history.back();\n\n            return false;\n        });\n    };\n});\n","Magento_CheckoutAgreements/js/view/agreement-validation.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Checkout/js/model/payment/additional-validators',\n    'Magento_CheckoutAgreements/js/model/agreement-validator'\n], function (Component, additionalValidators, agreementValidator) {\n    'use strict';\n\n    additionalValidators.registerValidator(agreementValidator);\n\n    return Component.extend({});\n});\n","Magento_CheckoutAgreements/js/view/checkout-agreements.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'jquery',\n    'uiComponent',\n    'Magento_CheckoutAgreements/js/model/agreements-modal'\n], function (ko, $, Component, agreementsModal) {\n    'use strict';\n\n    var checkoutConfig = window.checkoutConfig,\n        agreementManualMode = 1,\n        agreementsConfig = checkoutConfig ? checkoutConfig.checkoutAgreements : {};\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_CheckoutAgreements/checkout/checkout-agreements'\n        },\n        isVisible: agreementsConfig.isEnabled,\n        agreements: agreementsConfig.agreements,\n        modalTitle: ko.observable(null),\n        modalContent: ko.observable(null),\n        contentHeight: ko.observable(null),\n        modalWindow: null,\n\n        /**\n         * Checks if agreement required\n         *\n         * @param {Object} element\n         */\n        isAgreementRequired: function (element) {\n            return element.mode == agreementManualMode; //eslint-disable-line eqeqeq\n        },\n\n        /**\n         * Show agreement content in modal\n         *\n         * @param {Object} element\n         */\n        showContent: function (element) {\n            this.modalTitle(element.checkboxText);\n            this.modalContent(element.content);\n            this.contentHeight(element.contentHeight ? element.contentHeight : 'auto');\n            agreementsModal.showModal();\n        },\n\n        /**\n         * build a unique id for the term checkbox\n         *\n         * @param {Object} context - the ko context\n         * @param {Number} agreementId\n         */\n        getCheckboxId: function (context, agreementId) {\n            var paymentMethodName = '',\n                paymentMethodRenderer = context.$parents[1];\n\n            // corresponding payment method fetched from parent context\n            if (paymentMethodRenderer) {\n                // item looks like this: {title: \"Check / Money order\", method: \"checkmo\"}\n                paymentMethodName = paymentMethodRenderer.item ?\n                  paymentMethodRenderer.item.method : '';\n            }\n\n            return 'agreement_' + paymentMethodName + '_' + agreementId;\n        },\n\n        /**\n         * Init modal window for rendered element\n         *\n         * @param {Object} element\n         */\n        initModal: function (element) {\n            agreementsModal.createModal(element);\n        }\n    });\n});\n","Magento_CheckoutAgreements/js/model/agreement-validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/validation'\n], function ($) {\n    'use strict';\n\n    var checkoutConfig = window.checkoutConfig,\n        agreementsConfig = checkoutConfig ? checkoutConfig.checkoutAgreements : {},\n        agreementsInputPath = '.payment-method._active div.checkout-agreements input';\n\n    return {\n        /**\n         * Validate checkout agreements\n         *\n         * @returns {Boolean}\n         */\n        validate: function (hideError) {\n            var isValid = true;\n\n            if (!agreementsConfig.isEnabled || $(agreementsInputPath).length === 0) {\n                return true;\n            }\n\n            $(agreementsInputPath).each(function (index, element) {\n                if (!$.validator.validateSingleElement(element, {\n                    errorElement: 'div',\n                    hideError: hideError || false\n                })) {\n                    isValid = false;\n                }\n            });\n\n            return isValid;\n        }\n    };\n});\n","Magento_CheckoutAgreements/js/model/agreements-modal.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/modal',\n    'mage/translate'\n], function ($, modal, $t) {\n    'use strict';\n\n    return {\n        modalWindow: null,\n\n        /**\n         * Create popUp window for provided element.\n         *\n         * @param {HTMLElement} element\n         */\n        createModal: function (element) {\n            var options;\n\n            this.modalWindow = element;\n            options = {\n                'type': 'popup',\n                'modalClass': 'agreements-modal',\n                'responsive': true,\n                'innerScroll': true,\n                'trigger': '.show-modal',\n                'buttons': [\n                    {\n                        text: $t('Close'),\n                        class: 'action secondary action-hide-popup',\n\n                        /** @inheritdoc */\n                        click: function () {\n                            this.closeModal();\n                        }\n                    }\n                ]\n            };\n            modal(options, $(this.modalWindow));\n        },\n\n        /** Show login popup window */\n        showModal: function () {\n            $(this.modalWindow).modal('openModal');\n        }\n    };\n});\n","Magento_CheckoutAgreements/js/model/set-payment-information-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/utils/wrapper',\n    'Magento_CheckoutAgreements/js/model/agreements-assigner'\n], function ($, wrapper, agreementsAssigner) {\n    'use strict';\n\n    return function (placeOrderAction) {\n\n        /** Override place-order-mixin for set-payment-information action as they differs only by method signature */\n        return wrapper.wrap(placeOrderAction, function (originalAction, messageContainer, paymentData) {\n            agreementsAssigner(paymentData);\n\n            return originalAction(messageContainer, paymentData);\n        });\n    };\n});\n","Magento_CheckoutAgreements/js/model/agreements-assigner.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    var agreementsConfig = window.checkoutConfig.checkoutAgreements;\n\n    /** Override default place order action and add agreement_ids to request */\n    return function (paymentData) {\n        var agreementForm,\n            agreementData,\n            agreementIds;\n\n        if (!agreementsConfig.isEnabled) {\n            return;\n        }\n\n        agreementForm = $('.payment-method._active div[data-role=checkout-agreements] input');\n        agreementData = agreementForm.serializeArray();\n        agreementIds = [];\n\n        agreementData.forEach(function (item) {\n            agreementIds.push(item.value);\n        });\n\n        if (paymentData['extension_attributes'] === undefined) {\n            paymentData['extension_attributes'] = {};\n        }\n\n        paymentData['extension_attributes']['agreement_ids'] = agreementIds;\n    };\n});\n","Magento_CheckoutAgreements/js/model/place-order-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/utils/wrapper',\n    'Magento_CheckoutAgreements/js/model/agreements-assigner'\n], function ($, wrapper, agreementsAssigner) {\n    'use strict';\n\n    return function (placeOrderAction) {\n\n        /** Override default place order action and add agreement_ids to request */\n        return wrapper.wrap(placeOrderAction, function (originalAction, paymentData, messageContainer) {\n            agreementsAssigner(paymentData);\n\n            return originalAction(paymentData, messageContainer);\n        });\n    };\n});\n","Torresani_Consent/js/view/shipping-mixin.js":"define([\n    'jquery',\n    'underscore',\n    'Magento_Ui/js/form/form',\n    'ko',\n    'Magento_Customer/js/model/customer',\n    'Magento_Customer/js/model/address-list',\n    'Magento_Checkout/js/model/address-converter',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/action/create-shipping-address',\n    'Magento_Checkout/js/action/select-shipping-address',\n    'Magento_Checkout/js/model/shipping-rates-validator',\n    'Magento_Checkout/js/model/shipping-address/form-popup-state',\n    'Magento_Checkout/js/model/shipping-service',\n    'Magento_Checkout/js/action/select-shipping-method',\n    'Magento_Checkout/js/model/shipping-rate-registry',\n    'Magento_Checkout/js/action/set-shipping-information',\n    'Magento_Checkout/js/model/step-navigator',\n    'Magento_Ui/js/modal/modal',\n    'Magento_Checkout/js/model/checkout-data-resolver',\n    'Magento_Checkout/js/checkout-data',\n    'uiRegistry',\n    'mage/translate',\n    'Magento_Checkout/js/model/shipping-rate-service'\n], function (\n    $,\n    _,\n    Component,\n    ko,\n    customer,\n    addressList,\n    addressConverter,\n    quote,\n    createShippingAddress,\n    selectShippingAddress,\n    shippingRatesValidator,\n    formPopUpState,\n    shippingService,\n    selectShippingMethodAction,\n    rateRegistry,\n    setShippingInformationAction,\n    stepNavigator,\n    modal,\n    checkoutDataResolver,\n    checkoutData,\n    registry,\n    $t\n) {\n    'use strict';\n\n    var mixin = {\n        defaults: {\n            template: 'Torresani_Consent/shipping'\n        }\n    };\n\n    function showPrivacyCheckout() {\n        jQuery('div[name=\"shippingAddress.privacy\"] label > span').html('Ho letto e compreso l\u2019<a href=\"/informativa-privacy\" target=\"_blank\">informativa privacy</a> in merito al trattamento dei miei dati personali.');\n        jQuery('div[name=\"shippingAddress.terms\"] label > span').html('Accetto i <a href=\"/condizioni-generali-di-vendita\" target=\"_blank\">termini e le condizioni generali di vendita</a>.');\n        jQuery('div[name=\"shippingAddress.consent1\"] label > span').html('Acconsento a ricevere newsletter e comunicazioni commerciali sui nostri prodotti, servizi, attivit\u00e0 (punto 2 delle finalit\u00e0 indicate in <a href=\"/informativa-privacy\" target=\"_blank\">informativa privacy</a>');\n        jQuery('div[name=\"shippingAddress.consent2\"] label > span').html('Acconsento al trattamento dei miei dati per la profilazione finalizzata a ricevere comunicazioni, proposte commerciali, suggerimenti di acquisto in linea con i miei interessi (punto 3 delle finalit\u00e0 indicate in <a href=\"/informativa-privacy\" target=\"_blank\">informativa privacy</a>).');\n        jQuery('div[name=\"shippingAddress.consent3\"] label > span').html('Acconsento al trattamento dei miei dati per partecipare alle ricerche di mercato eseguite e/o commissionate dal Titolare (punto 5 delle finalit\u00e0 indicate in <a href=\"/informativa-privacy\" target=\"_blank\">informativa privacy</a>).');\n    }\n\n    return function (target) {\n        jQuery(document).ready(function() {\n            setTimeout(() => { showPrivacyCheckout(); }, 1000);\n            setTimeout(() => { showPrivacyCheckout(); }, 3000);\n            setTimeout(() => { showPrivacyCheckout(); }, 5000);\n        });\n        jQuery('body').on(\"click\", \"#shipping-method-buttons-container button.continue\", function(e){\n            var valid = true;\n            jQuery('.custom-checkout-form-mandatory .checkbox').each(function() {\n                if (!this.checked) {\n                    this.parentNode.classList.add(\"_error\");\n                    valid = false;\n                }\n            });\n            if (!valid) {\n                e.stopPropagation();\n            }\n            return valid;\n        });\n        return target.extend(mixin);\n    };\n});\n","Torresani_Consent/js/view/custom-checkout-form.js":"/*global define*/\ndefine([\n    'Magento_Ui/js/form/form'\n], function(Component) {\n    'use strict';\n    return Component.extend({\n        initialize: function () {\n            this._super();\n            return this;\n        },\n\n        /**\n         * Form submit handler\n         *\n         * This method can have any name.\n         */\n        onSubmit: function() {\n            this.source.set('params.invalid', false);\n            this.source.trigger('customCheckoutForm.data.validate');\n\n            // verify that form data is valid\n            if (!this.source.get('params.invalid')) {\n                // data is retrieved from data provider by value of the customScope property\n                var formData = this.source.get('customCheckoutForm');\n                // do something with form data\n //               console.dir(formData);\n            }\n        }\n    });\n});\n","jquery/jquery.metadata.js":"/*\n * Metadata - jQuery plugin for parsing metadata from elements\n *\n * Copyright (c) 2006 John Resig, Yehuda Katz, J\u00ef\u00bf\u00bd\u00c3\u00b6rn Zaefferer, Paul McLanahan\n *\n * Dual licensed under the MIT and GPL licenses:\n *   http://www.opensource.org/licenses/mit-license.php\n *   http://www.gnu.org/licenses/gpl.html\n *\n * Revision: $Id: jquery.metadata.js 3640 2007-10-11 18:34:38Z pmclanahan $\n *\n */\n\n/**\n * Sets the type of metadata to use. Metadata is encoded in JSON, and each property\n * in the JSON will become a property of the element itself.\n *\n * There are four supported types of metadata storage:\n *\n *   attr:  Inside an attribute. The name parameter indicates *which* attribute.\n *\n *   class: Inside the class attribute, wrapped in curly braces: { }\n *\n *   elem:  Inside a child element (e.g. a script tag). The\n *          name parameter indicates *which* element.\n *   html5: Values are stored in data-* attributes.\n *\n * The metadata for an element is loaded the first time the element is accessed via jQuery.\n *\n * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements\n * matched by expr, then redefine the metadata type and run another $(expr) for other elements.\n *\n * @name $.metadata.setType\n *\n * @example <p id=\"one\" class=\"some_class {item_id: 1, item_label: 'Label'}\">This is a p</p>\n * @before $.metadata.setType(\"class\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from the class attribute\n *\n * @example <p id=\"one\" class=\"some_class\" data=\"{item_id: 1, item_label: 'Label'}\">This is a p</p>\n * @before $.metadata.setType(\"attr\", \"data\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a \"data\" attribute\n *\n * @example <p id=\"one\" class=\"some_class\"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>\n * @before $.metadata.setType(\"elem\", \"script\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a nested script element\n *\n * @example <p id=\"one\" class=\"some_class\" data-item_id=\"1\" data-item_label=\"Label\">This is a p</p>\n * @before $.metadata.setType(\"html5\")\n * @after $(\"#one\").metadata().item_id == 1; $(\"#one\").metadata().item_label == \"Label\"\n * @desc Reads metadata from a series of data-* attributes\n *\n * @param String type The encoding type\n * @param String name The name of the attribute to be used to get metadata (optional)\n * @cat Plugins/Metadata\n * @descr Sets the type of encoding to be used when loading metadata for the first time\n * @type undefined\n * @see metadata()\n */\n(function (factory) {\n    if (typeof define === 'function' && define.amd) {\n        define([\"jquery\"], factory);\n    } else {\n        factory(jQuery);\n    }\n}(function ($) {\n\n\n    $.extend({\n        metadata : {\n            defaults : {\n                type: 'class',\n                name: 'metadata',\n                cre: /({.*})/,\n                single: 'metadata',\n                meta:'validate'\n            },\n            setType: function( type, name ){\n                this.defaults.type = type;\n                this.defaults.name = name;\n            },\n            get: function( elem, opts ){\n                var settings = $.extend({},this.defaults,opts);\n                // check for empty string in single property\n                if (!settings.single.length) {\n                    settings.single = 'metadata';\n                }\n                if (!settings.meta.length) {\n                    settings.meta = 'validate';\n                }\n\n                var data = $.data(elem, settings.single);\n                // returned cached data if it already exists\n                if ( data ) return data;\n\n                data = \"{}\";\n\n                var getData = function(data) {\n                    if(typeof data != \"string\") return data;\n\n                    if( data.indexOf('{') < 0 ) {\n                        data = eval(\"(\" + data + \")\");\n                    }\n                }\n\n                var getObject = function(data) {\n                    if(typeof data != \"string\") return data;\n\n                    data = eval(\"(\" + data + \")\");\n                    return data;\n                }\n\n                if ( settings.type == \"html5\" ) {\n                    var object = {};\n                    $( elem.attributes ).each(function() {\n                        var name = this.nodeName;\n                        if (name.indexOf('data-' + settings.meta) === 0) {\n                            name = name.replace(/^data-/, '');\n                        }\n                        else {\n                            return true;\n                        }\n                        object[name] = getObject(this.value);\n                    });\n                } else {\n                    if ( settings.type == \"class\" ) {\n                        var m = settings.cre.exec( elem.className );\n                        if ( m )\n                            data = m[1];\n                    } else if ( settings.type == \"elem\" ) {\n                        if( !elem.getElementsByTagName ) return;\n                        var e = elem.getElementsByTagName(settings.name);\n                        if ( e.length )\n                            data = $.trim(e[0].innerHTML);\n                    } else if ( elem.getAttribute != undefined ) {\n                        var attr = elem.getAttribute( settings.name );\n                        if ( attr )\n                            data = attr;\n                    }\n                    object = getObject(data.indexOf(\"{\") < 0 ? \"{\" + data + \"}\" : data);\n                }\n\n                $.data( elem, settings.single, object );\n                return object;\n            }\n        }\n    });\n\n    /**\n     * Returns the metadata object for the first member of the jQuery object.\n     *\n     * @name metadata\n     * @descr Returns element's metadata object\n     * @param Object opts An object contianing settings to override the defaults\n     * @type jQuery\n     * @cat Plugins/Metadata\n     */\n    $.fn.metadata = function( opts ){\n        return $.metadata.get( this[0], opts );\n    };\n\n}));","jquery/jquery-ui-timepicker-addon.js":"/*! jQuery Timepicker Addon - v1.6.3 - 2016-04-20\n* http://trentrichardson.com/examples/timepicker\n* Copyright (c) 2016 Trent Richardson; Licensed MIT */\n(function (factory) {\n    if (typeof define === 'function' && define.amd) {\n        define(['jquery', 'jquery/ui'], factory);\n    } else {\n        factory(jQuery);\n    }\n}(function ($) {\n\n    /*\n    * Lets not redefine timepicker, Prevent \"Uncaught RangeError: Maximum call stack size exceeded\"\n    */\n    $.ui.timepicker = $.ui.timepicker || {};\n    if ($.ui.timepicker.version) {\n        return;\n    }\n\n    /*\n    * Extend jQueryUI, get it started with our version number\n    */\n    $.extend($.ui, {\n        timepicker: {\n            version: \"1.6.3\"\n        }\n    });\n\n    /*\n    * Timepicker manager.\n    * Use the singleton instance of this class, $.timepicker, to interact with the time picker.\n    * Settings for (groups of) time pickers are maintained in an instance object,\n    * allowing multiple different settings on the same page.\n    */\n    var Timepicker = function () {\n        this.regional = []; // Available regional settings, indexed by language code\n        this.regional[''] = { // Default regional settings\n            currentText: 'Now',\n            closeText: 'Done',\n            amNames: ['AM', 'A'],\n            pmNames: ['PM', 'P'],\n            timeFormat: 'HH:mm',\n            timeSuffix: '',\n            timeOnlyTitle: 'Choose Time',\n            timeText: 'Time',\n            hourText: 'Hour',\n            minuteText: 'Minute',\n            secondText: 'Second',\n            millisecText: 'Millisecond',\n            microsecText: 'Microsecond',\n            timezoneText: 'Time Zone',\n            isRTL: false\n        };\n        this._defaults = { // Global defaults for all the datetime picker instances\n            showButtonPanel: true,\n            timeOnly: false,\n            timeOnlyShowDate: false,\n            showHour: null,\n            showMinute: null,\n            showSecond: null,\n            showMillisec: null,\n            showMicrosec: null,\n            showTimezone: null,\n            showTime: true,\n            stepHour: 1,\n            stepMinute: 1,\n            stepSecond: 1,\n            stepMillisec: 1,\n            stepMicrosec: 1,\n            hour: 0,\n            minute: 0,\n            second: 0,\n            millisec: 0,\n            microsec: 0,\n            timezone: null,\n            hourMin: 0,\n            minuteMin: 0,\n            secondMin: 0,\n            millisecMin: 0,\n            microsecMin: 0,\n            hourMax: 23,\n            minuteMax: 59,\n            secondMax: 59,\n            millisecMax: 999,\n            microsecMax: 999,\n            minDateTime: null,\n            maxDateTime: null,\n            maxTime: null,\n            minTime: null,\n            onSelect: null,\n            hourGrid: 0,\n            minuteGrid: 0,\n            secondGrid: 0,\n            millisecGrid: 0,\n            microsecGrid: 0,\n            alwaysSetTime: true,\n            separator: ' ',\n            altFieldTimeOnly: true,\n            altTimeFormat: null,\n            altSeparator: null,\n            altTimeSuffix: null,\n            altRedirectFocus: true,\n            pickerTimeFormat: null,\n            pickerTimeSuffix: null,\n            showTimepicker: true,\n            timezoneList: null,\n            addSliderAccess: false,\n            sliderAccessArgs: null,\n            controlType: 'slider',\n            oneLine: false,\n            defaultValue: null,\n            parse: 'strict',\n            afterInject: null\n        };\n        $.extend(this._defaults, this.regional['']);\n    };\n\n    $.extend(Timepicker.prototype, {\n        $input: null,\n        $altInput: null,\n        $timeObj: null,\n        inst: null,\n        hour_slider: null,\n        minute_slider: null,\n        second_slider: null,\n        millisec_slider: null,\n        microsec_slider: null,\n        timezone_select: null,\n        maxTime: null,\n        minTime: null,\n        hour: 0,\n        minute: 0,\n        second: 0,\n        millisec: 0,\n        microsec: 0,\n        timezone: null,\n        hourMinOriginal: null,\n        minuteMinOriginal: null,\n        secondMinOriginal: null,\n        millisecMinOriginal: null,\n        microsecMinOriginal: null,\n        hourMaxOriginal: null,\n        minuteMaxOriginal: null,\n        secondMaxOriginal: null,\n        millisecMaxOriginal: null,\n        microsecMaxOriginal: null,\n        ampm: '',\n        formattedDate: '',\n        formattedTime: '',\n        formattedDateTime: '',\n        timezoneList: null,\n        units: ['hour', 'minute', 'second', 'millisec', 'microsec'],\n        support: {},\n        control: null,\n\n        /*\n        * Override the default settings for all instances of the time picker.\n        * @param  {Object} settings  object - the new settings to use as defaults (anonymous object)\n        * @return {Object} the manager object\n        */\n        setDefaults: function (settings) {\n            extendRemove(this._defaults, settings || {});\n            return this;\n        },\n\n        /*\n        * Create a new Timepicker instance\n        */\n        _newInst: function ($input, opts) {\n            var tp_inst = new Timepicker(),\n                inlineSettings = {},\n                fns = {},\n                overrides, i;\n\n            for (var attrName in this._defaults) {\n                if (this._defaults.hasOwnProperty(attrName)) {\n                    var attrValue = $input.attr('time:' + attrName);\n                    if (attrValue) {\n                        try {\n                            inlineSettings[attrName] = eval(attrValue);\n                        } catch (err) {\n                            inlineSettings[attrName] = attrValue;\n                        }\n                    }\n                }\n            }\n\n            overrides = {\n                beforeShow: function (input, dp_inst) {\n                    if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {\n                        return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);\n                    }\n                },\n                onChangeMonthYear: function (year, month, dp_inst) {\n                    // Update the time as well : this prevents the time from disappearing from the $input field.\n                    // tp_inst._updateDateTime(dp_inst);\n                    if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {\n                        tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);\n                    }\n                },\n                onClose: function (dateText, dp_inst) {\n                    if (tp_inst.timeDefined === true && $input.val() !== '') {\n                        tp_inst._updateDateTime(dp_inst);\n                    }\n                    if ($.isFunction(tp_inst._defaults.evnts.onClose)) {\n                        tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);\n                    }\n                }\n            };\n            for (i in overrides) {\n                if (overrides.hasOwnProperty(i)) {\n                    fns[i] = opts[i] || this._defaults[i] || null;\n                }\n            }\n\n            tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, {\n                evnts: fns,\n                timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');\n            });\n            tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) {\n                return val.toUpperCase();\n            });\n            tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) {\n                return val.toUpperCase();\n            });\n\n            // detect which units are supported\n            tp_inst.support = detectSupport(\n                tp_inst._defaults.timeFormat +\n                (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') +\n                (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : ''));\n\n            // controlType is string - key to our this._controls\n            if (typeof(tp_inst._defaults.controlType) === 'string') {\n                if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') {\n                    tp_inst._defaults.controlType = 'select';\n                }\n                tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType];\n            }\n            // controlType is an object and must implement create, options, value methods\n            else {\n                tp_inst.control = tp_inst._defaults.controlType;\n            }\n\n            // prep the timezone options\n            var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60,\n                0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840];\n            if (tp_inst._defaults.timezoneList !== null) {\n                timezoneList = tp_inst._defaults.timezoneList;\n            }\n            var tzl = timezoneList.length, tzi = 0, tzv = null;\n            if (tzl > 0 && typeof timezoneList[0] !== 'object') {\n                for (; tzi < tzl; tzi++) {\n                    tzv = timezoneList[tzi];\n                    timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) };\n                }\n            }\n            tp_inst._defaults.timezoneList = timezoneList;\n\n            // set the default units\n            tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) :\n                ((new Date()).getTimezoneOffset() * -1);\n            tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin :\n                tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour;\n            tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin :\n                tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute;\n            tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin :\n                tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second;\n            tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin :\n                tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec;\n            tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin :\n                tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec;\n            tp_inst.ampm = '';\n            tp_inst.$input = $input;\n\n            if (tp_inst._defaults.altField) {\n                tp_inst.$altInput = $(tp_inst._defaults.altField);\n                if (tp_inst._defaults.altRedirectFocus === true) {\n                    tp_inst.$altInput.css({\n                        cursor: 'pointer'\n                    }).focus(function () {\n                        $input.trigger(\"focus\");\n                    });\n                }\n            }\n\n            if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {\n                tp_inst._defaults.minDate = new Date();\n            }\n            if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {\n                tp_inst._defaults.maxDate = new Date();\n            }\n\n            // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..\n            if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {\n                tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());\n            }\n            if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {\n                tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());\n            }\n            if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {\n                tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());\n            }\n            if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {\n                tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());\n            }\n            tp_inst.$input.bind('focus', function () {\n                tp_inst._onFocus();\n            });\n\n            return tp_inst;\n        },\n\n        /*\n        * add our sliders to the calendar\n        */\n        _addTimePicker: function (dp_inst) {\n            var currDT = $.trim((this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val());\n\n            this.timeDefined = this._parseTime(currDT);\n            this._limitMinMaxDateTime(dp_inst, false);\n            this._injectTimePicker();\n            this._afterInject();\n        },\n\n        /*\n        * parse the time string from input value or _setTime\n        */\n        _parseTime: function (timeString, withDate) {\n            if (!this.inst) {\n                this.inst = $.datepicker._getInst(this.$input[0]);\n            }\n\n            if (withDate || !this._defaults.timeOnly) {\n                var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');\n                try {\n                    var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);\n                    if (!parseRes.timeObj) {\n                        return false;\n                    }\n                    $.extend(this, parseRes.timeObj);\n                } catch (err) {\n                    $.timepicker.log(\"Error parsing the date/time string: \" + err +\n                        \"\\ndate/time string = \" + timeString +\n                        \"\\ntimeFormat = \" + this._defaults.timeFormat +\n                        \"\\ndateFormat = \" + dp_dateFormat);\n                    return false;\n                }\n                return true;\n            } else {\n                var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);\n                if (!timeObj) {\n                    return false;\n                }\n                $.extend(this, timeObj);\n                return true;\n            }\n        },\n\n        /*\n        * Handle callback option after injecting timepicker\n        */\n        _afterInject: function() {\n            var o = this.inst.settings;\n            if ($.isFunction(o.afterInject)) {\n                o.afterInject.call(this);\n            }\n        },\n\n        /*\n        * generate and inject html for timepicker into ui datepicker\n        */\n        _injectTimePicker: function () {\n            var $dp = this.inst.dpDiv,\n                o = this.inst.settings,\n                tp_inst = this,\n                litem = '',\n                uitem = '',\n                show = null,\n                max = {},\n                gridSize = {},\n                size = null,\n                i = 0,\n                l = 0;\n\n            // Prevent displaying twice\n            if ($dp.find(\"div.ui-timepicker-div\").length === 0 && o.showTimepicker) {\n                var noDisplay = ' ui_tpicker_unit_hide',\n                    html = '<div class=\"ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + (o.oneLine && o.controlType === 'select' ? ' ui-timepicker-oneLine' : '') + '\"><dl>' + '<dt class=\"ui_tpicker_time_label' + ((o.showTime) ? '' : noDisplay) + '\">' + o.timeText + '</dt>' +\n                        '<dd class=\"ui_tpicker_time '+ ((o.showTime) ? '' : noDisplay) + '\"><input class=\"ui_tpicker_time_input\" ' + (o.timeInput ? '' : 'disabled') + '/></dd>';\n\n                // Create the markup\n                for (i = 0, l = this.units.length; i < l; i++) {\n                    litem = this.units[i];\n                    uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);\n                    show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];\n\n                    // Added by Peter Medeiros:\n                    // - Figure out what the hour/minute/second max should be based on the step values.\n                    // - Example: if stepMinute is 15, then minMax is 45.\n                    max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10);\n                    gridSize[litem] = 0;\n\n                    html += '<dt class=\"ui_tpicker_' + litem + '_label' + (show ? '' : noDisplay) + '\">' + o[litem + 'Text'] + '</dt>' +\n                        '<dd class=\"ui_tpicker_' + litem + (show ? '' : noDisplay) + '\"><div class=\"ui_tpicker_' + litem + '_slider' + (show ? '' : noDisplay) + '\"></div>';\n\n                    if (show && o[litem + 'Grid'] > 0) {\n                        html += '<div style=\"padding-left: 1px\"><table class=\"ui-tpicker-grid-label\"><tr>';\n\n                        if (litem === 'hour') {\n                            for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) {\n                                gridSize[litem]++;\n                                var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o);\n                                html += '<td data-for=\"' + litem + '\">' + tmph + '</td>';\n                            }\n                        }\n                        else {\n                            for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) {\n                                gridSize[litem]++;\n                                html += '<td data-for=\"' + litem + '\">' + ((m < 10) ? '0' : '') + m + '</td>';\n                            }\n                        }\n\n                        html += '</tr></table></div>';\n                    }\n                    html += '</dd>';\n                }\n\n                // Timezone\n                var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone;\n                html += '<dt class=\"ui_tpicker_timezone_label' + (showTz ? '' : noDisplay) + '\">' + o.timezoneText + '</dt>';\n                html += '<dd class=\"ui_tpicker_timezone' + (showTz ? '' : noDisplay) + '\"></dd>';\n\n                // Create the elements from string\n                html += '</dl></div>';\n                var $tp = $(html);\n\n                // if we only want time picker...\n                if (o.timeOnly === true) {\n                    $tp.prepend('<div class=\"ui-widget-header ui-helper-clearfix ui-corner-all\">' + '<div class=\"ui-datepicker-title\">' + o.timeOnlyTitle + '</div>' + '</div>');\n                    $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();\n                }\n\n                // add sliders, adjust grids, add events\n                for (i = 0, l = tp_inst.units.length; i < l; i++) {\n                    litem = tp_inst.units[i];\n                    uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);\n                    show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];\n\n                    // add the slider\n                    tp_inst[litem + '_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_' + litem + '_slider'), litem, tp_inst[litem], o[litem + 'Min'], max[litem], o['step' + uitem]);\n\n                    // adjust the grid and add click event\n                    if (show && o[litem + 'Grid'] > 0) {\n                        size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']);\n                        $tp.find('.ui_tpicker_' + litem + ' table').css({\n                            width: size + \"%\",\n                            marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + \"%\"),\n                            marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + \"%\") : '0',\n                            borderCollapse: 'collapse'\n                        }).find(\"td\").click(function (e) {\n                            var $t = $(this),\n                                h = $t.html(),\n                                n = parseInt(h.replace(/[^0-9]/g), 10),\n                                ap = h.replace(/[^apm]/ig),\n                                f = $t.data('for'); // loses scope, so we use data-for\n\n                            if (f === 'hour') {\n                                if (ap.indexOf('p') !== -1 && n < 12) {\n                                    n += 12;\n                                }\n                                else {\n                                    if (ap.indexOf('a') !== -1 && n === 12) {\n                                        n = 0;\n                                    }\n                                }\n                            }\n\n                            tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n);\n\n                            tp_inst._onTimeChange();\n                            tp_inst._onSelectHandler();\n                        }).css({\n                            cursor: 'pointer',\n                            width: (100 / gridSize[litem]) + '%',\n                            textAlign: 'center',\n                            overflow: 'hidden'\n                        });\n                    } // end if grid > 0\n                } // end for loop\n\n                // Add timezone options\n                this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find(\"select\");\n                $.fn.append.apply(this.timezone_select,\n                    $.map(o.timezoneList, function (val, idx) {\n                        return $(\"<option />\").val(typeof val === \"object\" ? val.value : val).text(typeof val === \"object\" ? val.label : val);\n                    }));\n                if (typeof(this.timezone) !== \"undefined\" && this.timezone !== null && this.timezone !== \"\") {\n                    var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1;\n                    if (local_timezone === this.timezone) {\n                        selectLocalTimezone(tp_inst);\n                    } else {\n                        this.timezone_select.val(this.timezone);\n                    }\n                } else {\n                    if (typeof(this.hour) !== \"undefined\" && this.hour !== null && this.hour !== \"\") {\n                        this.timezone_select.val(o.timezone);\n                    } else {\n                        selectLocalTimezone(tp_inst);\n                    }\n                }\n                this.timezone_select.change(function () {\n                    tp_inst._onTimeChange();\n                    tp_inst._onSelectHandler();\n                    tp_inst._afterInject();\n                });\n                // End timezone options\n\n                // inject timepicker into datepicker\n                var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');\n                if ($buttonPanel.length) {\n                    $buttonPanel.before($tp);\n                } else {\n                    $dp.append($tp);\n                }\n\n                this.$timeObj = $tp.find('.ui_tpicker_time_input');\n                this.$timeObj.change(function () {\n                    var timeFormat = tp_inst.inst.settings.timeFormat;\n                    var parsedTime = $.datepicker.parseTime(timeFormat, this.value);\n                    var update = new Date();\n                    if (parsedTime) {\n                        update.setHours(parsedTime.hour);\n                        update.setMinutes(parsedTime.minute);\n                        update.setSeconds(parsedTime.second);\n                        $.datepicker._setTime(tp_inst.inst, update);\n                    } else {\n                        this.value = tp_inst.formattedTime;\n                        this.blur();\n                    }\n                });\n\n                if (this.inst !== null) {\n                    var timeDefined = this.timeDefined;\n                    this._onTimeChange();\n                    this.timeDefined = timeDefined;\n                }\n\n                // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/\n                if (this._defaults.addSliderAccess) {\n                    var sliderAccessArgs = this._defaults.sliderAccessArgs,\n                        rtl = this._defaults.isRTL;\n                    sliderAccessArgs.isRTL = rtl;\n\n                    setTimeout(function () { // fix for inline mode\n                        if ($tp.find('.ui-slider-access').length === 0) {\n                            $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);\n\n                            // fix any grids since sliders are shorter\n                            var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);\n                            if (sliderAccessWidth) {\n                                $tp.find('table:visible').each(function () {\n                                    var $g = $(this),\n                                        oldWidth = $g.outerWidth(),\n                                        oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''),\n                                        newWidth = oldWidth - sliderAccessWidth,\n                                        newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',\n                                        css = { width: newWidth, marginRight: 0, marginLeft: 0 };\n                                    css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft;\n                                    $g.css(css);\n                                });\n                            }\n                        }\n                    }, 10);\n                }\n                // end slideAccess integration\n\n                tp_inst._limitMinMaxDateTime(this.inst, true);\n            }\n        },\n\n        /*\n        * This function tries to limit the ability to go outside the\n        * min/max date range\n        */\n        _limitMinMaxDateTime: function (dp_inst, adjustSliders) {\n            var o = this._defaults,\n                dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);\n\n            if (!this._defaults.showTimepicker) {\n                return;\n            } // No time so nothing to check here\n\n            if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {\n                var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),\n                    minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);\n\n                if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) {\n                    this.hourMinOriginal = o.hourMin;\n                    this.minuteMinOriginal = o.minuteMin;\n                    this.secondMinOriginal = o.secondMin;\n                    this.millisecMinOriginal = o.millisecMin;\n                    this.microsecMinOriginal = o.microsecMin;\n                }\n\n                if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) {\n                    this._defaults.hourMin = minDateTime.getHours();\n                    if (this.hour <= this._defaults.hourMin) {\n                        this.hour = this._defaults.hourMin;\n                        this._defaults.minuteMin = minDateTime.getMinutes();\n                        if (this.minute <= this._defaults.minuteMin) {\n                            this.minute = this._defaults.minuteMin;\n                            this._defaults.secondMin = minDateTime.getSeconds();\n                            if (this.second <= this._defaults.secondMin) {\n                                this.second = this._defaults.secondMin;\n                                this._defaults.millisecMin = minDateTime.getMilliseconds();\n                                if (this.millisec <= this._defaults.millisecMin) {\n                                    this.millisec = this._defaults.millisecMin;\n                                    this._defaults.microsecMin = minDateTime.getMicroseconds();\n                                } else {\n                                    if (this.microsec < this._defaults.microsecMin) {\n                                        this.microsec = this._defaults.microsecMin;\n                                    }\n                                    this._defaults.microsecMin = this.microsecMinOriginal;\n                                }\n                            } else {\n                                this._defaults.millisecMin = this.millisecMinOriginal;\n                                this._defaults.microsecMin = this.microsecMinOriginal;\n                            }\n                        } else {\n                            this._defaults.secondMin = this.secondMinOriginal;\n                            this._defaults.millisecMin = this.millisecMinOriginal;\n                            this._defaults.microsecMin = this.microsecMinOriginal;\n                        }\n                    } else {\n                        this._defaults.minuteMin = this.minuteMinOriginal;\n                        this._defaults.secondMin = this.secondMinOriginal;\n                        this._defaults.millisecMin = this.millisecMinOriginal;\n                        this._defaults.microsecMin = this.microsecMinOriginal;\n                    }\n                } else {\n                    this._defaults.hourMin = this.hourMinOriginal;\n                    this._defaults.minuteMin = this.minuteMinOriginal;\n                    this._defaults.secondMin = this.secondMinOriginal;\n                    this._defaults.millisecMin = this.millisecMinOriginal;\n                    this._defaults.microsecMin = this.microsecMinOriginal;\n                }\n            }\n\n            if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {\n                var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),\n                    maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);\n\n                if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) {\n                    this.hourMaxOriginal = o.hourMax;\n                    this.minuteMaxOriginal = o.minuteMax;\n                    this.secondMaxOriginal = o.secondMax;\n                    this.millisecMaxOriginal = o.millisecMax;\n                    this.microsecMaxOriginal = o.microsecMax;\n                }\n\n                if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) {\n                    this._defaults.hourMax = maxDateTime.getHours();\n                    if (this.hour >= this._defaults.hourMax) {\n                        this.hour = this._defaults.hourMax;\n                        this._defaults.minuteMax = maxDateTime.getMinutes();\n                        if (this.minute >= this._defaults.minuteMax) {\n                            this.minute = this._defaults.minuteMax;\n                            this._defaults.secondMax = maxDateTime.getSeconds();\n                            if (this.second >= this._defaults.secondMax) {\n                                this.second = this._defaults.secondMax;\n                                this._defaults.millisecMax = maxDateTime.getMilliseconds();\n                                if (this.millisec >= this._defaults.millisecMax) {\n                                    this.millisec = this._defaults.millisecMax;\n                                    this._defaults.microsecMax = maxDateTime.getMicroseconds();\n                                } else {\n                                    if (this.microsec > this._defaults.microsecMax) {\n                                        this.microsec = this._defaults.microsecMax;\n                                    }\n                                    this._defaults.microsecMax = this.microsecMaxOriginal;\n                                }\n                            } else {\n                                this._defaults.millisecMax = this.millisecMaxOriginal;\n                                this._defaults.microsecMax = this.microsecMaxOriginal;\n                            }\n                        } else {\n                            this._defaults.secondMax = this.secondMaxOriginal;\n                            this._defaults.millisecMax = this.millisecMaxOriginal;\n                            this._defaults.microsecMax = this.microsecMaxOriginal;\n                        }\n                    } else {\n                        this._defaults.minuteMax = this.minuteMaxOriginal;\n                        this._defaults.secondMax = this.secondMaxOriginal;\n                        this._defaults.millisecMax = this.millisecMaxOriginal;\n                        this._defaults.microsecMax = this.microsecMaxOriginal;\n                    }\n                } else {\n                    this._defaults.hourMax = this.hourMaxOriginal;\n                    this._defaults.minuteMax = this.minuteMaxOriginal;\n                    this._defaults.secondMax = this.secondMaxOriginal;\n                    this._defaults.millisecMax = this.millisecMaxOriginal;\n                    this._defaults.microsecMax = this.microsecMaxOriginal;\n                }\n            }\n\n            if (dp_inst.settings.minTime!==null) {\n                var tempMinTime=new Date(\"01/01/1970 \" + dp_inst.settings.minTime);\n                if (this.hour<tempMinTime.getHours()) {\n                    this.hour=this._defaults.hourMin=tempMinTime.getHours();\n                    this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();\n                } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) {\n                    this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();\n                } else {\n                    if (this._defaults.hourMin<tempMinTime.getHours()) {\n                        this._defaults.hourMin=tempMinTime.getHours();\n                        this._defaults.minuteMin=tempMinTime.getMinutes();\n                    } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) {\n                        this._defaults.minuteMin=tempMinTime.getMinutes();\n                    } else {\n                        this._defaults.minuteMin=0;\n                    }\n                }\n            }\n\n            if (dp_inst.settings.maxTime!==null) {\n                var tempMaxTime=new Date(\"01/01/1970 \" + dp_inst.settings.maxTime);\n                if (this.hour>tempMaxTime.getHours()) {\n                    this.hour=this._defaults.hourMax=tempMaxTime.getHours();\n                    this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();\n                } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) {\n                    this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();\n                } else {\n                    if (this._defaults.hourMax>tempMaxTime.getHours()) {\n                        this._defaults.hourMax=tempMaxTime.getHours();\n                        this._defaults.minuteMax=tempMaxTime.getMinutes();\n                    } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) {\n                        this._defaults.minuteMax=tempMaxTime.getMinutes();\n                    } else {\n                        this._defaults.minuteMax=59;\n                    }\n                }\n            }\n\n            if (adjustSliders !== undefined && adjustSliders === true) {\n                var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),\n                    minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),\n                    secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),\n                    millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10),\n                    microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10);\n\n                if (this.hour_slider) {\n                    this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour });\n                    this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour));\n                }\n                if (this.minute_slider) {\n                    this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute });\n                    this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute));\n                }\n                if (this.second_slider) {\n                    this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond });\n                    this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond));\n                }\n                if (this.millisec_slider) {\n                    this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec });\n                    this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec));\n                }\n                if (this.microsec_slider) {\n                    this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec });\n                    this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec));\n                }\n            }\n\n        },\n\n        /*\n        * when a slider moves, set the internal time...\n        * on time change is also called when the time is updated in the text field\n        */\n        _onTimeChange: function () {\n            if (!this._defaults.showTimepicker) {\n                return;\n            }\n            var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,\n                minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,\n                second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,\n                millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,\n                microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false,\n                timezone = (this.timezone_select) ? this.timezone_select.val() : false,\n                o = this._defaults,\n                pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,\n                pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;\n\n            if (typeof(hour) === 'object') {\n                hour = false;\n            }\n            if (typeof(minute) === 'object') {\n                minute = false;\n            }\n            if (typeof(second) === 'object') {\n                second = false;\n            }\n            if (typeof(millisec) === 'object') {\n                millisec = false;\n            }\n            if (typeof(microsec) === 'object') {\n                microsec = false;\n            }\n            if (typeof(timezone) === 'object') {\n                timezone = false;\n            }\n\n            if (hour !== false) {\n                hour = parseInt(hour, 10);\n            }\n            if (minute !== false) {\n                minute = parseInt(minute, 10);\n            }\n            if (second !== false) {\n                second = parseInt(second, 10);\n            }\n            if (millisec !== false) {\n                millisec = parseInt(millisec, 10);\n            }\n            if (microsec !== false) {\n                microsec = parseInt(microsec, 10);\n            }\n            if (timezone !== false) {\n                timezone = timezone.toString();\n            }\n\n            var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];\n\n            // If the update was done in the input field, the input field should not be updated.\n            // If the update was done using the sliders, update the input field.\n            var hasChanged = (\n                hour !== parseInt(this.hour,10) || // sliders should all be numeric\n                minute !== parseInt(this.minute,10) ||\n                second !== parseInt(this.second,10) ||\n                millisec !== parseInt(this.millisec,10) ||\n                microsec !== parseInt(this.microsec,10) ||\n                (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) ||\n                (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or \"EST\" format, so use toString()\n            );\n\n            if (hasChanged) {\n\n                if (hour !== false) {\n                    this.hour = hour;\n                }\n                if (minute !== false) {\n                    this.minute = minute;\n                }\n                if (second !== false) {\n                    this.second = second;\n                }\n                if (millisec !== false) {\n                    this.millisec = millisec;\n                }\n                if (microsec !== false) {\n                    this.microsec = microsec;\n                }\n                if (timezone !== false) {\n                    this.timezone = timezone;\n                }\n\n                if (!this.inst) {\n                    this.inst = $.datepicker._getInst(this.$input[0]);\n                }\n\n                this._limitMinMaxDateTime(this.inst, true);\n            }\n            if (this.support.ampm) {\n                this.ampm = ampm;\n            }\n\n            // Updates the time within the timepicker\n            this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);\n            if (this.$timeObj) {\n                if (pickerTimeFormat === o.timeFormat) {\n                    this.$timeObj.val(this.formattedTime + pickerTimeSuffix);\n                }\n                else {\n                    this.$timeObj.val($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);\n                }\n                if (this.$timeObj[0].setSelectionRange) {\n                    var sPos = this.$timeObj[0].selectionStart;\n                    var ePos = this.$timeObj[0].selectionEnd;\n                    this.$timeObj[0].setSelectionRange(sPos, ePos);\n                }\n            }\n\n            this.timeDefined = true;\n            if (hasChanged) {\n                this._updateDateTime();\n                //this.$input.focus(); // may automatically open the picker on setDate\n            }\n        },\n\n        /*\n        * call custom onSelect.\n        * bind to sliders slidestop, and grid click.\n        */\n        _onSelectHandler: function () {\n            var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;\n            var inputEl = this.$input ? this.$input[0] : null;\n            if (onSelect && inputEl) {\n                onSelect.apply(inputEl, [this.formattedDateTime, this]);\n            }\n        },\n\n        /*\n        * update our input with the new date time..\n        */\n        _updateDateTime: function (dp_inst) {\n            dp_inst = this.inst || dp_inst;\n            var dtTmp = (dp_inst.currentYear > 0?\n                new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) :\n                new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),\n                dt = $.datepicker._daylightSavingAdjust(dtTmp),\n                //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),\n                //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)),\n                dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),\n                formatCfg = $.datepicker._getFormatConfig(dp_inst),\n                timeAvailable = dt !== null && this.timeDefined;\n            this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);\n            var formattedDateTime = this.formattedDate;\n\n            // if a slider was changed but datepicker doesn't have a value yet, set it\n            if (dp_inst.lastVal === \"\") {\n                dp_inst.currentYear = dp_inst.selectedYear;\n                dp_inst.currentMonth = dp_inst.selectedMonth;\n                dp_inst.currentDay = dp_inst.selectedDay;\n            }\n\n            /*\n            * remove following lines to force every changes in date picker to change the input value\n            * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker.\n            * If the user manually empty the value in the input field, the date picker will never change selected value.\n            */\n            //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {\n            //\treturn;\n            //}\n\n            if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) {\n                formattedDateTime = this.formattedTime;\n            } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) {\n                formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;\n            }\n\n            this.formattedDateTime = formattedDateTime;\n\n            if (!this._defaults.showTimepicker) {\n                this.$input.val(this.formattedDate);\n            } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) {\n                this.$altInput.val(this.formattedTime);\n                this.$input.val(this.formattedDate);\n            } else if (this.$altInput) {\n                this.$input.val(formattedDateTime);\n                var altFormattedDateTime = '',\n                    altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator,\n                    altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;\n\n                if (!this._defaults.timeOnly) {\n                    if (this._defaults.altFormat) {\n                        altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);\n                    }\n                    else {\n                        altFormattedDateTime = this.formattedDate;\n                    }\n\n                    if (altFormattedDateTime) {\n                        altFormattedDateTime += altSeparator;\n                    }\n                }\n\n                if (this._defaults.altTimeFormat !== null) {\n                    altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;\n                }\n                else {\n                    altFormattedDateTime += this.formattedTime + altTimeSuffix;\n                }\n                this.$altInput.val(altFormattedDateTime);\n            } else {\n                this.$input.val(formattedDateTime);\n            }\n\n            this.$input.trigger(\"change\");\n        },\n\n        _onFocus: function () {\n            if (!this.$input.val() && this._defaults.defaultValue) {\n                this.$input.val(this._defaults.defaultValue);\n                var inst = $.datepicker._getInst(this.$input.get(0)),\n                    tp_inst = $.datepicker._get(inst, 'timepicker');\n                if (tp_inst) {\n                    if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {\n                        try {\n                            $.datepicker._updateDatepicker(inst);\n                        } catch (err) {\n                            $.timepicker.log(err);\n                        }\n                    }\n                }\n            }\n        },\n\n        /*\n        * Small abstraction to control types\n        * We can add more, just be sure to follow the pattern: create, options, value\n        */\n        _controls: {\n            // slider methods\n            slider: {\n                create: function (tp_inst, obj, unit, val, min, max, step) {\n                    var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60\n                    return obj.prop('slide', null).slider({\n                        orientation: \"horizontal\",\n                        value: rtl ? val * -1 : val,\n                        min: rtl ? max * -1 : min,\n                        max: rtl ? min * -1 : max,\n                        step: step,\n                        slide: function (event, ui) {\n                            tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value);\n                            tp_inst._onTimeChange();\n                        },\n                        stop: function (event, ui) {\n                            tp_inst._onSelectHandler();\n                        }\n                    });\n                },\n                options: function (tp_inst, obj, unit, opts, val) {\n                    if (tp_inst._defaults.isRTL) {\n                        if (typeof(opts) === 'string') {\n                            if (opts === 'min' || opts === 'max') {\n                                if (val !== undefined) {\n                                    return obj.slider(opts, val * -1);\n                                }\n                                return Math.abs(obj.slider(opts));\n                            }\n                            return obj.slider(opts);\n                        }\n                        var min = opts.min,\n                            max = opts.max;\n                        opts.min = opts.max = null;\n                        if (min !== undefined) {\n                            opts.max = min * -1;\n                        }\n                        if (max !== undefined) {\n                            opts.min = max * -1;\n                        }\n                        return obj.slider(opts);\n                    }\n                    if (typeof(opts) === 'string' && val !== undefined) {\n                        return obj.slider(opts, val);\n                    }\n                    return obj.slider(opts);\n                },\n                value: function (tp_inst, obj, unit, val) {\n                    if (tp_inst._defaults.isRTL) {\n                        if (val !== undefined) {\n                            return obj.slider('value', val * -1);\n                        }\n                        return Math.abs(obj.slider('value'));\n                    }\n                    if (val !== undefined) {\n                        return obj.slider('value', val);\n                    }\n                    return obj.slider('value');\n                }\n            },\n            // select methods\n            select: {\n                create: function (tp_inst, obj, unit, val, min, max, step) {\n                    var sel = '<select class=\"ui-timepicker-select ui-state-default ui-corner-all\" data-unit=\"' + unit + '\" data-min=\"' + min + '\" data-max=\"' + max + '\" data-step=\"' + step + '\">',\n                        format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat;\n\n                    for (var i = min; i <= max; i += step) {\n                        sel += '<option value=\"' + i + '\"' + (i === val ? ' selected' : '') + '>';\n                        if (unit === 'hour') {\n                            sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults);\n                        }\n                        else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; }\n                        else {sel += '0' + i.toString(); }\n                        sel += '</option>';\n                    }\n                    sel += '</select>';\n\n                    obj.children('select').remove();\n\n                    $(sel).appendTo(obj).change(function (e) {\n                        tp_inst._onTimeChange();\n                        tp_inst._onSelectHandler();\n                        tp_inst._afterInject();\n                    });\n\n                    return obj;\n                },\n                options: function (tp_inst, obj, unit, opts, val) {\n                    var o = {},\n                        $t = obj.children('select');\n                    if (typeof(opts) === 'string') {\n                        if (val === undefined) {\n                            return $t.data(opts);\n                        }\n                        o[opts] = val;\n                    }\n                    else { o = opts; }\n                    return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min>=0 ? o.min : $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step'));\n                },\n                value: function (tp_inst, obj, unit, val) {\n                    var $t = obj.children('select');\n                    if (val !== undefined) {\n                        return $t.val(val);\n                    }\n                    return $t.val();\n                }\n            }\n        } // end _controls\n\n    });\n\n    $.fn.extend({\n        /*\n        * shorthand just to use timepicker.\n        */\n        timepicker: function (o) {\n            o = o || {};\n            var tmp_args = Array.prototype.slice.call(arguments);\n\n            if (typeof o === 'object') {\n                tmp_args[0] = $.extend(o, {\n                    timeOnly: true\n                });\n            }\n\n            return $(this).each(function () {\n                $.fn.datetimepicker.apply($(this), tmp_args);\n            });\n        },\n\n        /*\n        * extend timepicker to datepicker\n        */\n        datetimepicker: function (o) {\n            o = o || {};\n            var tmp_args = arguments;\n\n            if (typeof(o) === 'string') {\n                if (o === 'getDate'  || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) {\n                    return $.fn.datepicker.apply($(this[0]), tmp_args);\n                } else {\n                    return this.each(function () {\n                        var $t = $(this);\n                        $t.datepicker.apply($t, tmp_args);\n                    });\n                }\n            } else {\n                return this.each(function () {\n                    var $t = $(this);\n                    $t.datepicker($.timepicker._newInst($t, o)._defaults);\n                });\n            }\n        }\n    });\n\n    /*\n    * Public Utility to parse date and time\n    */\n    $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {\n        var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);\n        if (parseRes.timeObj) {\n            var t = parseRes.timeObj;\n            parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);\n            parseRes.date.setMicroseconds(t.microsec);\n        }\n\n        return parseRes.date;\n    };\n\n    /*\n    * Public utility to parse time\n    */\n    $.datepicker.parseTime = function (timeFormat, timeString, options) {\n        var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}),\n            iso8601 = (timeFormat.replace(/\\'.*?\\'/g, '').indexOf('Z') !== -1);\n\n        // Strict parse requires the timeString to match the timeFormat exactly\n        var strictParse = function (f, s, o) {\n\n            // pattern for standard and localized AM/PM markers\n            var getPatternAmpm = function (amNames, pmNames) {\n                var markers = [];\n                if (amNames) {\n                    $.merge(markers, amNames);\n                }\n                if (pmNames) {\n                    $.merge(markers, pmNames);\n                }\n                markers = $.map(markers, function (val) {\n                    return val.replace(/[.*+?|()\\[\\]{}\\\\]/g, '\\\\$&');\n                });\n                return '(' + markers.join('|') + ')?';\n            };\n\n            // figure out position of time elements.. cause js cant do named captures\n            var getFormatPositions = function (timeFormat) {\n                var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),\n                    orders = {\n                        h: -1,\n                        m: -1,\n                        s: -1,\n                        l: -1,\n                        c: -1,\n                        t: -1,\n                        z: -1\n                    };\n\n                if (finds) {\n                    for (var i = 0; i < finds.length; i++) {\n                        if (orders[finds[i].toString().charAt(0)] === -1) {\n                            orders[finds[i].toString().charAt(0)] = i + 1;\n                        }\n                    }\n                }\n                return orders;\n            };\n\n            var regstr = '^' + f.toString()\n                    .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {\n                        var ml = match.length;\n                        switch (match.charAt(0).toLowerCase()) {\n                            case 'h':\n                                return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n                            case 'm':\n                                return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n                            case 's':\n                                return ml === 1 ? '(\\\\d?\\\\d)' : '(\\\\d{' + ml + '})';\n                            case 'l':\n                                return '(\\\\d?\\\\d?\\\\d)';\n                            case 'c':\n                                return '(\\\\d?\\\\d?\\\\d)';\n                            case 'z':\n                                return '(z|[-+]\\\\d\\\\d:?\\\\d\\\\d|\\\\S+)?';\n                            case 't':\n                                return getPatternAmpm(o.amNames, o.pmNames);\n                            default:    // literal escaped in quotes\n                                return '(' + match.replace(/\\'/g, \"\").replace(/(\\.|\\$|\\^|\\\\|\\/|\\(|\\)|\\[|\\]|\\?|\\+|\\*)/g, function (m) { return \"\\\\\" + m; }) + ')?';\n                        }\n                    })\n                    .replace(/\\s/g, '\\\\s?') +\n                o.timeSuffix + '$',\n                order = getFormatPositions(f),\n                ampm = '',\n                treg;\n\n            treg = s.match(new RegExp(regstr, 'i'));\n\n            var resTime = {\n                hour: 0,\n                minute: 0,\n                second: 0,\n                millisec: 0,\n                microsec: 0\n            };\n\n            if (treg) {\n                if (order.t !== -1) {\n                    if (treg[order.t] === undefined || treg[order.t].length === 0) {\n                        ampm = '';\n                        resTime.ampm = '';\n                    } else {\n                        ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM';\n                        resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];\n                    }\n                }\n\n                if (order.h !== -1) {\n                    if (ampm === 'AM' && treg[order.h] === '12') {\n                        resTime.hour = 0; // 12am = 0 hour\n                    } else {\n                        if (ampm === 'PM' && treg[order.h] !== '12') {\n                            resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12\n                        } else {\n                            resTime.hour = Number(treg[order.h]);\n                        }\n                    }\n                }\n\n                if (order.m !== -1) {\n                    resTime.minute = Number(treg[order.m]);\n                }\n                if (order.s !== -1) {\n                    resTime.second = Number(treg[order.s]);\n                }\n                if (order.l !== -1) {\n                    resTime.millisec = Number(treg[order.l]);\n                }\n                if (order.c !== -1) {\n                    resTime.microsec = Number(treg[order.c]);\n                }\n                if (order.z !== -1 && treg[order.z] !== undefined) {\n                    resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);\n                }\n\n\n                return resTime;\n            }\n            return false;\n        };// end strictParse\n\n        // First try JS Date, if that fails, use strictParse\n        var looseParse = function (f, s, o) {\n            try {\n                var d = new Date('2012-01-01 ' + s);\n                if (isNaN(d.getTime())) {\n                    d = new Date('2012-01-01T' + s);\n                    if (isNaN(d.getTime())) {\n                        d = new Date('01/01/2012 ' + s);\n                        if (isNaN(d.getTime())) {\n                            throw \"Unable to parse time with native Date: \" + s;\n                        }\n                    }\n                }\n\n                return {\n                    hour: d.getHours(),\n                    minute: d.getMinutes(),\n                    second: d.getSeconds(),\n                    millisec: d.getMilliseconds(),\n                    microsec: d.getMicroseconds(),\n                    timezone: d.getTimezoneOffset() * -1\n                };\n            }\n            catch (err) {\n                try {\n                    return strictParse(f, s, o);\n                }\n                catch (err2) {\n                    $.timepicker.log(\"Unable to parse \\ntimeString: \" + s + \"\\ntimeFormat: \" + f);\n                }\n            }\n            return false;\n        }; // end looseParse\n\n        if (typeof o.parse === \"function\") {\n            return o.parse(timeFormat, timeString, o);\n        }\n        if (o.parse === 'loose') {\n            return looseParse(timeFormat, timeString, o);\n        }\n        return strictParse(timeFormat, timeString, o);\n    };\n\n    /**\n     * Public utility to format the time\n     * @param {string} format format of the time\n     * @param {Object} time Object not a Date for timezones\n     * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm\n     * @returns {string} the formatted time\n     */\n    $.datepicker.formatTime = function (format, time, options) {\n        options = options || {};\n        options = $.extend({}, $.timepicker._defaults, options);\n        time = $.extend({\n            hour: 0,\n            minute: 0,\n            second: 0,\n            millisec: 0,\n            microsec: 0,\n            timezone: null\n        }, time);\n\n        var tmptime = format,\n            ampmName = options.amNames[0],\n            hour = parseInt(time.hour, 10);\n\n        if (hour > 11) {\n            ampmName = options.pmNames[0];\n        }\n\n        tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {\n            switch (match) {\n                case 'HH':\n                    return ('0' + hour).slice(-2);\n                case 'H':\n                    return hour;\n                case 'hh':\n                    return ('0' + convert24to12(hour)).slice(-2);\n                case 'h':\n                    return convert24to12(hour);\n                case 'mm':\n                    return ('0' + time.minute).slice(-2);\n                case 'm':\n                    return time.minute;\n                case 'ss':\n                    return ('0' + time.second).slice(-2);\n                case 's':\n                    return time.second;\n                case 'l':\n                    return ('00' + time.millisec).slice(-3);\n                case 'c':\n                    return ('00' + time.microsec).slice(-3);\n                case 'z':\n                    return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false);\n                case 'Z':\n                    return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true);\n                case 'T':\n                    return ampmName.charAt(0).toUpperCase();\n                case 'TT':\n                    return ampmName.toUpperCase();\n                case 't':\n                    return ampmName.charAt(0).toLowerCase();\n                case 'tt':\n                    return ampmName.toLowerCase();\n                default:\n                    return match.replace(/'/g, \"\");\n            }\n        });\n\n        return tmptime;\n    };\n\n    /*\n    * the bad hack :/ override datepicker so it doesn't close on select\n    // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378\n    */\n    $.datepicker._base_selectDate = $.datepicker._selectDate;\n    $.datepicker._selectDate = function (id, dateStr) {\n        var inst = this._getInst($(id)[0]),\n            tp_inst = this._get(inst, 'timepicker'),\n            was_inline;\n\n        if (tp_inst && inst.settings.showTimepicker) {\n            tp_inst._limitMinMaxDateTime(inst, true);\n            was_inline = inst.inline;\n            inst.inline = inst.stay_open = true;\n            //This way the onSelect handler called from calendarpicker get the full dateTime\n            this._base_selectDate(id, dateStr);\n            inst.inline = was_inline;\n            inst.stay_open = false;\n            this._notifyChange(inst);\n            this._updateDatepicker(inst);\n        } else {\n            this._base_selectDate(id, dateStr);\n        }\n    };\n\n    /*\n    * second bad hack :/ override datepicker so it triggers an event when changing the input field\n    * and does not redraw the datepicker on every selectDate event\n    */\n    $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;\n    $.datepicker._updateDatepicker = function (inst) {\n\n        // don't popup the datepicker if there is another instance already opened\n        var input = inst.input[0];\n        if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) {\n            return;\n        }\n\n        if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {\n\n            this._base_updateDatepicker(inst);\n\n            // Reload the time control when changing something in the input text field.\n            var tp_inst = this._get(inst, 'timepicker');\n            if (tp_inst) {\n                tp_inst._addTimePicker(inst);\n            }\n        }\n    };\n\n    /*\n    * third bad hack :/ override datepicker so it allows spaces and colon in the input field\n    */\n    $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;\n    $.datepicker._doKeyPress = function (event) {\n        var inst = $.datepicker._getInst(event.target),\n            tp_inst = $.datepicker._get(inst, 'timepicker');\n\n        if (tp_inst) {\n            if ($.datepicker._get(inst, 'constrainInput')) {\n                var ampm = tp_inst.support.ampm,\n                    tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone,\n                    dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),\n                    datetimeChars = tp_inst._defaults.timeFormat.toString()\n                            .replace(/[hms]/g, '')\n                            .replace(/TT/g, ampm ? 'APM' : '')\n                            .replace(/Tt/g, ampm ? 'AaPpMm' : '')\n                            .replace(/tT/g, ampm ? 'AaPpMm' : '')\n                            .replace(/T/g, ampm ? 'AP' : '')\n                            .replace(/tt/g, ampm ? 'apm' : '')\n                            .replace(/t/g, ampm ? 'ap' : '') +\n                        \" \" + tp_inst._defaults.separator +\n                        tp_inst._defaults.timeSuffix +\n                        (tz ? tp_inst._defaults.timezoneList.join('') : '') +\n                        (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) +\n                        dateChars,\n                    chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);\n                return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);\n            }\n        }\n\n        return $.datepicker._base_doKeyPress(event);\n    };\n\n    /*\n    * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField\n    * Update any alternate field to synchronise with the main field.\n    */\n    $.datepicker._base_updateAlternate = $.datepicker._updateAlternate;\n    $.datepicker._updateAlternate = function (inst) {\n        var tp_inst = this._get(inst, 'timepicker');\n        if (tp_inst) {\n            var altField = tp_inst._defaults.altField;\n            if (altField) { // update alternate field too\n                var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,\n                    date = this._getDate(inst),\n                    formatCfg = $.datepicker._getFormatConfig(inst),\n                    altFormattedDateTime = '',\n                    altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator,\n                    altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,\n                    altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;\n\n                altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;\n                if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) {\n                    if (tp_inst._defaults.altFormat) {\n                        altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime;\n                    }\n                    else {\n                        altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;\n                    }\n                }\n                $(altField).val( inst.input.val() ? altFormattedDateTime : \"\");\n            }\n        }\n        else {\n            $.datepicker._base_updateAlternate(inst);\n        }\n    };\n\n    /*\n    * Override key up event to sync manual input changes.\n    */\n    $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;\n    $.datepicker._doKeyUp = function (event) {\n        var inst = $.datepicker._getInst(event.target),\n            tp_inst = $.datepicker._get(inst, 'timepicker');\n\n        if (tp_inst) {\n            if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {\n                try {\n                    $.datepicker._updateDatepicker(inst);\n                } catch (err) {\n                    $.timepicker.log(err);\n                }\n            }\n        }\n\n        return $.datepicker._base_doKeyUp(event);\n    };\n\n    /*\n    * override \"Today\" button to also grab the time and set it to input field.\n    */\n    $.datepicker._base_gotoToday = $.datepicker._gotoToday;\n    $.datepicker._gotoToday = function (id) {\n        var inst = this._getInst($(id)[0]);\n        this._base_gotoToday(id);\n        var tp_inst = this._get(inst, 'timepicker');\n        if (!tp_inst) {\n            return;\n        }\n\n        var tzoffset = $.timepicker.timezoneOffsetNumber(tp_inst.timezone);\n        var now = new Date();\n        now.setMinutes(now.getMinutes() + now.getTimezoneOffset() + parseInt(tzoffset, 10));\n        this._setTime(inst, now);\n        this._setDate(inst, now);\n        tp_inst._onSelectHandler();\n    };\n\n    /*\n    * Disable & enable the Time in the datetimepicker\n    */\n    $.datepicker._disableTimepickerDatepicker = function (target) {\n        var inst = this._getInst(target);\n        if (!inst) {\n            return;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n        $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\n        if (tp_inst) {\n            inst.settings.showTimepicker = false;\n            tp_inst._defaults.showTimepicker = false;\n            tp_inst._updateDateTime(inst);\n        }\n    };\n\n    $.datepicker._enableTimepickerDatepicker = function (target) {\n        var inst = this._getInst(target);\n        if (!inst) {\n            return;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n        $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\n        if (tp_inst) {\n            inst.settings.showTimepicker = true;\n            tp_inst._defaults.showTimepicker = true;\n            tp_inst._addTimePicker(inst); // Could be disabled on page load\n            tp_inst._updateDateTime(inst);\n        }\n    };\n\n    /*\n    * Create our own set time function\n    */\n    $.datepicker._setTime = function (inst, date) {\n        var tp_inst = this._get(inst, 'timepicker');\n        if (tp_inst) {\n            var defaults = tp_inst._defaults;\n\n            // calling _setTime with no date sets time to defaults\n            tp_inst.hour = date ? date.getHours() : defaults.hour;\n            tp_inst.minute = date ? date.getMinutes() : defaults.minute;\n            tp_inst.second = date ? date.getSeconds() : defaults.second;\n            tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;\n            tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec;\n\n            //check if within min/max times..\n            tp_inst._limitMinMaxDateTime(inst, true);\n\n            tp_inst._onTimeChange();\n            tp_inst._updateDateTime(inst);\n        }\n    };\n\n    /*\n    * Create new public method to set only time, callable as $().datepicker('setTime', date)\n    */\n    $.datepicker._setTimeDatepicker = function (target, date, withDate) {\n        var inst = this._getInst(target);\n        if (!inst) {\n            return;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n\n        if (tp_inst) {\n            this._setDateFromField(inst);\n            var tp_date;\n            if (date) {\n                if (typeof date === \"string\") {\n                    tp_inst._parseTime(date, withDate);\n                    tp_date = new Date();\n                    tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);\n                    tp_date.setMicroseconds(tp_inst.microsec);\n                } else {\n                    tp_date = new Date(date.getTime());\n                    tp_date.setMicroseconds(date.getMicroseconds());\n                }\n                if (tp_date.toString() === 'Invalid Date') {\n                    tp_date = undefined;\n                }\n                this._setTime(inst, tp_date);\n            }\n        }\n\n    };\n\n    /*\n    * override setDate() to allow setting time too within Date object\n    */\n    $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;\n    $.datepicker._setDateDatepicker = function (target, _date) {\n        var inst = this._getInst(target);\n        var date = _date;\n        if (!inst) {\n            return;\n        }\n\n        if (typeof(_date) === 'string') {\n            date = new Date(_date);\n            if (!date.getTime()) {\n                this._base_setDateDatepicker.apply(this, arguments);\n                date = $(target).datepicker('getDate');\n            }\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n        var tp_date;\n        if (date instanceof Date) {\n            tp_date = new Date(date.getTime());\n            tp_date.setMicroseconds(date.getMicroseconds());\n        } else {\n            tp_date = date;\n        }\n\n        // This is important if you are using the timezone option, javascript's Date\n        // object will only return the timezone offset for the current locale, so we\n        // adjust it accordingly.  If not using timezone option this won't matter..\n        // If a timezone is different in tp, keep the timezone as is\n        if (tp_inst && tp_date) {\n            // look out for DST if tz wasn't specified\n            if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {\n                tp_inst.timezone = tp_date.getTimezoneOffset() * -1;\n            }\n            date = $.timepicker.timezoneAdjust(date, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()), tp_inst.timezone);\n            tp_date = $.timepicker.timezoneAdjust(tp_date, $.timepicker.timezoneOffsetString(-tp_date.getTimezoneOffset()), tp_inst.timezone);\n        }\n\n        this._updateDatepicker(inst);\n        this._base_setDateDatepicker.apply(this, arguments);\n        this._setTimeDatepicker(target, tp_date, true);\n    };\n\n    /*\n    * override getDate() to allow getting time too within Date object\n    */\n    $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;\n    $.datepicker._getDateDatepicker = function (target, noDefault) {\n        var inst = this._getInst(target);\n        if (!inst) {\n            return;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n\n        if (tp_inst) {\n            // if it hasn't yet been defined, grab from field\n            if (inst.lastVal === undefined) {\n                this._setDateFromField(inst, noDefault);\n            }\n\n            var date = this._getDate(inst);\n\n            var currDT = null;\n\n            if (tp_inst.$altInput && tp_inst._defaults.altFieldTimeOnly) {\n                currDT = tp_inst.$input.val() + ' ' + tp_inst.$altInput.val();\n            }\n            else if (tp_inst.$input.get(0).tagName !== 'INPUT' && tp_inst.$altInput) {\n                /**\n                 * in case the datetimepicker has been applied to a non-input tag for inline UI,\n                 * and the user has not configured the plugin to display only time in altInput,\n                 * pick current date time from the altInput (and hope for the best, for now, until \"ER1\" is applied)\n                 *\n                 * @todo ER1. Since altInput can have a totally difference format, convert it to standard format by reading input format from \"altFormat\" and \"altTimeFormat\" option values\n                 */\n                currDT = tp_inst.$altInput.val();\n            }\n            else {\n                currDT = tp_inst.$input.val();\n            }\n\n            if (date && tp_inst._parseTime(currDT, !inst.settings.timeOnly)) {\n                date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);\n                date.setMicroseconds(tp_inst.microsec);\n\n                // This is important if you are using the timezone option, javascript's Date\n                // object will only return the timezone offset for the current locale, so we\n                // adjust it accordingly.  If not using timezone option this won't matter..\n                if (tp_inst.timezone != null) {\n                    // look out for DST if tz wasn't specified\n                    if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {\n                        tp_inst.timezone = date.getTimezoneOffset() * -1;\n                    }\n                    date = $.timepicker.timezoneAdjust(date, tp_inst.timezone, $.timepicker.timezoneOffsetString(-date.getTimezoneOffset()));\n                }\n            }\n            return date;\n        }\n        return this._base_getDateDatepicker(target, noDefault);\n    };\n\n    /*\n    * override parseDate() because UI 1.8.14 throws an error about \"Extra characters\"\n    * An option in datapicker to ignore extra format characters would be nicer.\n    */\n    $.datepicker._base_parseDate = $.datepicker.parseDate;\n    $.datepicker.parseDate = function (format, value, settings) {\n        var date;\n        try {\n            date = this._base_parseDate(format, value, settings);\n        } catch (err) {\n            // Hack!  The error message ends with a colon, a space, and\n            // the \"extra\" characters.  We rely on that instead of\n            // attempting to perfectly reproduce the parsing algorithm.\n            if (err.indexOf(\":\") >= 0) {\n                date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings);\n                $.timepicker.log(\"Error parsing the date string: \" + err + \"\\ndate string = \" + value + \"\\ndate format = \" + format);\n            } else {\n                throw err;\n            }\n        }\n        return date;\n    };\n\n    /*\n    * override formatDate to set date with time to the input\n    */\n    $.datepicker._base_formatDate = $.datepicker._formatDate;\n    $.datepicker._formatDate = function (inst, day, month, year) {\n        var tp_inst = this._get(inst, 'timepicker');\n        if (tp_inst) {\n            tp_inst._updateDateTime(inst);\n            return tp_inst.$input.val();\n        }\n        return this._base_formatDate(inst);\n    };\n\n    /*\n    * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate\n    */\n    $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;\n    $.datepicker._optionDatepicker = function (target, name, value) {\n        var inst = this._getInst(target),\n            name_clone;\n        if (!inst) {\n            return null;\n        }\n\n        var tp_inst = this._get(inst, 'timepicker');\n        if (tp_inst) {\n            var min = null,\n                max = null,\n                onselect = null,\n                overrides = tp_inst._defaults.evnts,\n                fns = {},\n                prop,\n                ret,\n                oldVal,\n                $target;\n            if (typeof name === 'string') { // if min/max was set with the string\n                if (name === 'minDate' || name === 'minDateTime') {\n                    min = value;\n                } else if (name === 'maxDate' || name === 'maxDateTime') {\n                    max = value;\n                } else if (name === 'onSelect') {\n                    onselect = value;\n                } else if (overrides.hasOwnProperty(name)) {\n                    if (typeof (value) === 'undefined') {\n                        return overrides[name];\n                    }\n                    fns[name] = value;\n                    name_clone = {}; //empty results in exiting function after overrides updated\n                }\n            } else if (typeof name === 'object') { //if min/max was set with the JSON\n                if (name.minDate) {\n                    min = name.minDate;\n                } else if (name.minDateTime) {\n                    min = name.minDateTime;\n                } else if (name.maxDate) {\n                    max = name.maxDate;\n                } else if (name.maxDateTime) {\n                    max = name.maxDateTime;\n                }\n                for (prop in overrides) {\n                    if (overrides.hasOwnProperty(prop) && name[prop]) {\n                        fns[prop] = name[prop];\n                    }\n                }\n            }\n            for (prop in fns) {\n                if (fns.hasOwnProperty(prop)) {\n                    overrides[prop] = fns[prop];\n                    if (!name_clone) { name_clone = $.extend({}, name); }\n                    delete name_clone[prop];\n                }\n            }\n            if (name_clone && isEmptyObject(name_clone)) { return; }\n            if (min) { //if min was set\n                if (min === 0) {\n                    min = new Date();\n                } else {\n                    min = new Date(min);\n                }\n                tp_inst._defaults.minDate = min;\n                tp_inst._defaults.minDateTime = min;\n            } else if (max) { //if max was set\n                if (max === 0) {\n                    max = new Date();\n                } else {\n                    max = new Date(max);\n                }\n                tp_inst._defaults.maxDate = max;\n                tp_inst._defaults.maxDateTime = max;\n            } else if (onselect) {\n                tp_inst._defaults.onSelect = onselect;\n            }\n\n            // Datepicker will override our date when we call _base_optionDatepicker when\n            // calling minDate/maxDate, so we will first grab the value, call\n            // _base_optionDatepicker, then set our value back.\n            if(min || max){\n                $target = $(target);\n                oldVal = $target.datetimepicker('getDate');\n                ret = this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);\n                $target.datetimepicker('setDate', oldVal);\n                return ret;\n            }\n        }\n        if (value === undefined) {\n            return this._base_optionDatepicker.call($.datepicker, target, name);\n        }\n        return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);\n    };\n\n    /*\n    * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,\n    * it will return false for all objects\n    */\n    var isEmptyObject = function (obj) {\n        var prop;\n        for (prop in obj) {\n            if (obj.hasOwnProperty(prop)) {\n                return false;\n            }\n        }\n        return true;\n    };\n\n    /*\n    * jQuery extend now ignores nulls!\n    */\n    var extendRemove = function (target, props) {\n        $.extend(target, props);\n        for (var name in props) {\n            if (props[name] === null || props[name] === undefined) {\n                target[name] = props[name];\n            }\n        }\n        return target;\n    };\n\n    /*\n    * Determine by the time format which units are supported\n    * Returns an object of booleans for each unit\n    */\n    var detectSupport = function (timeFormat) {\n        var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals\n            isIn = function (f, t) { // does the format contain the token?\n                return f.indexOf(t) !== -1 ? true : false;\n            };\n        return {\n            hour: isIn(tf, 'h'),\n            minute: isIn(tf, 'm'),\n            second: isIn(tf, 's'),\n            millisec: isIn(tf, 'l'),\n            microsec: isIn(tf, 'c'),\n            timezone: isIn(tf, 'z'),\n            ampm: isIn(tf, 't') && isIn(timeFormat, 'h'),\n            iso8601: isIn(timeFormat, 'Z')\n        };\n    };\n\n    /*\n    * Converts 24 hour format into 12 hour\n    * Returns 12 hour without leading 0\n    */\n    var convert24to12 = function (hour) {\n        hour %= 12;\n\n        if (hour === 0) {\n            hour = 12;\n        }\n\n        return String(hour);\n    };\n\n    var computeEffectiveSetting = function (settings, property) {\n        return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];\n    };\n\n    /*\n    * Splits datetime string into date and time substrings.\n    * Throws exception when date can't be parsed\n    * Returns {dateString: dateString, timeString: timeString}\n    */\n    var splitDateTime = function (dateTimeString, timeSettings) {\n        // The idea is to get the number separator occurrences in datetime and the time format requested (since time has\n        // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.\n        var separator = computeEffectiveSetting(timeSettings, 'separator'),\n            format = computeEffectiveSetting(timeSettings, 'timeFormat'),\n            timeParts = format.split(separator), // how many occurrences of separator may be in our format?\n            timePartsLen = timeParts.length,\n            allParts = dateTimeString.split(separator),\n            allPartsLen = allParts.length;\n\n        if (allPartsLen > 1) {\n            return {\n                dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator),\n                timeString: allParts.splice(0, timePartsLen).join(separator)\n            };\n        }\n\n        return {\n            dateString: dateTimeString,\n            timeString: ''\n        };\n    };\n\n    /*\n    * Internal function to parse datetime interval\n    * Returns: {date: Date, timeObj: Object}, where\n    *   date - parsed date without time (type Date)\n    *   timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional\n    */\n    var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {\n        var date,\n            parts,\n            parsedTime;\n\n        parts = splitDateTime(dateTimeString, timeSettings);\n        date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);\n\n        if (parts.timeString === '') {\n            return {\n                date: date\n            };\n        }\n\n        parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);\n\n        if (!parsedTime) {\n            throw 'Wrong time format';\n        }\n\n        return {\n            date: date,\n            timeObj: parsedTime\n        };\n    };\n\n    /*\n    * Internal function to set timezone_select to the local timezone\n    */\n    var selectLocalTimezone = function (tp_inst, date) {\n        if (tp_inst && tp_inst.timezone_select) {\n            var now = date || new Date();\n            tp_inst.timezone_select.val(-now.getTimezoneOffset());\n        }\n    };\n\n    /*\n    * Create a Singleton Instance\n    */\n    $.timepicker = new Timepicker();\n\n    /**\n     * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)\n     * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned\n     * @param {boolean} iso8601 if true formats in accordance to iso8601 \"+12:45\"\n     * @return {string}\n     */\n    $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) {\n        if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) {\n            return tzMinutes;\n        }\n\n        var off = tzMinutes,\n            minutes = off % 60,\n            hours = (off - minutes) / 60,\n            iso = iso8601 ? ':' : '',\n            tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);\n\n        if (tz === '+00:00') {\n            return 'Z';\n        }\n        return tz;\n    };\n\n    /**\n     * Get the number in minutes that represents a timezone string\n     * @param  {string} tzString formatted like \"+0500\", \"-1245\", \"Z\"\n     * @return {number} the offset minutes or the original string if it doesn't match expectations\n     */\n    $.timepicker.timezoneOffsetNumber = function (tzString) {\n        var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with \"+1245\"\n\n        if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset\n            return 0;\n        }\n\n        if (!/^(\\-|\\+)\\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back\n            return parseInt(tzString, 10);\n        }\n\n        return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus\n            ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes)\n                parseInt(normalized.substr(3, 2), 10))); // minutes\n    };\n\n    /**\n     * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate)\n     * @param  {Date} date\n     * @param  {string} fromTimezone formatted like \"+0500\", \"-1245\"\n     * @param  {string} toTimezone formatted like \"+0500\", \"-1245\"\n     * @return {Date}\n     */\n    $.timepicker.timezoneAdjust = function (date, fromTimezone, toTimezone) {\n        var fromTz = $.timepicker.timezoneOffsetNumber(fromTimezone);\n        var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);\n        if (!isNaN(toTz)) {\n            date.setMinutes(date.getMinutes() + (-fromTz) - (-toTz));\n        }\n        return date;\n    };\n\n    /**\n     * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to\n     * enforce date range limits.\n     * n.b. The input value must be correctly formatted (reformatting is not supported)\n     * @param  {Element} startTime\n     * @param  {Element} endTime\n     * @param  {Object} options Options for the timepicker() call\n     * @return {jQuery}\n     */\n    $.timepicker.timeRange = function (startTime, endTime, options) {\n        return $.timepicker.handleRange('timepicker', startTime, endTime, options);\n    };\n\n    /**\n     * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to\n     * enforce date range limits.\n     * @param  {Element} startTime\n     * @param  {Element} endTime\n     * @param  {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n     *   a boolean value that can be used to reformat the input values to the `dateFormat`.\n     * @param  {string} method Can be used to specify the type of picker to be added\n     * @return {jQuery}\n     */\n    $.timepicker.datetimeRange = function (startTime, endTime, options) {\n        $.timepicker.handleRange('datetimepicker', startTime, endTime, options);\n    };\n\n    /**\n     * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to\n     * enforce date range limits.\n     * @param  {Element} startTime\n     * @param  {Element} endTime\n     * @param  {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n     *   a boolean value that can be used to reformat the input values to the `dateFormat`.\n     * @return {jQuery}\n     */\n    $.timepicker.dateRange = function (startTime, endTime, options) {\n        $.timepicker.handleRange('datepicker', startTime, endTime, options);\n    };\n\n    /**\n     * Calls `method` on the `startTime` and `endTime` elements, and configures them to\n     * enforce date range limits.\n     * @param  {string} method Can be used to specify the type of picker to be added\n     * @param  {Element} startTime\n     * @param  {Element} endTime\n     * @param  {Object} options Options for the `timepicker()` call. Also supports `reformat`,\n     *   a boolean value that can be used to reformat the input values to the `dateFormat`.\n     * @return {jQuery}\n     */\n    $.timepicker.handleRange = function (method, startTime, endTime, options) {\n        options = $.extend({}, {\n            minInterval: 0, // min allowed interval in milliseconds\n            maxInterval: 0, // max allowed interval in milliseconds\n            start: {},      // options for start picker\n            end: {}         // options for end picker\n        }, options);\n\n        // for the mean time this fixes an issue with calling getDate with timepicker()\n        var timeOnly = false;\n        if(method === 'timepicker'){\n            timeOnly = true;\n            method = 'datetimepicker';\n        }\n\n        function checkDates(changed, other) {\n            var startdt = startTime[method]('getDate'),\n                enddt = endTime[method]('getDate'),\n                changeddt = changed[method]('getDate');\n\n            if (startdt !== null) {\n                var minDate = new Date(startdt.getTime()),\n                    maxDate = new Date(startdt.getTime());\n\n                minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval);\n                maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval);\n\n                if (options.minInterval > 0 && minDate > enddt) { // minInterval check\n                    endTime[method]('setDate', minDate);\n                }\n                else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check\n                    endTime[method]('setDate', maxDate);\n                }\n                else if (startdt > enddt) {\n                    other[method]('setDate', changeddt);\n                }\n            }\n        }\n\n        function selected(changed, other, option) {\n            if (!changed.val()) {\n                return;\n            }\n            var date = changed[method].call(changed, 'getDate');\n            if (date !== null && options.minInterval > 0) {\n                if (option === 'minDate') {\n                    date.setMilliseconds(date.getMilliseconds() + options.minInterval);\n                }\n                if (option === 'maxDate') {\n                    date.setMilliseconds(date.getMilliseconds() - options.minInterval);\n                }\n            }\n\n            if (date.getTime) {\n                other[method].call(other, 'option', option, date);\n            }\n        }\n\n        $.fn[method].call(startTime, $.extend({\n            timeOnly: timeOnly,\n            onClose: function (dateText, inst) {\n                checkDates($(this), endTime);\n            },\n            onSelect: function (selectedDateTime) {\n                selected($(this), endTime, 'minDate');\n            }\n        }, options, options.start));\n        $.fn[method].call(endTime, $.extend({\n            timeOnly: timeOnly,\n            onClose: function (dateText, inst) {\n                checkDates($(this), startTime);\n            },\n            onSelect: function (selectedDateTime) {\n                selected($(this), startTime, 'maxDate');\n            }\n        }, options, options.end));\n\n        checkDates(startTime, endTime);\n\n        selected(startTime, endTime, 'minDate');\n        selected(endTime, startTime, 'maxDate');\n\n        return $([startTime.get(0), endTime.get(0)]);\n    };\n\n    /**\n     * Log error or data to the console during error or debugging\n     * @param  {Object} err pass any type object to log to the console during error or debugging\n     * @return {void}\n     */\n    $.timepicker.log = function () {\n        // Older IE (9, maybe 10) throw error on accessing `window.console.log.apply`, so check first.\n        if (window.console && window.console.log && window.console.log.apply) {\n            window.console.log.apply(window.console, Array.prototype.slice.call(arguments));\n        }\n    };\n\n    /*\n     * Add util object to allow access to private methods for testability.\n     */\n    $.timepicker._util = {\n        _extendRemove: extendRemove,\n        _isEmptyObject: isEmptyObject,\n        _convert24to12: convert24to12,\n        _detectSupport: detectSupport,\n        _selectLocalTimezone: selectLocalTimezone,\n        _computeEffectiveSetting: computeEffectiveSetting,\n        _splitDateTime: splitDateTime,\n        _parseDateTimeInternal: parseDateTimeInternal\n    };\n\n    /*\n    * Microsecond support\n    */\n    if (!Date.prototype.getMicroseconds) {\n        Date.prototype.microseconds = 0;\n        Date.prototype.getMicroseconds = function () { return this.microseconds; };\n        Date.prototype.setMicroseconds = function (m) {\n            this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000));\n            this.microseconds = m % 1000;\n            return this;\n        };\n    }\n\n    /*\n    * Keep up with the version\n    */\n    $.timepicker.version = \"1.6.3\";\n\n}));\n","jquery/z-index.js":"/*!\n * zIndex plugin from jQuery UI Core - v1.10.4\n * http://jqueryui.com\n *\n * Copyright 2014 jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/category/ui-core/\n */\ndefine([\n    'jquery'\n], function ($, undefined) {\n\n// plugins\n    $.fn.extend({\n        zIndex: function (zIndex) {\n            if (zIndex !== undefined) {\n                return this.css(\"zIndex\", zIndex);\n            }\n\n            if (this.length) {\n                var elem = $(this[0]), position, value;\n                while (elem.length && elem[0] !== document) {\n                    // Ignore z-index if position is set to a value where z-index is ignored by the browser\n                    // This makes behavior of this function consistent across browsers\n                    // WebKit always returns auto if the element is positioned\n                    position = elem.css(\"position\");\n                    if (position === \"absolute\" || position === \"relative\" || position === \"fixed\") {\n                        // IE returns 0 when zIndex is not specified\n                        // other browsers return a string\n                        // we ignore the case of nested elements with an explicit value of 0\n                        // <div style=\"z-index: -10;\"><div style=\"z-index: 0;\"></div></div>\n                        value = parseInt(elem.css(\"zIndex\"), 10);\n                        if (!isNaN(value) && value !== 0) {\n                            return value;\n                        }\n                    }\n                    elem = elem.parent();\n                }\n            }\n\n            return 0;\n        }\n    });\n});\n","jquery/jquery.tabs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    \"jquery\",\n    \"jquery/bootstrap/tab\",\n    \"jquery/bootstrap/collapse\",\n], function () {\n\n});\n","jquery/jquery.cookie.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'js-cookie/cookie-wrapper'\n], function () {\n\n});\n"}
}});