Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/cartforge.co/pub/static/frontend/Smartwave/porto/en_US/js/bundle/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/cartforge.co/pub/static/frontend/Smartwave/porto/en_US/js/bundle/bundle8.js
require.config({"config": {
        "jsbuild":{"Mageplaza_Core/js/bootstrap.min.js":"/*!\n * Bootstrap v3.3.6 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under the MIT license\n */\nif(\"undefined\"==typeof jQuery)throw new Error(\"Bootstrap's JavaScript requires jQuery\");+function(a){\"use strict\";var b=a.fn.jquery.split(\" \")[0].split(\".\");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error(\"Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3\")}(jQuery),+function(a){\"use strict\";function b(){var a=document.createElement(\"bootstrap\"),b={WebkitTransition:\"webkitTransitionEnd\",MozTransition:\"transitionend\",OTransition:\"oTransitionEnd otransitionend\",transition:\"transitionend\"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(\"bsTransitionEnd\",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var c=a(this),e=c.data(\"bs.alert\");e||c.data(\"bs.alert\",e=new d(this)),\"string\"==typeof b&&e[b].call(c)})}var c='[data-dismiss=\"alert\"]',d=function(b){a(b).on(\"click\",c,this.close)};d.VERSION=\"3.3.6\",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger(\"closed.bs.alert\").remove()}var e=a(this),f=e.attr(\"data-target\");f||(f=e.attr(\"href\"),f=f&&f.replace(/.*(?=#[^\\s]*$)/,\"\"));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(\".alert\")),g.trigger(b=a.Event(\"close.bs.alert\")),b.isDefaultPrevented()||(g.removeClass(\"in\"),a.support.transition&&g.hasClass(\"fade\")?g.one(\"bsTransitionEnd\",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on(\"click.bs.alert.data-api\",c,d.prototype.close)}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.button\"),f=\"object\"==typeof b&&b;e||d.data(\"bs.button\",e=new c(this,f)),\"toggle\"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION=\"3.3.6\",c.DEFAULTS={loadingText:\"loading...\"},c.prototype.setState=function(b){var c=\"disabled\",d=this.$element,e=d.is(\"input\")?\"val\":\"html\",f=d.data();b+=\"Text\",null==f.resetText&&d.data(\"resetText\",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),\"loadingText\"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle=\"buttons\"]');if(b.length){var c=this.$element.find(\"input\");\"radio\"==c.prop(\"type\")?(c.prop(\"checked\")&&(a=!1),b.find(\".active\").removeClass(\"active\"),this.$element.addClass(\"active\")):\"checkbox\"==c.prop(\"type\")&&(c.prop(\"checked\")!==this.$element.hasClass(\"active\")&&(a=!1),this.$element.toggleClass(\"active\")),c.prop(\"checked\",this.$element.hasClass(\"active\")),a&&c.trigger(\"change\")}else this.$element.attr(\"aria-pressed\",!this.$element.hasClass(\"active\")),this.$element.toggleClass(\"active\")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on(\"click.bs.button.data-api\",'[data-toggle^=\"button\"]',function(c){var d=a(c.target);d.hasClass(\"btn\")||(d=d.closest(\".btn\")),b.call(d,\"toggle\"),a(c.target).is('input[type=\"radio\"]')||a(c.target).is('input[type=\"checkbox\"]')||c.preventDefault()}).on(\"focus.bs.button.data-api blur.bs.button.data-api\",'[data-toggle^=\"button\"]',function(b){a(b.target).closest(\".btn\").toggleClass(\"focus\",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.carousel\"),f=a.extend({},c.DEFAULTS,d.data(),\"object\"==typeof b&&b),g=\"string\"==typeof b?b:f.slide;e||d.data(\"bs.carousel\",e=new c(this,f)),\"number\"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(\".carousel-indicators\"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on(\"keydown.bs.carousel\",a.proxy(this.keydown,this)),\"hover\"==this.options.pause&&!(\"ontouchstart\"in document.documentElement)&&this.$element.on(\"mouseenter.bs.carousel\",a.proxy(this.pause,this)).on(\"mouseleave.bs.carousel\",a.proxy(this.cycle,this))};c.VERSION=\"3.3.6\",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:\"hover\",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(\".item\"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d=\"prev\"==a&&0===c||\"next\"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e=\"prev\"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(\".item.active\"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one(\"slid.bs.carousel\",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?\"next\":\"prev\",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(\".next, .prev\").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide(\"next\")},c.prototype.prev=function(){return this.sliding?void 0:this.slide(\"prev\")},c.prototype.slide=function(b,d){var e=this.$element.find(\".item.active\"),f=d||this.getItemForDirection(b,e),g=this.interval,h=\"next\"==b?\"left\":\"right\",i=this;if(f.hasClass(\"active\"))return this.sliding=!1;var j=f[0],k=a.Event(\"slide.bs.carousel\",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(\".active\").removeClass(\"active\");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass(\"active\")}var m=a.Event(\"slid.bs.carousel\",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass(\"slide\")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one(\"bsTransitionEnd\",function(){f.removeClass([b,h].join(\" \")).addClass(\"active\"),e.removeClass([\"active\",h].join(\" \")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass(\"active\"),f.addClass(\"active\"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr(\"data-target\")||(d=e.attr(\"href\"))&&d.replace(/.*(?=#[^\\s]+$)/,\"\"));if(f.hasClass(\"carousel\")){var g=a.extend({},f.data(),e.data()),h=e.attr(\"data-slide-to\");h&&(g.interval=!1),b.call(f,g),h&&f.data(\"bs.carousel\").to(h),c.preventDefault()}};a(document).on(\"click.bs.carousel.data-api\",\"[data-slide]\",e).on(\"click.bs.carousel.data-api\",\"[data-slide-to]\",e),a(window).on(\"load\",function(){a('[data-ride=\"carousel\"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){\"use strict\";function b(b){var c,d=b.attr(\"data-target\")||(c=b.attr(\"href\"))&&c.replace(/.*(?=#[^\\s]+$)/,\"\");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data(\"bs.collapse\"),f=a.extend({},d.DEFAULTS,c.data(),\"object\"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data(\"bs.collapse\",e=new d(this,f)),\"string\"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle=\"collapse\"][href=\"#'+b.id+'\"],[data-toggle=\"collapse\"][data-target=\"#'+b.id+'\"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION=\"3.3.6\",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass(\"width\");return a?\"width\":\"height\"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass(\"in\")){var b,e=this.$parent&&this.$parent.children(\".panel\").children(\".in, .collapsing\");if(!(e&&e.length&&(b=e.data(\"bs.collapse\"),b&&b.transitioning))){var f=a.Event(\"show.bs.collapse\");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,\"hide\"),b||e.data(\"bs.collapse\",null));var g=this.dimension();this.$element.removeClass(\"collapse\").addClass(\"collapsing\")[g](0).attr(\"aria-expanded\",!0),this.$trigger.removeClass(\"collapsed\").attr(\"aria-expanded\",!0),this.transitioning=1;var h=function(){this.$element.removeClass(\"collapsing\").addClass(\"collapse in\")[g](\"\"),this.transitioning=0,this.$element.trigger(\"shown.bs.collapse\")};if(!a.support.transition)return h.call(this);var i=a.camelCase([\"scroll\",g].join(\"-\"));this.$element.one(\"bsTransitionEnd\",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass(\"in\")){var b=a.Event(\"hide.bs.collapse\");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass(\"collapsing\").removeClass(\"collapse in\").attr(\"aria-expanded\",!1),this.$trigger.addClass(\"collapsed\").attr(\"aria-expanded\",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass(\"collapsing\").addClass(\"collapse\").trigger(\"hidden.bs.collapse\")};return a.support.transition?void this.$element[c](0).one(\"bsTransitionEnd\",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass(\"in\")?\"hide\":\"show\"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle=\"collapse\"][data-parent=\"'+this.options.parent+'\"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass(\"in\");a.attr(\"aria-expanded\",c),b.toggleClass(\"collapsed\",!c).attr(\"aria-expanded\",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on(\"click.bs.collapse.data-api\",'[data-toggle=\"collapse\"]',function(d){var e=a(this);e.attr(\"data-target\")||d.preventDefault();var f=b(e),g=f.data(\"bs.collapse\"),h=g?\"toggle\":e.data();c.call(f,h)})}(jQuery),+function(a){\"use strict\";function b(b){var c=b.attr(\"data-target\");c||(c=b.attr(\"href\"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\\s]*$)/,\"\"));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass(\"open\")&&(c&&\"click\"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event(\"hide.bs.dropdown\",f)),c.isDefaultPrevented()||(d.attr(\"aria-expanded\",\"false\"),e.removeClass(\"open\").trigger(a.Event(\"hidden.bs.dropdown\",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data(\"bs.dropdown\");d||c.data(\"bs.dropdown\",d=new g(this)),\"string\"==typeof b&&d[b].call(c)})}var e=\".dropdown-backdrop\",f='[data-toggle=\"dropdown\"]',g=function(b){a(b).on(\"click.bs.dropdown\",this.toggle)};g.VERSION=\"3.3.6\",g.prototype.toggle=function(d){var e=a(this);if(!e.is(\".disabled, :disabled\")){var f=b(e),g=f.hasClass(\"open\");if(c(),!g){\"ontouchstart\"in document.documentElement&&!f.closest(\".navbar-nav\").length&&a(document.createElement(\"div\")).addClass(\"dropdown-backdrop\").insertAfter(a(this)).on(\"click\",c);var h={relatedTarget:this};if(f.trigger(d=a.Event(\"show.bs.dropdown\",h)),d.isDefaultPrevented())return;e.trigger(\"focus\").attr(\"aria-expanded\",\"true\"),f.toggleClass(\"open\").trigger(a.Event(\"shown.bs.dropdown\",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(\".disabled, :disabled\")){var e=b(d),g=e.hasClass(\"open\");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger(\"focus\"),d.trigger(\"click\");var h=\" li:not(.disabled):visible a\",i=e.find(\".dropdown-menu\"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger(\"focus\")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on(\"click.bs.dropdown.data-api\",c).on(\"click.bs.dropdown.data-api\",\".dropdown form\",function(a){a.stopPropagation()}).on(\"click.bs.dropdown.data-api\",f,g.prototype.toggle).on(\"keydown.bs.dropdown.data-api\",f,g.prototype.keydown).on(\"keydown.bs.dropdown.data-api\",\".dropdown-menu\",g.prototype.keydown)}(jQuery),+function(a){\"use strict\";function b(b,d){return this.each(function(){var e=a(this),f=e.data(\"bs.modal\"),g=a.extend({},c.DEFAULTS,e.data(),\"object\"==typeof b&&b);f||e.data(\"bs.modal\",f=new c(this,g)),\"string\"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(\".modal-dialog\"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(\".modal-content\").load(this.options.remote,a.proxy(function(){this.$element.trigger(\"loaded.bs.modal\")},this))};c.VERSION=\"3.3.6\",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event(\"show.bs.modal\",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass(\"modal-open\"),this.escape(),this.resize(),this.$element.on(\"click.dismiss.bs.modal\",'[data-dismiss=\"modal\"]',a.proxy(this.hide,this)),this.$dialog.on(\"mousedown.dismiss.bs.modal\",function(){d.$element.one(\"mouseup.dismiss.bs.modal\",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass(\"fade\");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass(\"in\"),d.enforceFocus();var f=a.Event(\"shown.bs.modal\",{relatedTarget:b});e?d.$dialog.one(\"bsTransitionEnd\",function(){d.$element.trigger(\"focus\").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger(\"focus\").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event(\"hide.bs.modal\"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off(\"focusin.bs.modal\"),this.$element.removeClass(\"in\").off(\"click.dismiss.bs.modal\").off(\"mouseup.dismiss.bs.modal\"),this.$dialog.off(\"mousedown.dismiss.bs.modal\"),a.support.transition&&this.$element.hasClass(\"fade\")?this.$element.one(\"bsTransitionEnd\",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off(\"focusin.bs.modal\").on(\"focusin.bs.modal\",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger(\"focus\")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on(\"keydown.dismiss.bs.modal\",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off(\"keydown.dismiss.bs.modal\")},c.prototype.resize=function(){this.isShown?a(window).on(\"resize.bs.modal\",a.proxy(this.handleUpdate,this)):a(window).off(\"resize.bs.modal\")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass(\"modal-open\"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger(\"hidden.bs.modal\")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass(\"fade\")?\"fade\":\"\";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement(\"div\")).addClass(\"modal-backdrop \"+e).appendTo(this.$body),this.$element.on(\"click.dismiss.bs.modal\",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&(\"static\"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass(\"in\"),!b)return;f?this.$backdrop.one(\"bsTransitionEnd\",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass(\"in\");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass(\"fade\")?this.$backdrop.one(\"bsTransitionEnd\",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:\"\",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:\"\"})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:\"\",paddingRight:\"\"})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css(\"padding-right\")||0,10);this.originalBodyPad=document.body.style.paddingRight||\"\",this.bodyIsOverflowing&&this.$body.css(\"padding-right\",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css(\"padding-right\",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement(\"div\");a.className=\"modal-scrollbar-measure\",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on(\"click.bs.modal.data-api\",'[data-toggle=\"modal\"]',function(c){var d=a(this),e=d.attr(\"href\"),f=a(d.attr(\"data-target\")||e&&e.replace(/.*(?=#[^\\s]+$)/,\"\")),g=f.data(\"bs.modal\")?\"toggle\":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is(\"a\")&&c.preventDefault(),f.one(\"show.bs.modal\",function(a){a.isDefaultPrevented()||f.one(\"hidden.bs.modal\",function(){d.is(\":visible\")&&d.trigger(\"focus\")})}),b.call(f,g,this)})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.tooltip\"),f=\"object\"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data(\"bs.tooltip\",e=new c(this,f)),\"string\"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init(\"tooltip\",a,b)};c.VERSION=\"3.3.6\",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:\"top\",selector:!1,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,container:!1,viewport:{selector:\"body\",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error(\"`selector` option must be specified when initializing \"+this.type+\" on the window.document object!\");for(var e=this.options.trigger.split(\" \"),f=e.length;f--;){var g=e[f];if(\"click\"==g)this.$element.on(\"click.\"+this.type,this.options.selector,a.proxy(this.toggle,this));else if(\"manual\"!=g){var h=\"hover\"==g?\"mouseenter\":\"focusin\",i=\"hover\"==g?\"mouseleave\":\"focusout\";this.$element.on(h+\".\"+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+\".\"+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:\"manual\",selector:\"\"}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&\"number\"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data(\"bs.\"+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c)),b instanceof a.Event&&(c.inState[\"focusin\"==b.type?\"focus\":\"hover\"]=!0),c.tip().hasClass(\"in\")||\"in\"==c.hoverState?void(c.hoverState=\"in\"):(clearTimeout(c.timeout),c.hoverState=\"in\",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){\"in\"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data(\"bs.\"+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c)),b instanceof a.Event&&(c.inState[\"focusout\"==b.type?\"focus\":\"hover\"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState=\"out\",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){\"out\"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event(\"show.bs.\"+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr(\"id\",g),this.$element.attr(\"aria-describedby\",g),this.options.animation&&f.addClass(\"fade\");var h=\"function\"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\\s?auto?\\s?/i,j=i.test(h);j&&(h=h.replace(i,\"\")||\"top\"),f.detach().css({top:0,left:0,display:\"block\"}).addClass(h).data(\"bs.\"+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger(\"inserted.bs.\"+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h=\"bottom\"==h&&k.bottom+m>o.bottom?\"top\":\"top\"==h&&k.top-m<o.top?\"bottom\":\"right\"==h&&k.right+l>o.width?\"left\":\"left\"==h&&k.left-l<o.left?\"right\":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger(\"shown.bs.\"+e.type),e.hoverState=null,\"out\"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass(\"fade\")?f.one(\"bsTransitionEnd\",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css(\"margin-top\"),10),h=parseInt(d.css(\"margin-left\"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass(\"in\");var i=d[0].offsetWidth,j=d[0].offsetHeight;\"top\"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?\"offsetWidth\":\"offsetHeight\";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?\"left\":\"top\",50*(1-a/b)+\"%\").css(c?\"top\":\"left\",\"\")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(\".tooltip-inner\")[this.options.html?\"html\":\"text\"](b),a.removeClass(\"fade in top bottom left right\")},c.prototype.hide=function(b){function d(){\"in\"!=e.hoverState&&f.detach(),e.$element.removeAttr(\"aria-describedby\").trigger(\"hidden.bs.\"+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event(\"hide.bs.\"+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass(\"in\"),a.support.transition&&f.hasClass(\"fade\")?f.one(\"bsTransitionEnd\",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr(\"title\")||\"string\"!=typeof a.attr(\"data-original-title\"))&&a.attr(\"data-original-title\",a.attr(\"title\")||\"\").attr(\"title\",\"\")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d=\"BODY\"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return\"bottom\"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:\"top\"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:\"left\"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr(\"data-original-title\")||(\"function\"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+\" `template` option must consist of exactly 1 top-level element!\");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(\".tooltip-arrow\")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data(\"bs.\"+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data(\"bs.\"+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass(\"in\")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off(\".\"+a.type).removeData(\"bs.\"+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.popover\"),f=\"object\"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data(\"bs.popover\",e=new c(this,f)),\"string\"==typeof b&&e[b]())})}var c=function(a,b){this.init(\"popover\",a,b)};if(!a.fn.tooltip)throw new Error(\"Popover requires tooltip.js\");c.VERSION=\"3.3.6\",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:\"right\",trigger:\"click\",content:\"\",template:'<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(\".popover-title\")[this.options.html?\"html\":\"text\"](b),a.find(\".popover-content\").children().detach().end()[this.options.html?\"string\"==typeof c?\"html\":\"append\":\"text\"](c),a.removeClass(\"fade top bottom left right in\"),a.find(\".popover-title\").html()||a.find(\".popover-title\").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr(\"data-content\")||(\"function\"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(\".arrow\")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){\"use strict\";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||\"\")+\" .nav li > a\",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on(\"scroll.bs.scrollspy\",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data(\"bs.scrollspy\"),f=\"object\"==typeof c&&c;e||d.data(\"bs.scrollspy\",e=new b(this,f)),\"string\"==typeof c&&e[c]()})}b.VERSION=\"3.3.6\",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c=\"offset\",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c=\"position\",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data(\"target\")||b.attr(\"href\"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(\":visible\")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target=\"'+b+'\"],'+this.selector+'[href=\"'+b+'\"]',d=a(c).parents(\"li\").addClass(\"active\");\n    d.parent(\".dropdown-menu\").length&&(d=d.closest(\"li.dropdown\").addClass(\"active\")),d.trigger(\"activate.bs.scrollspy\")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,\".active\").removeClass(\"active\")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on(\"load.bs.scrollspy.data-api\",function(){a('[data-spy=\"scroll\"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.tab\");e||d.data(\"bs.tab\",e=new c(this)),\"string\"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION=\"3.3.6\",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest(\"ul:not(.dropdown-menu)\"),d=b.data(\"target\");if(d||(d=b.attr(\"href\"),d=d&&d.replace(/.*(?=#[^\\s]*$)/,\"\")),!b.parent(\"li\").hasClass(\"active\")){var e=c.find(\".active:last a\"),f=a.Event(\"hide.bs.tab\",{relatedTarget:b[0]}),g=a.Event(\"show.bs.tab\",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest(\"li\"),c),this.activate(h,h.parent(),function(){e.trigger({type:\"hidden.bs.tab\",relatedTarget:b[0]}),b.trigger({type:\"shown.bs.tab\",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass(\"active\").find(\"> .dropdown-menu > .active\").removeClass(\"active\").end().find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!1),b.addClass(\"active\").find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!0),h?(b[0].offsetWidth,b.addClass(\"in\")):b.removeClass(\"fade\"),b.parent(\".dropdown-menu\").length&&b.closest(\"li.dropdown\").addClass(\"active\").end().find('[data-toggle=\"tab\"]').attr(\"aria-expanded\",!0),e&&e()}var g=d.find(\"> .active\"),h=e&&a.support.transition&&(g.length&&g.hasClass(\"fade\")||!!d.find(\"> .fade\").length);g.length&&h?g.one(\"bsTransitionEnd\",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass(\"in\")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),\"show\")};a(document).on(\"click.bs.tab.data-api\",'[data-toggle=\"tab\"]',e).on(\"click.bs.tab.data-api\",'[data-toggle=\"pill\"]',e)}(jQuery),+function(a){\"use strict\";function b(b){return this.each(function(){var d=a(this),e=d.data(\"bs.affix\"),f=\"object\"==typeof b&&b;e||d.data(\"bs.affix\",e=new c(this,f)),\"string\"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on(\"scroll.bs.affix.data-api\",a.proxy(this.checkPosition,this)).on(\"click.bs.affix.data-api\",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION=\"3.3.6\",c.RESET=\"affix affix-top affix-bottom\",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&\"top\"==this.affixed)return c>e?\"top\":!1;if(\"bottom\"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:\"bottom\":a-d>=e+g?!1:\"bottom\";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?\"top\":null!=d&&i+j>=a-d?\"bottom\":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass(\"affix\");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(\":visible\")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());\"object\"!=typeof d&&(f=e=d),\"function\"==typeof e&&(e=d.top(this.$element)),\"function\"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css(\"top\",\"\");var i=\"affix\"+(h?\"-\"+h:\"\"),j=a.Event(i+\".bs.affix\");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin=\"bottom\"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace(\"affix\",\"affixed\")+\".bs.affix\")}\"bottom\"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on(\"load\",function(){a('[data-spy=\"affix\"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);","StripeIntegration_Payments/js/stripe.js":"// Copyright \u00a9 Stripe, Inc\n//\n// @package    StripeIntegration_Payments\n// @version    4.2.0\ndefine(\n    [\n        'stripejs'\n    ],\n    function ()\n    {\n        'use strict';\n\n        // Warning: This file should be kept lightweight as it is loaded on nearly all pages.\n\n        return (window.stripe = {\n\n            // Properties\n            version: \"4.2.0\",\n            stripeJs: null,\n\n            initStripe: function(params, callback)\n            {\n                if (typeof callback == \"undefined\")\n                    callback = null;\n\n                var message = null;\n\n                if (!this.stripeJs)\n                {\n                    try\n                    {\n                        var options = {};\n                        if (params.options)\n                        {\n                            options = params.options;\n                        }\n\n                        this.stripeJs = Stripe(params.apiKey, options);\n                    }\n                    catch (e)\n                    {\n                        if (typeof e != \"undefined\" && typeof e.message != \"undefined\")\n                            message = 'Could not initialize Stripe.js: ' + e.message;\n                        else\n                            message = 'Could not initialize Stripe.js';\n                    }\n\n                    if (this.stripeJs && typeof params.appInfo != \"undefined\")\n                    {\n                        try\n                        {\n                            this.stripeJs.registerAppInfo(params.appInfo);\n                        }\n                        catch (e)\n                        {\n                            console.warn(e);\n                        }\n                    }\n                }\n\n                if (callback)\n                    callback(message);\n                else if (message)\n                    console.error(message);\n            },\n\n            authenticateCustomer: function(intentId, done) {\n                try {\n                    var isPaymentIntent = intentId.startsWith('pi_');\n                    var isSetupIntent = intentId.startsWith('seti_');\n\n                    var handleIntent = function(result) {\n                        if (result.error)\n                            return done(result.error);\n\n                        var intent = result.paymentIntent || result.setupIntent;\n                        var requiresActionStatuses = [\"requires_action\", \"requires_source_action\"];\n\n                        if (requiresActionStatuses.includes(intent.status))\n                        {\n                            if (intent.next_action && intent.next_action.type === \"verify_with_microdeposits\")\n                            {\n                                window.location = intent.next_action.verify_with_microdeposits.hosted_verification_url;\n                            }\n                            else\n                            {\n                                stripe.stripeJs.handleNextAction({\n                                    clientSecret: intent.client_secret\n                                })\n                                .then(function(result)\n                                {\n                                    if (result && result.error)\n                                    {\n                                        return done(result.error.message);\n                                    }\n\n                                    return done();\n                                });\n                            }\n                        }\n                        else\n                        {\n                            return done();\n                        }\n                    };\n\n                    if (isPaymentIntent) {\n                        this.stripeJs.retrievePaymentIntent(intentId).then(handleIntent);\n                    } else if (isSetupIntent) {\n                        this.stripeJs.retrieveSetupIntent(intentId).then(handleIntent);\n                    } else {\n                        throw new Error(\"Invalid intent ID\");\n                    }\n                } catch (e) {\n                    done(e.message);\n                }\n            }\n        });\n    }\n);\n","StripeIntegration_Payments/js/stripe_payments_express.js":"/*global define*/\ndefine(\n    [\n        'jquery',\n        'mage/url',\n        'mage/storage',\n        'Magento_Ui/js/modal/alert',\n        'mage/translate',\n        'Magento_Customer/js/customer-data',\n        'StripeIntegration_Payments/js/stripe',\n        'mage/loader'\n    ],\n    function (\n        jQuery,\n        urlBuilder,\n        storage,\n        alert,\n        $t,\n        customerData,\n        stripe\n    ) {\n        'use strict';\n\n        return {\n            shippingAddress: [],\n            shippingMethod: null,\n            elements: null,\n            expressCheckoutElement: null,\n            expressCheckoutOptions: null,\n            clickResolvePayload: null,\n            resolvePayload: null,\n            pendingActionsQueue: [],\n            isAddToCartPending: false,\n            waitingForNewTotals: false,\n            lastTotal: null,\n            mountElementId: null,\n            mode: null,\n            isLoading: false,\n            debug: false,\n\n            getExpressCheckoutElementParams: function(payload, callback)\n            {\n                var serviceUrl = urlBuilder.build('/rest/V1/stripe/payments/ece_params', {}),\n                    self = this;\n\n                return storage.post(\n                    serviceUrl,\n                    JSON.stringify(payload),\n                    false\n                )\n                .fail(function (xhr, textStatus, errorThrown)\n                {\n                    console.error(\"Could not retrieve initialization params for Express Checkout\");\n                })\n                .done(function (response) {\n                    self.processResponseWithECEParams(response, callback);\n                });\n            },\n\n            processResponseWithECEParams: function(response, callback)\n            {\n                try\n                {\n                    if (typeof response === 'string') {\n                        response = JSON.parse(response);\n                    }\n\n                    if (response && response.resolvePayload)\n                    {\n                        if (response.resolvePayload.allowedShippingCountries)\n                        {\n                            // Convert to object map to array\n                            response.resolvePayload.allowedShippingCountries = Object.keys(response.resolvePayload.allowedShippingCountries).map(function (key) { return response.resolvePayload.allowedShippingCountries[key]; });\n                        }\n\n                        callback(null, response);\n                    }\n                    else\n                    {\n                        callback(null, response);\n                    }\n                }\n                catch (e)\n                {\n                    callback(e.message, response);\n                }\n            },\n\n            /**\n             * Init Stripe Express\n             * @param elementId\n             * @param apiKey\n             * @param paramsType\n             * @param settings\n             * @param callback\n             */\n            initStripeExpress: function (elementId, stripeJsInitParams, locationDetails, expressCheckoutOptions, callback)\n            {\n                // Only one express element is allowed per page\n                if (locationDetails.location == 'minicart')\n                {\n                    if (document.body.classList.contains('catalog-product-view') && // We are on the product page\n                        locationDetails.activeLocations.indexOf('product_page') >= 0) // ECE is enabled on the product page\n                        return;\n\n                    if (document.body.classList.contains('checkout-cart-index') && // We are on the cart page\n                        locationDetails.activeLocations.indexOf('shopping_cart_page') >= 0) // ECE is enabled on the cart page\n                        return;\n                }\n\n                if (this.waitingForNewTotals)\n                {\n                    // This method can be called from cart.subscribe(). In that case, we do not want to re-initialize the widget\n                    // because we are waiting for the addToCart() to finish. We will update the amounts after the addToCart() is done.\n                    return;\n                }\n\n                var self = this;\n                this.mountElementId = elementId;\n                this.stripeJsInitParams = stripeJsInitParams;\n                this.locationDetails = locationDetails;\n                this.expressCheckoutOptions = expressCheckoutOptions;\n\n                this.getExpressCheckoutElementParams(locationDetails, function(err, result)\n                {\n                    if (err)\n                    {\n                        console.warn('Cannot initialize wallets: ' + err);\n                        return;\n                    }\n\n                    if (!result.elementOptions)\n                        return;\n\n                    if (result.elementOptions.mode != 'setup')\n                    {\n                        // if (!result.elementOptions.amount || result.elementOptions.amount == 0)\n                        //     return;\n                    }\n\n                    self.mode = result.elementOptions.mode;\n                    self.clickResolvePayload = result.resolvePayload;\n\n                    stripe.initStripe(stripeJsInitParams, function (err)\n                    {\n                        if (err)\n                        {\n                            self.showError(self.maskError(err));\n                            return;\n                        }\n\n                        self.initElements(result.elementOptions);\n                        self.initExpressCheckoutElement(elementId, expressCheckoutOptions, callback);\n                    });\n                });\n            },\n\n            // Accepts unlimited parameters\n            log: function()\n            {\n                if (!this.debug)\n                    return;\n\n                console.log.apply(console, arguments);\n            },\n\n            initElements: function(elementsOptions)\n            {\n                if (!this.elements)\n                {\n                    this.log('initElements', elementsOptions);\n                    this.elements = stripe.stripeJs.elements(elementsOptions);\n                }\n                else\n                {\n                    this.log('updateElements', elementsOptions);\n                    this.elements.update(elementsOptions);\n                }\n            },\n\n            maskError: function(err)\n            {\n                var errLowercase = err.toLowerCase();\n                var pos1 = errLowercase.indexOf(\"Invalid API key provided\".toLowerCase());\n                var pos2 = errLowercase.indexOf(\"No API key provided\".toLowerCase());\n                if (pos1 === 0 || pos2 === 0)\n                    return 'Invalid Stripe API key provided.';\n\n                return err;\n            },\n\n            initExpressCheckoutElement: function(elementId, expressCheckoutOptions, callback)\n            {\n                if (this.expressCheckoutElement)\n                {\n                    // ECE was already initialized, no need to update it.\n                    return;\n                }\n\n                var DOMElement = jQuery(elementId),\n                    self = this;\n\n                try {\n                    if (typeof expressCheckoutOptions === 'string')\n                        expressCheckoutOptions = JSON.parse(expressCheckoutOptions);\n\n                    this.log('initExpressCheckoutElement', expressCheckoutOptions);\n                    this.expressCheckoutElement = this.elements.create('expressCheckout', expressCheckoutOptions);\n                }\n                catch (e)\n                {\n                    console.warn(e.message);\n                    return;\n                }\n\n                if (document.getElementById(elementId.substr(1)))\n                    this.expressCheckoutElement.mount(elementId);\n\n                this.expressCheckoutElement.on('ready', function (result)\n                {\n                    self.log(\"on.ready\");\n                    if (result.availablePaymentMethods)\n                    {\n                        callback(self.expressCheckoutElement);\n                    }\n                    else\n                    {\n                        DOMElement.hide();\n                    }\n                });\n            },\n\n            getClientSecretFromResponse: function(response)\n            {\n                if (typeof response != \"string\")\n                {\n                    return null;\n                }\n\n                if (response.indexOf(\"Authentication Required: \") >= 0)\n                {\n                    return response.substring(\"Authentication Required: \".length);\n                }\n\n                return null;\n            },\n\n            /**\n             * Place Order\n             * @param result\n             * @param callback\n             */\n            placeOrder: function (result, location, callback) {\n                var serviceUrl = urlBuilder.build('/rest/V1/stripe/payments/place_order', {}),\n                    payload = {\n                        result: result,\n                        location: location\n                    },\n                    self = this;\n\n                return storage.post(\n                    serviceUrl,\n                    JSON.stringify(payload),\n                    false\n                ).fail(function (xhr, textStatus, errorThrown)\n                {\n                    try\n                    {\n                        var response = JSON.parse(xhr.responseText);\n\n                        var clientSecret = self.getClientSecretFromResponse(response.message);\n\n                        if (clientSecret)\n                        {\n                            return stripe.authenticateCustomer(clientSecret, function(err)\n                            {\n                                if (err)\n                                    return callback(err, { message: err }, result);\n\n                                self.placeOrder(result, location, callback);\n                            });\n                        }\n                        else\n                            callback(response.message, response, result);\n                    }\n                    catch (e)\n                    {\n                        return self.showError(xhr.responseText);\n                    }\n                }).done(function (response) { // @todo - this should be success, we dont want to callback() on failure\n                    if (typeof response === 'string')\n                    {\n                        try\n                        {\n                            response = JSON.parse(response);\n                        }\n                        catch (e)\n                        {\n                            return self.showError(response);\n                        }\n                    }\n\n                    callback(null, response, result);\n                });\n            },\n\n            /**\n             * Add Item to Cart\n             * @param params\n             * @param shipping_id\n             * @param callback\n             */\n            addToCart: function(params, shipping_id, callback) {\n                var self = this;\n                this.isAddToCartPending = this.waitingForNewTotals = true;\n                var addToCartPromise = new Promise(function(resolve, reject) {\n                    var serviceUrl = urlBuilder.build('/rest/V1/stripe/payments/addtocart', {}),\n                        payload = {params: params, shipping_id: shipping_id};\n\n                    storage.post(\n                        serviceUrl,\n                        JSON.stringify(payload),\n                        false\n                    ).fail(function(xhr, textStatus, errorThrown) {\n                        self.parseFailedResponse.apply(self, [xhr.responseText, callback]);\n                        self.waitingForNewTotals = false;\n                        reject(); // Reject the promise\n                    }).done(function(response) {\n                        customerData.invalidate(['cart']);\n                        customerData.reload(['cart'], true);\n                        callback(null, response);\n                        resolve(); // Resolve the promise\n                    });\n                });\n\n                addToCartPromise.then(function() {\n                    self.isAddToCartPending = false;\n\n                    // After the promise is resolved, run the functions in the queue\n                    while (self.pendingActionsQueue.length) {\n                        var fn = self.pendingActionsQueue.shift(); // Dequeue the first function\n                        fn(); // Execute the dequeued function\n                    }\n\n                    self.waitingForNewTotals = false;\n\n                    // Invalidate the minicart and display any errors or warnings. The wait is needed so that the server side finishes processing any cart updates\n                    setTimeout(function()\n                    {\n                        customerData.reload(['cart', 'messages'], true);\n                    }, 1000);\n                });\n\n                return addToCartPromise;\n            },\n\n            getShippingAddressFrom: function(eceShippingAddress)\n            {\n                if (!eceShippingAddress)\n                    return null;\n\n                // For some countries like Japan, the ECE does not set the City, only the region\n                if (eceShippingAddress.city.length == 0 && eceShippingAddress.region.length > 0)\n                    eceShippingAddress.city = eceShippingAddress.region;\n\n                return eceShippingAddress;\n            },\n\n            getNewShippingRatesFor: function(address, callback) {\n                var serviceUrl = urlBuilder.build('/rest/V1/stripe/payments/ece_shipping_address_changed', {}),\n                    payload = {newAddress: address, location: this.locationDetails.location},\n                    self = this;\n\n                return storage.post(\n                    serviceUrl,\n                    JSON.stringify(payload),\n                    false\n                ).fail(function (xhr, textStatus, errorThrown)\n                {\n                    self.parseFailedResponse.apply(self, [ xhr.responseText, callback ]);\n                }\n                ).done(function (response) {\n                    self.processResponseWithECEParams(response, callback);\n                });\n            },\n\n            parseFailedResponse: function(responseText, callback)\n            {\n                try\n                {\n                    var response = JSON.parse(responseText);\n                    callback(response.message);\n                }\n                catch (e)\n                {\n                    callback(responseText);\n                }\n            },\n\n            /**\n             * Apply Shipping and Return Totals\n             * @param address\n             * @param shipping_id\n             * @param callback\n             * @returns {*}\n             */\n            updateShippingRate: function(address, shipping_id, callback) {\n                var serviceUrl = urlBuilder.build('/rest/V1/stripe/payments/ece_shipping_rate_changed', {}),\n                    payload = {address: address, shipping_id: shipping_id},\n                    self = this;\n\n                return storage.post(\n                    serviceUrl,\n                    JSON.stringify(payload),\n                    false\n                ).fail(function (xhr, textStatus, errorThrown)\n                {\n                    self.parseFailedResponse.apply(self, [ xhr.responseText, callback ]);\n                }\n                ).done(function (response) {\n                    self.processResponseWithECEParams(response, callback);\n                });\n            },\n\n            onShippingAddressChange: function(event)\n            {\n                this.log(\"onShippingAddressChange\");\n                var executeMethod = this.onShippingAddressChangeAction.bind(this, event);\n\n                if (this.isAddToCartPending) {\n                    this.pendingActionsQueue.push(executeMethod);\n                } else {\n                    executeMethod();\n                }\n            },\n\n            onShippingAddressChangeAction: function(event)\n            {\n                var self = this;\n                this.shippingAddress = this.getShippingAddressFrom(event.address);\n                this.waitingForNewTotals = true;\n                this.getNewShippingRatesFor(this.shippingAddress, function (err, eceResponseParams)\n                {\n                    if (err)\n                    {\n                        event.reject();\n                        self.waitingForNewTotals = false;\n                        return self.showError(err);\n                    }\n\n                    if (!eceResponseParams.resolvePayload.shippingRates)\n                    {\n                        event.reject();\n                        self.waitingForNewTotals = false;\n                        return;\n                    }\n\n                    self.resolveEvent(event, eceResponseParams.resolvePayload);\n                    self.waitingForNewTotals = false;\n                });\n            },\n\n            resolveEvent: function(event, resolvePayload)\n            {\n                if (!event)\n                    return;\n\n                var self = this;\n                var total = this.getLineItemsTotal(resolvePayload.lineItems);\n\n                if (resolvePayload.lineItems && !event.isClick && this.mode != \"setup\")\n                {\n                    if (total > 0)\n                    {\n                        this.log('Updating total to ' + total + ' cents');\n                        var promise = self.elements.update({amount: total});\n                    }\n                    else\n                    {\n                        this.log('Will not update total to ' + total + ' cents');\n                        delete resolvePayload.lineItems;\n                    }\n\n                    // We need this until a promise is implemented by Stripe\n                    setTimeout(function() {\n                        self.log('Resolving event with delay ', resolvePayload);\n                        event.resolve(resolvePayload);\n                    }, 1000);\n                }\n                else\n                {\n                    if (this.mode == \"setup\" && resolvePayload.lineItems)\n                    {\n                        delete resolvePayload.lineItems;\n                    }\n                    this.log('Resolving event with no delay ', resolvePayload, this.isAddToCartPending, total);\n                    event.resolve(resolvePayload);\n                }\n            },\n\n            getLineItemsTotal: function(lineItems)\n            {\n                var total = 0;\n\n                if (!lineItems || !lineItems.length)\n                    return total;\n\n                for (var i = 0; i < lineItems.length; i++) {\n                    total += lineItems[i].amount;\n                }\n\n                return total;\n            },\n\n            onShippingRateChange: function(event)\n            {\n                this.log(\"onShippingRateChange\");\n                var executeMethod = this.onShippingRateChangeAction.bind(this, event);\n\n                if (this.isAddToCartPending) {\n                    this.pendingActionsQueue.push(executeMethod);\n                } else {\n                    executeMethod();\n                }\n            },\n\n            onShippingRateChangeAction: function(event)\n            {\n                var self = this;\n                var shippingMethod = event.shippingRate.hasOwnProperty('id') ? event.shippingRate.id : null;\n                this.waitingForNewTotals = true;\n                this.updateShippingRate(this.shippingAddress, shippingMethod, function (err, response)\n                {\n                    if (err) {\n                        event.reject();\n                        self.waitingForNewTotals = false;\n                        return self.showError(err);\n                    }\n\n                    self.resolveEvent(event, response.resolvePayload);\n                    self.waitingForNewTotals = false;\n                });\n            },\n\n            startLoader: function()\n            {\n                if (this.isLoading)\n                    return;\n\n                this.isLoading = true;\n                jQuery('body').trigger('processStart');\n            },\n\n            stopLoader: function()\n            {\n                if (!this.isLoading)\n                    return;\n\n                this.isLoading = false;\n                jQuery('body').trigger('processStop');\n            },\n\n            onConfirm: function(location, confirmResult)\n            {\n                this.startLoader();\n\n                var onPaymentMethodCreated = this.onPaymentMethodCreated.bind(this, confirmResult, location);\n                var showError = this.showError.bind(this);\n\n                var paymentMethodData = {\n                    elements: this.elements,\n                    params: {\n                        billing_details: confirmResult.billingDetails\n                    },\n                    shipping: confirmResult.shippingAddress\n                };\n\n                this.elements.submit().then(function()\n                {\n                    stripe.stripeJs.createConfirmationToken(paymentMethodData).then(function(createConfirmationTokenResult)\n                    {\n                        if (createConfirmationTokenResult.error)\n                        {\n                            return showError(createConfirmationTokenResult.error.message);\n                        }\n                        else if (createConfirmationTokenResult.confirmationToken)\n                        {\n                            confirmResult.confirmationToken = createConfirmationTokenResult.confirmationToken;\n                            return onPaymentMethodCreated();\n                        }\n                        else\n                        {\n                            this.stopLoader();\n                            throw new Error('Invalid response from Stripe');\n                        }\n                    }).catch(function(error) {\n                        return showError(error.message);\n                    });\n                }).catch(function(error) {\n                    return showError(error.message);\n                });\n\n            },\n\n            onCancel: function()\n            {\n                this.log(\"onCancel\");\n                this.stopLoader();\n            },\n\n            initCheckoutWidget: function (checkoutValidator)\n            {\n                var self = this;\n                this.expressCheckoutElement.on('click', function(event)\n                {\n                    if (!checkoutValidator())\n                    {\n                        event.preventDefault();\n                        return;\n                    }\n\n                    event.isClick = true;\n                    self.startLoader();\n                    self.resolveEvent(event, self.clickResolvePayload);\n                });\n                this.expressCheckoutElement.on('shippingaddresschange', this.onShippingAddressChange.bind(this));\n                this.expressCheckoutElement.on('shippingratechange', this.onShippingRateChange.bind(this));\n                this.expressCheckoutElement.on('confirm', this.onConfirm.bind(this, 'checkout'));\n                this.expressCheckoutElement.on('cancel', this.onCancel.bind(this));\n            },\n\n            /**\n             * Init Widget for Cart Page\n             */\n            initCartWidget: function ()\n            {\n                var self = this;\n                this.expressCheckoutElement.on('click', function(event) {\n                    event.isClick = true;\n                    self.startLoader();\n                    self.resolveEvent(event, self.clickResolvePayload);\n                });\n                this.expressCheckoutElement.on('shippingaddresschange', this.onShippingAddressChange.bind(this));\n                this.expressCheckoutElement.on('shippingratechange', this.onShippingRateChange.bind(this));\n                this.expressCheckoutElement.on('confirm', this.onConfirm.bind(this, 'cart'));\n                this.expressCheckoutElement.on('cancel', this.onCancel.bind(this));\n            },\n\n            /**\n             * Init Widget for Mini cart\n             */\n            initMiniCartWidget: function ()\n            {\n                var self = this;\n                this.expressCheckoutElement.on('click', function(event) {\n                    event.isClick = true;\n                    self.startLoader();\n                    self.resolveEvent(event, self.clickResolvePayload);\n                });\n                this.expressCheckoutElement.on('shippingaddresschange', this.onShippingAddressChange.bind(this));\n                this.expressCheckoutElement.on('shippingratechange', this.onShippingRateChange.bind(this));\n                this.expressCheckoutElement.on('confirm', this.onConfirm.bind(this, 'minicart'));\n                this.expressCheckoutElement.on('cancel', this.onCancel.bind(this));\n            },\n\n            /**\n             * Init Widget for Single Product Page\n             */\n            initProductWidget: function ()\n            {\n                var self = this;\n                this.expressCheckoutElement.on('click', function(event) {\n                    event.isClick = true;\n                    self.startLoader();\n                    self.onClickAtProductPage(event);\n                });\n                this.expressCheckoutElement.on('shippingaddresschange', this.onShippingAddressChange.bind(this));\n                this.expressCheckoutElement.on('shippingratechange', this.onShippingRateChange.bind(this));\n                this.expressCheckoutElement.on('confirm', this.onConfirm.bind(this, 'product'));\n                this.expressCheckoutElement.on('cancel', this.onCancel.bind(this));\n\n                this.bindConfigurableProductOptions();\n            },\n\n            formToArrayObject: function(data) {\n                var obj = {};\n                for (var i = 0; i < data.length; i++) {\n                    obj[data[i].name] = data[i].value;\n                }\n                return obj;\n            },\n\n            onClickAtProductPage: function(event)\n            {\n                this.log(\"onClickAtProductPage\");\n                var self = this,\n                    form = jQuery('#product_addtocart_form'),\n                    params = [];\n\n                var validator = form.validation({radioCheckboxClosest: '.nested'});\n\n                if (!validator.valid())\n                {\n                    this.stopLoader();\n                    return;\n                }\n\n                // Add to Cart\n                params = this.formToArrayObject(form.serializeArray());\n                this.addToCart(params, this.shippingMethod, function (err)\n                {\n                    if (err)\n                    {\n                        return self.showError(err);\n                    }\n                });\n\n                this.resolveEvent(event, this.clickResolvePayload);\n            },\n\n            showError: function(message)\n            {\n                this.stopLoader();\n\n                alert({\n                    title: $t('Error'),\n                    content: message,\n                    actions: {\n                        always: function (){}\n                    }\n                });\n            },\n\n            onPaymentMethodCreated: function(result, location)\n            {\n                var self = this;\n                this.placeOrder(result, location, function (err, response, result)\n                {\n                    if (err)\n                    {\n                        self.showError(response.message);\n                    }\n                    else if (response.hasOwnProperty('redirect'))\n                    {\n                        customerData.invalidate(['cart']);\n                        window.location = response.redirect;\n                    }\n                    else\n                    {\n                        self.stopLoader();\n                    }\n                });\n            },\n\n            bindConfigurableProductOptions: function()\n            {\n                var self = this;\n                var options = jQuery(\"#product-options-wrapper .configurable select.super-attribute-select\");\n\n                options.each(function(index)\n                {\n                    var onConfigurableProductChanged = self.onConfigurableProductChanged.bind(self, this);\n                    jQuery(this).on(\"change\", onConfigurableProductChanged);\n                });\n            },\n\n            onConfigurableProductChanged: function(element)\n            {\n                var self = this;\n\n                if (element.value)\n                {\n                    var locationDetails = {\n                        location: 'product',\n                        productId: this.locationDetails.productId,\n                        attribute: element.value\n                    };\n                    this.initStripeExpress(\n                        this.mountElementId,\n                        this.stripeJsInitParams,\n                        locationDetails,\n                        self.expressCheckoutOptions,\n                        self.initProductWidget.bind(self)\n                    );\n                }\n            }\n        };\n    }\n);\n","StripeIntegration_Payments/js/view/ui_components/setup_element.js":"define(\n    [\n        'ko',\n        'uiComponent',\n        'StripeIntegration_Payments/js/action/list-payment-methods',\n        'StripeIntegration_Payments/js/action/add-payment-method',\n        'StripeIntegration_Payments/js/action/delete-payment-method',\n        'StripeIntegration_Payments/js/stripe',\n        'Magento_Ui/js/model/messageList',\n        'Magento_Customer/js/model/customer',\n        'mage/translate',\n        'jquery',\n        'mage/storage',\n        'Magento_Customer/js/customer-data',\n        'Magento_Ui/js/model/messages',\n        'uiLayout'\n    ],\n    function (\n        ko,\n        Component,\n        listPaymentMethodsAction,\n        addPaymentMethodAction,\n        deletePaymentMethodAction,\n        stripe,\n        globalMessageList,\n        customer,\n        $t,\n        $,\n        storage,\n        customerData,\n        messagesModel,\n        layout\n    ) {\n        'use strict';\n\n        return Component.extend({\n            externalRedirectUrl: null,\n            defaults: {\n                template: 'StripeIntegration_Payments/setup_element',\n            },\n            elements: null,\n            initParams: null,\n\n            initObservable: function ()\n            {\n                this._super()\n                    .observe([\n                        'paymentElement',\n                        'isPaymentFormComplete',\n                        'isPaymentFormVisible',\n                        'isLoading',\n                        'stripePaymentsError',\n                        'permanentError',\n                        'isOrderPlaced',\n                        'isInitialized',\n                        'savedPaymentMethods',\n                        'processingSavedPaymentMethods'\n                    ]);\n\n                var self = this;\n\n                this.isPaymentFormVisible(false);\n                this.isOrderPlaced(false);\n                this.isInitialized(false);\n                this.processingSavedPaymentMethods(false);\n\n                this.hasPaymentMethods = ko.computed(this.hasPaymentMethodsComputed.bind(this));\n\n                this.messageContainer = new messagesModel();\n\n                var messagesComponent = {\n                    parent: this.name,\n                    name: this.name + '.messages',\n                    displayArea: 'messages',\n                    component: 'Magento_Ui/js/view/messages',\n                    config: {\n                        messageContainer: this.messageContainer,\n                        autoHideTimeOut: -1\n                    }\n                };\n\n                layout([messagesComponent]);\n\n                return this;\n            },\n\n            getStripeParam: function(param)\n            {\n                if (typeof window.initParams == \"undefined\")\n                    return null;\n\n                if (typeof window.initParams[param] == \"undefined\")\n                    return null;\n\n                return window.initParams[param];\n            },\n\n            onPaymentElementContainerRendered: function()\n            {\n                var self = this;\n                this.isLoading(true);\n                this.listPaymentMethods();\n                var initParams = window.initParams;\n\n                stripe.initStripe(initParams, function(err)\n                {\n                    if (err)\n                        return self.crash(err);\n\n                    self.initSetupElement(initParams);\n                });\n            },\n\n            onContainerRendered: function()\n            {\n                this.onPaymentElementContainerRendered();\n            },\n\n            crash: function(message)\n            {\n                this.isLoading(false);\n                this.permanentError($t(\"Sorry, an error has occurred. Please contact us for assistance.\"));\n                console.error(\"Error: \" + message);\n            },\n\n            softCrash: function(message)\n            {\n                this.showError($t(\"Sorry, an error has occurred. Please contact us for assistance.\"));\n                this.stripePaymentsError(message);\n                console.error(\"Error: \" + message);\n            },\n\n            initSetupElement: function(params)\n            {\n                if (document.getElementById('stripe-setup-element') === null)\n                    return this.crash(\"Cannot initialize Payment Element on a DOM that does not contain a div.stripe-setup-element.\");\n\n                if (!stripe.stripeJs)\n                    return this.crash(\"Stripe.js could not be initialized.\");\n\n                var elements = this.elements = stripe.stripeJs.elements({\n                    mode: \"setup\",\n                    setup_future_usage: \"on_session\",\n                    locale: params.locale,\n                    currency: params.currency,\n                    appearance: this.getStripePaymentElementOptions(),\n                    paymentMethodCreation: \"manual\"\n                });\n\n                this.paymentElement = elements.create('payment');\n                this.paymentElement.mount('#stripe-setup-element');\n                this.paymentElement.on('change', this.onChange.bind(this));\n                this.isLoading(false);\n            },\n\n            onChange: function(event)\n            {\n                this.isLoading(false);\n                this.isPaymentFormComplete(event.complete);\n            },\n\n            getStripePaymentElementOptions: function()\n            {\n                return {\n                  theme: 'stripe',\n                  variables: {\n                    colorText: '#32325d',\n                    fontFamily: '\"Open Sans\",\"Helvetica Neue\", Helvetica, Arial, sans-serif',\n                  },\n                };\n            },\n\n            getAddressField: function(field)\n            {\n                var address = [];\n\n                if (typeof address[field] == \"undefined\")\n                    return null;\n\n                if (typeof address[field] !== \"string\" && typeof address[field] !== \"object\")\n                    return null;\n\n                if (address[field].length == 0)\n                    return null;\n\n                return address[field];\n            },\n\n            getBillingDetails: function()\n            {\n                var details = {};\n                var address = {};\n\n                if (this.getAddressField('city'))\n                    address.city = this.getAddressField('city');\n\n                if (this.getAddressField('countryId'))\n                    address.country = this.getAddressField('countryId');\n\n                if (this.getAddressField('postcode'))\n                    address.postal_code = this.getAddressField('postcode');\n\n                if (this.getAddressField('region'))\n                    address.state = this.getAddressField('region');\n\n                if (this.getAddressField('street'))\n                {\n                    var street = this.getAddressField('street');\n                    address.line1 = street[0];\n\n                    if (street.length > 1)\n                        address.line2 = street[1];\n                }\n\n                if (Object.keys(address).length > 0)\n                    details.address = address;\n\n                if (this.getAddressField('telephone'))\n                    details.phone = this.getAddressField('telephone');\n\n                if (this.getAddressField('firstname'))\n                    details.name = this.getAddressField('firstname') + ' ' + this.getAddressField('lastname');\n\n                if (customerData.email)\n                    details.email = customerData.email;\n\n                if (Object.keys(details).length > 0)\n                    return details;\n\n                return null;\n            },\n\n            config: function()\n            {\n                return self.initParams;\n            },\n\n            onClick: function(result, outcome, response)\n            {\n                if (!this.isPaymentFormComplete())\n                    return this.showError($t('Please complete the payment method details.'));\n\n                this.clearErrors();\n\n                this.isLoading(true);\n                var onPaymentMethodCreated = this.onPaymentMethodCreated.bind(this);\n                var onFail = this.onFail.bind(this);\n\n                this.createPaymentMethod(onPaymentMethodCreated, onFail);\n            },\n\n            createPaymentMethod: function(onPaymentMethodCreated, onFail)\n            {\n                var paymentMethodData = {\n                    elements: this.elements,\n                    params: {}\n                };\n\n                this.elements.submit().then(function()\n                {\n                    stripe.stripeJs.createPaymentMethod(paymentMethodData).then(onPaymentMethodCreated, onFail);\n                }, onFail);\n\n            },\n\n            setNewPaymentMethods: function(newMethods, isDuplicate)\n            {\n                this.savedPaymentMethods(newMethods);\n\n                if (isDuplicate)\n                {\n                    this.showSuccessMessage($t(\"An existing payment method has been updated.\"));\n                }\n                else\n                {\n                    this.showSuccessMessage($t(\"The payment method has been saved.\"));\n                }\n\n                this.clearFormData();\n            },\n\n            onPaymentMethodCreated: function(result)\n            {\n                var self = this;\n\n                if (result.error)\n                {\n                    this.showError(result.error.message);\n                }\n                else\n                {\n                    addPaymentMethodAction(result.paymentMethod.id, function(response, status, xhr)\n                    {\n                        self.isLoading(false);\n                        if (status == \"success\")\n                        {\n                            try\n                            {\n                                var data = JSON.parse(response);\n\n                                var methods = self.savedPaymentMethods();\n                                if (!methods)\n                                {\n                                    methods = [];\n                                }\n\n                                var isDuplicate = false;\n                                var newMethods = [];\n\n                                for (var i in methods)\n                                {\n                                    if (methods[i].fingerprint != data.fingerprint)\n                                    {\n                                        newMethods.push(methods[i]);\n                                    }\n                                    else\n                                    {\n                                        isDuplicate = true;\n                                    }\n                                }\n\n                                newMethods.push(data);\n\n                                if (data.client_secret)\n                                {\n                                    stripe.authenticateCustomer(data.client_secret, function(err)\n                                    {\n                                        if (err)\n                                        {\n                                            self.showError($t(\"Sorry, the payment method could not be saved: \" + err));\n                                            return;\n                                        }\n\n                                        self.setNewPaymentMethods(newMethods, isDuplicate);\n                                    });\n                                }\n                                else\n                                {\n                                    self.setNewPaymentMethods(newMethods, isDuplicate);\n                                }\n                            }\n                            catch (e)\n                            {\n                                console.warn(e);\n                                self.showError($t(\"The payment method could not be saved: %1\").replace(\"%1\", e.message));\n                            }\n                        }\n                        else if (response && response.responseJSON && response.responseJSON.message)\n                        {\n                            self.showError(response.responseJSON.message);\n                        }\n                        else\n                        {\n                            self.showError(\"Sorry, the payment methods could not be added.\");\n                            console.warn(response);\n                        }\n                    });\n                }\n            },\n\n            clearFormData: function()\n            {\n                this.paymentElement.clear();\n                $('html, body').animate({ scrollTop: $(\"#my-saved-payment-methods-table\").offset().top - 100}, 500);\n            },\n\n            onFail: function(result)\n            {\n                this.showError(\"Could not set up the payment method. Please try again.\");\n                console.error(result);\n            },\n\n            showError: function(message)\n            {\n                this.isLoading(false);\n                this.messageContainer.addErrorMessage({ \"message\": message });\n            },\n\n            showSuccessMessage: function(message)\n            {\n                this.isLoading(false);\n                this.messageContainer.addSuccessMessage({ \"message\": message });\n            },\n\n            validate: function(elm)\n            {\n                return true;\n            },\n\n            getCode: function()\n            {\n                return 'stripe_payments';\n            },\n\n            clearErrors: function()\n            {\n                this.messageContainer.clear();\n                this.stripePaymentsError(null);\n            },\n\n            hasPaymentMethodsComputed: function()\n            {\n                return this.savedPaymentMethods() && this.savedPaymentMethods().length > 0;\n            },\n\n            removePaymentMethod: function(fingerprint)\n            {\n                var methods = this.savedPaymentMethods();\n                if (!methods)\n                {\n                    methods = [];\n                }\n\n                var newMethods = [];\n\n                for (var i in methods)\n                {\n                    if (methods[i].fingerprint != fingerprint)\n                    {\n                        newMethods.push(methods[i]);\n                    }\n                }\n\n                return newMethods;\n            },\n\n            deletePaymentMethod: function(paymentMethod)\n            {\n                var sure = confirm($t(\"Are you sure you want to delete this payment method?\"));\n\n                if (!sure)\n                    return;\n\n                var self = this;\n                this.processingSavedPaymentMethods(true);\n                deletePaymentMethodAction(paymentMethod.id, paymentMethod.fingerprint, function(response, status, xhr)\n                {\n                    self.processingSavedPaymentMethods(false);\n                    if (status == \"success\")\n                    {\n                        try\n                        {\n                            var data = JSON.parse(response);\n                            self.showSuccessMessage(data);\n\n                            var newMethods = self.removePaymentMethod(paymentMethod.fingerprint);\n                            self.savedPaymentMethods(newMethods);\n                        }\n                        catch (e)\n                        {\n                            self.showError($t(\"The payment methods could not be deleted: %1\").replace(\"%1\", e.message));\n                        }\n                    }\n                    else if (response && response.responseJSON && response.responseJSON.message)\n                    {\n                        self.showError(response.responseJSON.message);\n                    }\n                    else\n                    {\n                        self.showError($t(\"The payment methods could not be deleted: %1\").replace(\"%1\", response));\n                    }\n                });\n            },\n\n            listPaymentMethods: function()\n            {\n                var self = this;\n                this.processingSavedPaymentMethods(true);\n\n                listPaymentMethodsAction(function(response, status, xhr)\n                {\n                    self.processingSavedPaymentMethods(false);\n                    if (status == \"success\")\n                    {\n                        try\n                        {\n                            var data = JSON.parse(response);\n                            var methods = [];\n\n                            for (var fingerprint in data)\n                            {\n                                methods.push(data[fingerprint]);\n                            }\n\n                            self.savedPaymentMethods(methods);\n                        }\n                        catch (e)\n                        {\n                            console.warn(e);\n                            console.warn(response);\n                        }\n                    }\n                });\n            }\n\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/subscription_update/review.js":"define(\n    [\n        'ko',\n        'Magento_Checkout/js/view/payment/default',\n        'Magento_Ui/js/model/messageList',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Customer/js/model/customer',\n        'StripeIntegration_Payments/js/helper/subscriptions',\n        'StripeIntegration_Payments/js/model/upcomingInvoice',\n        'mage/translate',\n        'jquery',\n        'Magento_Checkout/js/action/place-order',\n        'Magento_Checkout/js/model/payment/additional-validators',\n        'Magento_CheckoutAgreements/js/model/agreement-validator',\n        'Magento_CheckoutAgreements/js/model/agreements-assigner'\n    ],\n    function (\n        ko,\n        Component,\n        globalMessageList,\n        quote,\n        customer,\n        subscriptions,\n        upcomingInvoice,\n        $t,\n        $,\n        placeOrderAction,\n        additionalValidators,\n        agreementValidator,\n        agreementsAssigner\n    ) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                template: 'StripeIntegration_Payments/subscription_update/review',\n            },\n            currentTotals: null,\n            newPrice: ko.observable(\"--\"),\n            prorationFee: ko.observable(\"--\"),\n            unusedTime: ko.observable(\"--\"),\n            isPlaceOrderEnabled: ko.observable(false),\n            credit: ko.observable(null),\n\n            initObservable: function ()\n            {\n                this._super()\n                    .observe([\n                        'isLoading',\n                        'stripePaymentsError',\n                        'permanentError',\n                        'userError'\n                    ]);\n\n                var self = this;\n\n                this.initParams = window.checkoutConfig.payment.stripe_payments.initParams;\n\n                upcomingInvoice.initialize();\n                var onUpcomingInvoiceChanged = this.onUpcomingInvoiceChanged.bind(this);\n                upcomingInvoice.onChange(onUpcomingInvoiceChanged);\n\n                this.hasProrationFee = ko.computed(function(){\n                    return self.prorationFee() && self.prorationFee() != \"--\";\n                });\n\n                return this;\n            },\n\n            getConfig: function(key)\n            {\n                return subscriptions.getConfig(key);\n            },\n\n            crash: function(message)\n            {\n                this.isLoading(false);\n                if (this.userError())\n                    this.showError(this.userError());\n                else\n                    this.permanentError($t(\"Sorry, this payment method is not available. Please contact us for assistance.\"));\n\n                console.error(\"Error: \" + message);\n            },\n\n            softCrash: function(message)\n            {\n                this.isLoading(false);\n                if (this.userError())\n                    this.showError(this.userError());\n                else\n                    this.showError($t(\"Sorry, this payment method is not available. Please contact us for assistance.\"));\n\n                console.error(\"Error: \" + message);\n            },\n\n            onChange: function(event)\n            {\n                this.isLoading(false);\n            },\n\n            placeOrder: function()\n            {\n                if (!this.validate())\n                    return;\n\n                var self = this;\n                this.isPlaceOrderEnabled(false);\n                this.isLoading(true);\n\n                this.getPlaceOrderDeferredObject()\n                    .fail(this.handlePlaceOrderErrors.bind(this))\n                    .done(this.onOrderPlaced.bind(this))\n                    .always(function(){\n                        self.isLoading(false);\n                        self.isPlaceOrderEnabled(true);\n                    });\n            },\n\n            getPlaceOrderDeferredObject: function()\n            {\n                return placeOrderAction(this.getData(), this.messageContainer);\n            },\n\n            handlePlaceOrderErrors: function (result)\n            {\n                if (result && result.responseJSON && result.responseJSON.message)\n                    this.showError(result.responseJSON.message);\n                else\n                {\n                    this.showError($t(\"Sorry, the subscription could not be updated. Please contact us for assistance.\"));\n\n                    if (result && result.responseText)\n                        console.error(result.responseText);\n                    else\n                        console.error(result);\n                }\n            },\n\n            onOrderPlaced: function(result, outcome, response)\n            {\n                if (result && !isNaN(result))\n                {\n                    $.mage.redirect(subscriptions.getSuccessUrl());\n                    return;\n                }\n\n                try\n                {\n                    var jsonResponse = JSON.parse(result);\n                    if (jsonResponse && jsonResponse.error)\n                    {\n                        return this.showError(jsonResponse.error);\n                    }\n                    else\n                    {\n                        console.warn(\"The order could not be placed. The server response was: \" + result);\n                        return this.showError($t(\"Sorry, the subscription could not be updated. Please contact us for assistance.\"));\n                    }\n                }\n                catch (e)\n                {\n                    console.warn(\"The order could not be placed. The error was: \" + e);\n                        return this.showError($t(\"Sorry, the subscription could not be updated. Please contact us for assistance.\"));\n                }\n            },\n\n            getData: function()\n            {\n                var data = {\n                    'method': \"stripe_payments\",\n                    'additional_data': {\n                        'is_subscription_update': true\n                    }\n                };\n\n                agreementsAssigner(data);\n\n                return data;\n            },\n\n            showError: function(message)\n            {\n                this.isLoading(false);\n                this.messageContainer.addErrorMessage({ \"message\": message });\n            },\n\n            validate: function(elm)\n            {\n                return agreementValidator.validate() && additionalValidators.validate();\n            },\n\n            getCode: function()\n            {\n                return 'stripe_payments';\n            },\n\n            clearErrors: function()\n            {\n                this.stripePaymentsError(null);\n            },\n\n            onUpcomingInvoiceChanged: function(result, outcome, response)\n            {\n                try\n                {\n                    var params = JSON.parse(result);\n\n                    this.resetTotals();\n\n                    if (params && params.error)\n                    {\n                        this.userError(params.error);\n                        return this.softCrash(params.error);\n                    }\n\n                    if (!params || !params.upcomingInvoice)\n                        return this.softCrash(\"Could not retrieve upcoming invoice\");\n\n                    if (params.upcomingInvoice.new_price &&\n                        params.upcomingInvoice.new_price.label &&\n                        params.upcomingInvoice.new_price.label.length > 0)\n                    {\n                        this.newPrice(params.upcomingInvoice.new_price.label);\n                    }\n\n                    if (params.upcomingInvoice.proration_fee &&\n                        params.upcomingInvoice.proration_fee.label &&\n                        params.upcomingInvoice.proration_fee.label.length > 0)\n                    {\n                        this.prorationFee(params.upcomingInvoice.proration_fee.label);\n                    }\n\n                    if (params.upcomingInvoice.unused_time &&\n                        params.upcomingInvoice.unused_time.label &&\n                        params.upcomingInvoice.unused_time.label.length > 0)\n                    {\n                        this.unusedTime(params.upcomingInvoice.unused_time.label);\n                    }\n\n                    if (params.upcomingInvoice.credit)\n                    {\n                        this.credit(params.upcomingInvoice.credit);\n                    }\n\n                    this.isPlaceOrderEnabled(true);\n                }\n                catch (e)\n                {\n                    console.warn(\"Could not calculate subscription update prices\");\n                    console.warn(e);\n                }\n            },\n\n            resetTotals: function()\n            {\n                this.newPrice(\"--\");\n                this.prorationFee(\"--\");\n                this.unusedTime(\"--\");\n            },\n\n            getCancelUrl: function()\n            {\n                return subscriptions.getCancelUrl();\n            }\n\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/subscription_update/sidebar.js":"define([\n    'ko',\n    'uiComponent',\n    'Magento_Checkout/js/model/totals',\n    'Magento_Checkout/js/model/quote',\n    'Magento_Customer/js/customer-data',\n    'StripeIntegration_Payments/js/helper/subscriptions',\n    'mage/translate',\n    'jquery'\n],\nfunction (\n    ko,\n    Component,\n    totals,\n    quote,\n    customerData,\n    subscriptions,\n    $t,\n    $\n)\n{\n    'use strict';\n\n    return Component.extend({\n        isDisplayed: ko.observable(false),\n        isLoading: totals.isLoading,\n\n        initialize: function()\n        {\n            this._super();\n\n            this.isDisplayed(subscriptions.displaySidebar());\n\n            // var self = this;\n\n            // window.addEventListener('hashchange', function()\n            // {\n            //     self.isDisplayed(subscriptions.displaySidebar());\n            // });\n        },\n\n        getConfig: function(key)\n        {\n            return subscriptions.getConfig(key);\n        },\n\n        cancelUpdate: function()\n        {\n            var cancelUrl = subscriptions.getCancelUrl();\n            var yes = confirm($t(\"Are you sure you want to cancel the subscription update?\"));\n            if (yes)\n            {\n                $.mage.redirect(cancelUrl);\n            }\n        },\n\n    });\n});\n","StripeIntegration_Payments/js/view/checkout/trialing_subscriptions.js":"define(\n    [\n        'ko',\n        'Magento_Checkout/js/view/summary/abstract-total',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Catalog/js/price-utils',\n        'Magento_Checkout/js/model/totals',\n        'mage/translate',\n        'StripeIntegration_Payments/js/action/get-trialing-subscriptions',\n        'Magento_Customer/js/customer-data'\n    ],\n    function (ko, Component, quote, priceUtils, totals, $t, getTrialingSubscriptions, customerData) {\n        \"use strict\";\n        return Component.extend({\n            defaults: {\n                isFullTaxSummaryDisplayed: window.checkoutConfig.isFullTaxSummaryDisplayed || false,\n                template: 'StripeIntegration_Payments/checkout/trialing_subscriptions',\n                trialingSubscriptions: ko.observable(window.checkoutConfig.payment.stripe_payments.trialingSubscriptions),\n                fetching: ko.observable(false)\n            },\n            totals: quote.getTotals(),\n            isTaxDisplayedInGrandTotal: window.checkoutConfig.includeTaxInGrandTotal || false,\n\n            initialize: function ()\n            {\n                this._super();\n\n                this.observe(['trialingSubscriptions']);\n                this.trialingSubscriptions(window.checkoutConfig.payment.stripe_payments.trialingSubscriptions);\n\n                this.getFormattedSubscriptionsPrice = ko.computed(function()\n                {\n                    var price = -this.getAmount('subscriptions_total');\n                    return this.getFormattedPrice(price);\n                }, this);\n\n                this.getFormattedShipping = ko.computed(function()\n                {\n                    var price = -this.getAmount('shipping_total');\n                    return this.getFormattedPrice(price);\n                }, this);\n\n                this.getFormattedTax = ko.computed(function()\n                {\n                    var price = -this.getAmount('tax_total');\n                    return this.getFormattedPrice(price);\n                }, this);\n\n                this.getFormattedDiscount = ko.computed(function()\n                {\n                    var price = this.getAmount('discount_total');\n                    return this.getFormattedPrice(price);\n                }, this);\n\n                this.hasTrialingSubscriptions = ko.computed(function()\n                {\n                    return this.getAmount('subscriptions_total') !== 0;\n                }, this);\n\n                this.hasShipping = ko.computed(function()\n                {\n                    return this.getAmount('shipping_total') !== 0;\n                }, this);\n\n                this.hasTax = ko.computed(function()\n                {\n                    return this.getAmount('tax_total') !== 0;\n                }, this);\n\n                this.hasDiscount = ko.computed(function()\n                {\n                    return this.getAmount('discount_total') !== 0;\n                }, this);\n\n                this.trialingSubscriptions(this.getTrialSubscriptions());\n\n                var grandTotal = quote.totals().grand_total;\n\n                quote.totals.subscribe(function (totals)\n                {\n                    if (grandTotal == quote.totals().grand_total)\n                        return;\n\n                    grandTotal = quote.totals().grand_total;\n\n                    this.refresh(quote);\n                }, this);\n            },\n\n            isDisplayed: function()\n            {\n                return this.isFullMode() && this.getPureValue() !== 0;\n            },\n\n            getTrialSubscriptions: function()\n            {\n                if (\n                    window.checkoutConfig &&\n                    window.checkoutConfig.payment &&\n                    window.checkoutConfig.payment.stripe_payments &&\n                    window.checkoutConfig.payment.stripe_payments.hasTrialSubscriptions &&\n                    window.checkoutConfig.payment.stripe_payments.trialingSubscriptions\n                )\n                {\n                    return window.checkoutConfig.payment.stripe_payments.trialingSubscriptions;\n                }\n\n                return null;\n            },\n\n            refresh: function(quote)\n            {\n                if (!this.getTrialSubscriptions())\n                    return;\n\n                if (this.fetching())\n                    return;\n\n                var self = this;\n                this.fetching(true);\n\n                getTrialingSubscriptions(quote)\n                    .always(function()\n                    {\n                        self.fetching(false);\n                    })\n                    .done(function (subscriptions)\n                    {\n                        try {\n                            var data = JSON.parse(subscriptions);\n                            window.checkoutConfig.payment.stripe_payments.trialingSubscriptions = data;\n                            self.trialingSubscriptions(data);\n                        } catch (e) {\n                            console.warn('Could not retrieve trial subscriptions: ' + e.message);\n                            self.trialingSubscriptions(window.checkoutConfig.payment.stripe_payments.trialingSubscriptions);\n                        }\n                    })\n                    .fail(function (xhr, textStatus, errorThrown)\n                    {\n                        console.warn(console.warn('Could not retrieve trial subscriptions: ' + xhr.responseText));\n                    });\n            },\n\n            discountTitle: function()\n            {\n                return $t('Trial Discount');\n            },\n\n            shippingTitle: function()\n            {\n                return $t('Trial Shipping');\n            },\n\n            taxTitle: function()\n            {\n                return $t('Trial Tax');\n            },\n\n            getAmount: function(key)\n            {\n                var config = this.trialingSubscriptions();\n\n                if (config == null)\n                    return 0;\n\n                if ((key in config) && !isNaN(config[key]))\n                    return config[key];\n\n                return 0;\n            },\n\n            getPureValue: function()\n            {\n                var price = this.getAmount('discount_total') -\n                            this.getAmount('subscriptions_total') -\n                            this.getAmount('shipping_total') -\n                            this.getAmount('tax_total') +\n                            this.getAmount('tax_inclusive');\n\n                return Math.round(price * 10000) / 10000;\n            },\n\n            getBasePureValue: function()\n            {\n                var price = this.getAmount('base_discount_total') -\n                            this.getAmount('base_subscriptions_total') -\n                            this.getAmount('base_shipping_total') -\n                            this.getAmount('base_tax_total') +\n                            this.getAmount('base_tax_inclusive');\n\n                return Math.round(price * 10000) / 10000;\n            },\n\n            getTaxAmount: function()\n            {\n                return this.getAmount('tax_total');\n            },\n\n            config: function()\n            {\n                return window.checkoutConfig.payment.stripe_payments;\n            }\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/checkout/cart/totals/initial_fee.js":"define(\n    [\n        'StripeIntegration_Payments/js/view/checkout/summary/initial_fee'\n    ],\n    function (Component) {\n        'use strict';\n\n        return Component.extend(\n        {\n            isDisplayed: function ()\n            {\n                return this.getPureValue() !== 0;\n            }\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/checkout/summary/prorations.js":"define(\n    [\n        'ko',\n        'mage/translate',\n        'Magento_Checkout/js/view/summary/abstract-total',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Catalog/js/price-utils',\n        'Magento_Checkout/js/model/totals',\n        'StripeIntegration_Payments/js/helper/subscriptions',\n        'StripeIntegration_Payments/js/model/upcomingInvoice'\n    ],\n    function (\n        ko,\n        $t,\n        Component,\n        quote,\n        priceUtils,\n        totals,\n        subscriptions,\n        upcomingInvoice\n    ) {\n        \"use strict\";\n\n        return Component.extend({\n            defaults: {\n                template: 'StripeIntegration_Payments/checkout/summary/prorations'\n            },\n            totals: quote.getTotals(),\n            prorationAdjustment: ko.observable(0),\n            baseProrationAdjustment: ko.observable(0),\n\n            initialize: function()\n            {\n                this._super();\n                upcomingInvoice.initialize();\n                upcomingInvoice.onChange(this.onUpcomingInvoiceChanged.bind(this));\n            },\n\n            isDisplayed: function()\n            {\n                return subscriptions.isSubscriptionUpdate() && this.isFullMode() && this.getPureValue() !== 0;\n            },\n\n            getValue: function()\n            {\n                var price = this.getPureValue();\n                return this.getFormattedPrice(price);\n            },\n\n            getPureValue: function()\n            {\n                var price = 0;\n                if (subscriptions.isSubscriptionUpdate() && this.prorationAdjustment()) {\n                    price = this.prorationAdjustment();\n                }\n                return price;\n            },\n\n            getBasePureValue: function()\n            {\n                var price = 0;\n                if (subscriptions.isSubscriptionUpdate() && this.baseProrationAdjustment()) {\n                    price = this.baseProrationAdjustment();\n                }\n                return price;\n            },\n\n            onUpcomingInvoiceChanged: function(result, outcome, response)\n            {\n                try\n                {\n                    var params = JSON.parse(result);\n\n                    if (params && params.error)\n                    {\n                        return;\n                    }\n\n                    if (!params || !params.upcomingInvoice)\n                        return;\n\n                    if (!isNaN(params.upcomingInvoice.proration_adjustment))\n                    {\n                        this.prorationAdjustment(params.upcomingInvoice.proration_adjustment);\n                    }\n\n                    if (!isNaN(params.upcomingInvoice.base_proration_adjustment))\n                    {\n                        this.baseProrationAdjustment(params.upcomingInvoice.base_proration_adjustment);\n                    }\n                }\n                catch (e)\n                {\n                    console.warn(\"Could not calculate sidebar proration amount\");\n                    console.warn(e);\n                }\n            },\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/checkout/summary/initial_fee.js":"define(\n    [\n        'Magento_Checkout/js/view/summary/abstract-total',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Catalog/js/price-utils',\n        'Magento_Checkout/js/model/totals'\n    ],\n    function (Component, quote, priceUtils, totals) {\n        \"use strict\";\n        return Component.extend({\n            defaults: {\n                isFullTaxSummaryDisplayed: window.checkoutConfig.isFullTaxSummaryDisplayed || false,\n                template: 'StripeIntegration_Payments/checkout/summary/initial_fee'\n            },\n            totals: quote.getTotals(),\n            isTaxDisplayedInGrandTotal: window.checkoutConfig.includeTaxInGrandTotal || false,\n\n            isDisplayed: function() {\n                return this.isFullMode() && this.getPureValue() !== 0;\n            },\n\n            getValue: function() {\n                var price = 0;\n                if (this.totals() && totals.getSegment('initial_fee')) {\n                    price = totals.getSegment('initial_fee').value;\n                }\n                return this.getFormattedPrice(price);\n            },\n            getPureValue: function() {\n                var price = 0;\n                if (this.totals() && totals.getSegment('initial_fee')) {\n                    price = totals.getSegment('initial_fee').value;\n                }\n                return price;\n            }\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/payment/stripe_payments.js":"define(\n    [\n        'uiComponent',\n        'Magento_Checkout/js/model/payment/renderer-list',\n        'Magento_Checkout/js/model/payment/method-group',\n        'StripeIntegration_Payments/js/helper/subscriptions'\n    ],\n    function (\n        Component,\n        rendererList,\n        methodGroup,\n        subscriptions\n    ) {\n        'use strict';\n\n        var subscriptionUpdateComponent = null;\n        if (subscriptions.isSubscriptionUpdate())\n        {\n            subscriptionUpdateComponent = 'StripeIntegration_Payments/js/view/subscription_update/review';\n        }\n\n        rendererList.push(\n            {\n                type: 'stripe_payments',\n                component: subscriptionUpdateComponent || 'StripeIntegration_Payments/js/view/payment/method-renderer/stripe_payments'\n            },\n            {\n                type: 'stripe_payments_checkout',\n                component: subscriptionUpdateComponent || 'StripeIntegration_Payments/js/view/payment/method-renderer/checkout'\n            },\n            {\n                type: 'stripe_payments_bank_transfers',\n                component: subscriptionUpdateComponent || 'StripeIntegration_Payments/js/view/payment/method-renderer/bank_transfers'\n            }\n        );\n\n        // Add view logic here if needed\n        return Component.extend({});\n    }\n);\n","StripeIntegration_Payments/js/view/payment/express_checkout.js":"// This file can only be loaded at the checkout page because it injects Magento_Checkout/js/model/quote\ndefine(\n    [\n        'jquery',\n        'uiComponent',\n        'StripeIntegration_Payments/js/helper/subscriptions',\n        'stripe_payments_express',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Ui/js/model/messageList'\n    ],\n    function (\n        $,\n        Component,\n        subscriptions,\n        stripeExpress,\n        quote,\n        globalMessageList\n    ) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                // template: 'StripeIntegration_Payments/payment/express_checkout',\n                stripePaymentsShowExpressCheckoutSection: false,\n                isECErendered: false\n            },\n\n            initObservable: function ()\n            {\n                this._super()\n                    .observe([\n                        'stripePaymentsShowExpressCheckoutSection',\n                        'isExpressCheckoutElementSupported'\n                    ]);\n\n                if (subscriptions.isSubscriptionUpdate())\n                    return this;\n\n                var self = this;\n                var currentTotals = quote.totals();\n\n                quote.totals.subscribe(function (totals)\n                {\n                    if (JSON.stringify(totals.total_segments) == JSON.stringify(currentTotals.total_segments))\n                        return;\n\n                    currentTotals = totals;\n\n                    if (!self.isECErendered)\n                        return;\n\n                    self.initECE();\n                }, this);\n\n                quote.paymentMethod.subscribe(function(method)\n                {\n                    if (method != null)\n                    {\n                        $(\".payment-method.stripe-payments.mobile\").removeClass(\"_active\");\n                    }\n                }, null, 'change');\n\n                return this;\n            },\n\n            initECE: function()\n            {\n                if (!this.config().enabled)\n                    return;\n\n                var self = this;\n                var params = self.config().initParams;\n                var payload = {\n                    location: 'checkout'\n                };\n                stripeExpress.initStripeExpress('#payment-request-button', params, payload, self.config().buttonConfig,\n                    function () {\n                        self.isExpressCheckoutElementSupported(true);\n                        self.stripePaymentsShowExpressCheckoutSection(true);\n                        stripeExpress.initCheckoutWidget(self.validate.bind(self));\n                        self.isECErendered = true;\n                    }\n                );\n            },\n\n            config: function()\n            {\n                return window.checkoutConfig.payment.express_checkout;\n            },\n\n            validate: function()\n            {\n                var agreementsConfig = window.checkoutConfig ? window.checkoutConfig.checkoutAgreements : {},\n                    agreementsInputPath = '.payment-method.stripe-payments.mobile div.checkout-agreements input';\n                var isValid = true;\n\n                if (!agreementsConfig.isEnabled || $(agreementsInputPath).length === 0) {\n                    return true;\n                }\n\n                $(agreementsInputPath).each(function (index, element)\n                {\n                    if (!$.validator.validateSingleElement(element, {\n                        errorElement: 'div',\n                        hideError: false\n                    })) {\n                        isValid = false;\n                    }\n                });\n\n                return isValid;\n            },\n\n            showError: function(message)\n            {\n                document.getElementById('checkout').scrollIntoView(true);\n                globalMessageList.addErrorMessage({ \"message\": message });\n            }\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/payment/method-renderer/stripe_payments.js":"define(\n    [\n        'ko',\n        'Magento_Checkout/js/view/payment/default',\n        'Magento_Ui/js/model/messageList',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Customer/js/model/customer',\n        'StripeIntegration_Payments/js/action/post-update-cart',\n        'StripeIntegration_Payments/js/action/post-restore-quote',\n        'StripeIntegration_Payments/js/action/post-cancel-order',\n        'StripeIntegration_Payments/js/action/get-requires-action',\n        'StripeIntegration_Payments/js/view/checkout/trialing_subscriptions',\n        'StripeIntegration_Payments/js/stripe',\n        'stripe_payments_express',\n        'mage/translate',\n        'mage/url',\n        'jquery',\n        'Magento_Checkout/js/action/place-order',\n        'Magento_Checkout/js/model/payment/additional-validators',\n        'Magento_Checkout/js/action/redirect-on-success',\n        'mage/storage',\n        'mage/url',\n        'Magento_CheckoutAgreements/js/model/agreement-validator',\n        'Magento_Customer/js/customer-data',\n        'Magento_Checkout/js/model/payment-service'\n    ],\n    function (\n        ko,\n        Component,\n        globalMessageList,\n        quote,\n        customer,\n        updateCartAction,\n        restoreQuoteAction,\n        cancelLastOrderAction,\n        getRequiresAction,\n        trialingSubscriptions,\n        stripe,\n        stripeExpress,\n        $t,\n        url,\n        $,\n        placeOrderAction,\n        additionalValidators,\n        redirectOnSuccessAction,\n        storage,\n        urlBuilder,\n        agreementValidator,\n        customerData,\n        paymentService\n    ) {\n        'use strict';\n\n        return Component.extend({\n            externalRedirectUrl: null,\n            defaults: {\n                template: 'StripeIntegration_Payments/payment/element',\n                stripePaymentsShowExpressCheckoutSection: false\n            },\n            redirectAfterPlaceOrder: false,\n            elements: null,\n            initParams: null,\n            paymentElement: null,\n            zeroDecimalCurrencies: ['BIF','CLP','DJF','GNF','JPY','KMF','KRW','MGA','PYG','RWF','UGX','VND','VUV','XAF','XOF','XPF'],\n            threeDecimalCurrencies: ['BHD','JOD','KWD','OMR','TND'],\n            selectedPaymentMethodCode: null,\n\n            initObservable: function ()\n            {\n                this._super()\n                    .observe([\n                        'paymentElement',\n                        'isPaymentFormComplete',\n                        'isPaymentFormVisible',\n                        'isLoading',\n                        'stripePaymentsError',\n                        'permanentError',\n                        'isOrderPlaced',\n                        'isInitializing',\n                        'isInitialized',\n                        'useQuoteBillingAddress',\n                        'cvcToken',\n                        'paymentElementPaymentMethod',\n\n                        // Saved payment methods dropdown\n                        'dropdownOptions',\n                        'selection',\n                        'isDropdownOpen'\n                    ]);\n\n                var self = this;\n\n                this.isPaymentFormVisible(false);\n                this.isOrderPlaced(false);\n                this.isInitializing(true);\n                this.isInitialized(false);\n                this.useQuoteBillingAddress(false);\n                this.cvcToken(null);\n                this.collectCvc = ko.computed(this.shouldCollectCvc.bind(this));\n                this.isAmex = ko.computed(this.isAmexSelected.bind(this));\n                this.cardCvcElement = null;\n\n                var currentTotals = quote.totals();\n                var currentShippingAddress = quote.shippingAddress();\n                var currentBillingAddress = quote.billingAddress();\n\n                quote.totals.subscribe(function (totals)\n                {\n                    if (!totals || !totals.grand_total || !totals.quote_currency_code)\n                    {\n                        return;\n                    }\n\n                    if (!currentTotals || !currentTotals.grand_total || !currentTotals.quote_currency_code)\n                    {\n                        currentTotals = totals;\n                        return;\n                    }\n\n                    var amount1 = totals.grand_total;\n                    var amount2 = currentTotals.grand_total;\n                    var currency1 = totals.quote_currency_code;\n                    var currency2 = currentTotals.quote_currency_code;\n\n                    if (amount1 === amount2 && currency1 === currency2)\n                    {\n                        return;\n                    }\n\n                    currentTotals = totals;\n\n                    self.onQuoteTotalsChanged.bind(self)();\n                    self.isOrderPlaced(false);\n                }, this);\n\n                quote.paymentMethod.subscribe(function (method)\n                {\n                    if (method && method.method == this.getCode() && !this.isInitializing())\n                    {\n                        // We intentionally re-create the element because its container element may have changed\n                        this.initPaymentForm();\n                    }\n                }, this);\n\n                quote.billingAddress.subscribe(function(address)\n                {\n                    if (address && self.paymentElement && self.paymentElement.update && !self.isPaymentFormComplete())\n                    {\n                        // Remove the postcode & country fields if a billing address has been specified\n                        self.paymentElement.update(self.getPaymentElementUpdateOptions());\n                    }\n                });\n\n                return this;\n            },\n\n            initSavedPaymentMethods: function()\n            {\n                // If it is already initialized, do not re-initialize\n                if (this.dropdownOptions())\n                {\n                    return;\n                }\n\n                var options = [];\n                var methods = this.getStripeParam(\"savedMethods\");\n                if (methods)\n                {\n                    for (var i in methods)\n                    {\n                        if (methods.hasOwnProperty(i))\n                        {\n                            // We do this because some themes and libraries extend all objects with their own methods\n                            options.push(methods[i]);\n                        }\n                    }\n                }\n\n                if (options.length > 0)\n                {\n                    this.isPaymentFormVisible(false);\n                    this.selection(options[0]);\n                }\n                else\n                {\n                    this.isPaymentFormVisible(true);\n                    this.selection(false);\n                }\n\n                this.dropdownOptions(options);\n            },\n\n            shouldCollectCvc: function()\n            {\n                var selection = this.selection();\n\n                if (!selection)\n                    return false;\n\n                if (selection.type != 'card')\n                    return false;\n\n                return !!selection.cvc;\n            },\n\n            isAmexSelected: function()\n            {\n                var selection = this.selection();\n\n                if (!selection)\n                    return false;\n\n                if (selection.type != 'card')\n                    return false;\n\n                return (selection.brand == \"amex\");\n            },\n\n            newPaymentMethod: function()\n            {\n                this.messageContainer.clear();\n\n                this.selection({\n                    type: 'new',\n                    value: 'new',\n                    icon: false,\n                    label: $t('New payment method')\n                });\n                this.isDropdownOpen(false);\n                this.isPaymentFormVisible(true);\n                if (!this.isInitialized())\n                {\n                    this.onContainerRendered();\n                    this.isInitialized(true);\n                }\n            },\n\n            getPaymentMethodId: function()\n            {\n                if (this.isExternalPaymentMethodCode(this.selectedPaymentMethodCode))\n                {\n                    return this.selectedPaymentMethodCode;\n                }\n\n                var selection = this.selection();\n\n                if (selection && typeof selection.value != \"undefined\" && selection.value != \"new\")\n                {\n                    return selection.value;\n                }\n\n                var paymentMethod = this.paymentElementPaymentMethod();\n                if (paymentMethod && paymentMethod.id)\n                {\n                    return paymentMethod.id;\n                }\n\n                return null;\n            },\n\n            toggleDropdown: function()\n            {\n                this.isDropdownOpen(!this.isDropdownOpen());\n            },\n\n            getStripeParam: function(param)\n            {\n                var params = this.getInitParams();\n\n                if (!params)\n                {\n                    return null;\n                }\n\n                if (typeof params[param] != \"undefined\")\n                {\n                    return params[param];\n                }\n\n                return null;\n            },\n\n            onQuoteTotalsChanged: function()\n            {\n                if (!this.elements || !this.elements.update)\n                {\n                    return;\n                }\n\n                try\n                {\n                    this.elements.update(this.getElementsOptions(true));\n                }\n                catch (e)\n                {\n                    this.elements.update(this.getElementsOptions(false));\n                }\n            },\n\n            getInitParams: function()\n            {\n                return window.checkoutConfig.payment.stripe_payments.initParams;\n            },\n\n            isWalletEnabled: function(walletName)\n            {\n                if (window.checkoutConfig &&\n                    window.checkoutConfig.payment &&\n                    window.checkoutConfig.payment.express_checkout &&\n                    window.checkoutConfig.payment.express_checkout.buttonConfig &&\n                    window.checkoutConfig.payment.express_checkout.buttonConfig.paymentMethods &&\n                    window.checkoutConfig.payment.express_checkout.buttonConfig.paymentMethods[walletName]\n                )\n                {\n                    var value = window.checkoutConfig.payment.express_checkout.buttonConfig.paymentMethods[walletName];\n                    return (value == \"always\" || value == \"auto\");\n                }\n\n                return false;\n            },\n\n            onPaymentElementContainerRendered: function()\n            {\n                var self = this;\n                this.isLoading(true);\n                stripe.initStripe(this.getInitParams(), function(err)\n                {\n                    if (err)\n                        return self.crash(err);\n\n                    self.initSavedPaymentMethods();\n                    self.initPaymentForm();\n                });\n            },\n\n            onContainerRendered: function()\n            {\n                this.onPaymentElementContainerRendered();\n            },\n\n            getCardCVCOptions: function()\n            {\n                return {\n                  style: {\n                    base: {\n                  //     iconColor: '#c4f0ff',\n                  //     color: '#fff',\n                  //     fontWeight: '500',\n                  //     fontFamily: 'Roboto, Open Sans, Segoe UI, sans-serif',\n                      fontSize: '16px',\n                  //     fontSmoothing: 'antialiased',\n                  //     ':-webkit-autofill': {\n                  //       color: '#fce883',\n                  //     },\n                  //     '::placeholder': {\n                  //       color: '#87BBFD',\n                  //     },\n                  //   },\n                  //   invalid: {\n                  //     iconColor: '#FFC7EE',\n                  //     color: '#FFC7EE',\n                    },\n                  },\n                };\n            },\n\n            onCvcContainerRendered: function()\n            {\n                var self = this;\n                var params = this.getInitParams();\n\n                stripe.initStripe(params, function(err)\n                {\n                    if (err)\n                        return self.crash(err);\n\n                    var options = {};\n                    if (params && params.locale)\n                    {\n                        options.locale = params.locale;\n                    }\n\n                    try\n                    {\n                        var elements = stripe.stripeJs.elements(options);\n                        self.cardCvcElement = elements.create('cardCvc', self.getCardCVCOptions());\n                        self.cardCvcElement.mount('#stripe-card-cvc-element');\n                        self.cardCvcElement.on('change', self.onCvcChange.bind(self));\n                        self.cardCvcElement.on('loaderror', self.onLoadError.bind(self));\n                    }\n                    catch (e)\n                    {\n                        this.crash(e.message);\n                    }\n                });\n            },\n\n            onCvcChange: function(event)\n            {\n                if (event.error)\n                    this.selection().cvcError = event.error.message;\n                else\n                    this.selection().cvcError = null;\n            },\n\n            crash: function(message)\n            {\n                this.isLoading(false);\n                var userError = this.getStripeParam(\"userError\");\n                if (userError)\n                    this.permanentError(userError);\n                else\n                    this.permanentError($t(\"Sorry, this payment method is not available. Please contact us for assistance.\"));\n\n                console.error(\"Error: \", message);\n            },\n\n            softCrash: function(message)\n            {\n                var userError = this.getStripeParam(\"userError\");\n                if (userError)\n                    this.showError(userError);\n                else\n                    this.showError($t(\"Sorry, this payment method is not available. Please contact us for assistance.\"));\n\n                console.error(\"Error: \", message);\n            },\n\n            isCollapsed: function()\n            {\n                if (this.isChecked() == this.getCode())\n                {\n                    return false;\n                }\n                else\n                {\n                    return true;\n                }\n            },\n\n            initPaymentForm: function()\n            {\n                this.isInitializing(false);\n                this.isLoading(false);\n\n                if (this.isCollapsed()) // Don't render PE with a height of 0\n                    return;\n\n                if (document.getElementById('stripe-payment-element') === null)\n                    return this.crash(\"Cannot initialize Payment Element on a DOM that does not contain a div.stripe-payment-element.\");\n\n                if (!stripe.stripeJs)\n                    return this.crash(\"Stripe.js could not be initialized.\");\n\n                if (this.getStripeParam(\"isOrderPlaced\"))\n                    this.isOrderPlaced(true);\n\n                try\n                {\n                    try\n                    {\n                        this.elements = stripe.stripeJs.elements(this.getElementsOptions(true));\n                    }\n                    catch (e)\n                    {\n                        console.warn(\"Could not filter Stripe payment method types: \" + e.message);\n                        this.elements = stripe.stripeJs.elements(this.getElementsOptions(false));\n                    }\n                    this.paymentElement = this.elements.create('payment', this.getPaymentElementOptions());\n                    this.paymentElement.mount('#stripe-payment-element');\n                    this.paymentElement.on('change', this.onChange.bind(this));\n                    this.paymentElement.on('loaderror', this.onLoadError.bind(this));\n                }\n                catch (e)\n                {\n                    this.crash(e.message);\n                }\n            },\n\n            onLoadError: function(event)\n            {\n                if (event && event.error && event.error.message)\n                {\n                    this.permanentError(event.error.message);\n                }\n                else\n                {\n                    this.crash(event);\n                }\n            },\n\n            shouldHideRedirectBasedPaymentMethods: function()\n            {\n                var totals = quote.totals();\n                if (!totals || !totals.total_segments || !totals.total_segments.length)\n                {\n                    return false;\n                }\n\n                var targetSegments = [\"giftcardaccount\", \"customerbalance\", \"reward\"];\n\n                for (var i = 0; i < totals.total_segments.length; i++)\n                {\n                    var segment = totals.total_segments[i];\n                    if (targetSegments.indexOf(segment.code) >= 0 && !isNaN(segment.value) && segment.value != 0)\n                    {\n                        return true;\n                    }\n                }\n\n                return false;\n            },\n\n            getElementsOptions: function(filterPaymentMethods)\n            {\n                var options = Object.assign({}, window.checkoutConfig.payment.stripe_payments.elementOptions);\n\n                if (this.shouldHideRedirectBasedPaymentMethods())\n                {\n                    options.paymentMethodTypes = ['card'];\n\n                    if (this.isWalletEnabled(\"link\"))\n                    {\n                        options.paymentMethodTypes.push('link');\n                    }\n                }\n                else if (options.paymentMethodTypes)\n                {\n                    // Case where paymentMethodOptions were passed from the server side\n                }\n                else\n                {\n                    // Unset any previously set paymentMethodTypes in case a gift card was removed etc\n                    options.paymentMethodTypes = null;\n                }\n\n                if (!filterPaymentMethods && options.paymentMethodTypes)\n                    delete options.paymentMethodTypes;\n\n                if (options.mode != \"setup\")\n                {\n                    options.amount = this.getElementsAmount();\n                }\n\n                var externalPaymentMethods = this.getExternalPaymentMethods();\n                if (externalPaymentMethods)\n                {\n                    options.externalPaymentMethodTypes = externalPaymentMethods.map(function(method)\n                    {\n                        return method.code;\n                    });\n                }\n\n                return options;\n            },\n\n            getExternalPaymentMethods: function()\n            {\n                var initParams = this.getInitParams();\n\n                if (initParams &&\n                    initParams.externalPaymentMethods &&\n                    initParams.externalPaymentMethods.length > 0 &&\n                    initParams.externalPaymentMethods[0].code &&\n                    initParams.externalPaymentMethods[0].redirect_url\n                )\n                {\n                    return initParams.externalPaymentMethods;\n                }\n\n                return null;\n            },\n\n            getPaymentElementOptions: function()\n            {\n                var options = {};\n\n                var params = this.getInitParams();\n                if (params)\n                {\n                    if (params.wallets)\n                        options.wallets = params.wallets;\n\n                    if (params.layout)\n                        options.layout = params.layout;\n\n                    if (params.terms)\n                        options.terms = params.terms;\n                }\n\n                var billingAddress = quote.billingAddress();\n\n                if (billingAddress)\n                {\n                    try\n                    {\n                        this.useQuoteBillingAddress(true);\n\n                        var hasState = (billingAddress.region || billingAddress.regionCode || billingAddress.regionId);\n\n                        options.fields = {\n                            billingDetails: {\n                                name: 'never',\n                                email: 'never',\n                                phone: (billingAddress.telephone ? 'never' : 'auto'),\n                                address: {\n                                    line1: ((billingAddress.street.length > 0) ? 'never' : 'auto'),\n                                    line2: ((billingAddress.street.length > 0) ? 'never' : 'auto'),\n                                    city: billingAddress.city ? 'never' : 'auto',\n                                    state: hasState ? 'never' : 'auto',\n                                    country: billingAddress.countryId ? 'never' : 'auto',\n                                    postalCode: billingAddress.postcode ? 'never' : 'auto'\n                                }\n                            }\n                        };\n                    }\n                    catch (e)\n                    {\n                        this.useQuoteBillingAddress(false);\n\n                        options.fields = {};\n                        console.warn('Could not retrieve billing address: '  + e.message);\n                    }\n\n                    // Set the default billing address in order to enable the Link payment method\n                    var billingDetails = this.getBillingDetails();\n\n                    if (billingDetails)\n                    {\n                        options.defaultValues = {\n                            billingDetails: billingDetails\n                        };\n                    }\n                }\n                else\n                {\n                    this.useQuoteBillingAddress(false);\n                }\n\n                return options;\n            },\n\n            getPaymentElementUpdateOptions: function()\n            {\n                var options = this.getPaymentElementOptions();\n\n                if (options.wallets)\n                {\n                    delete options.wallets;\n                }\n\n                return options;\n            },\n\n            onChange: function(event)\n            {\n                this.isLoading(false);\n                this.isPaymentFormComplete(event.complete);\n\n                if (event.value && event.value.type)\n                {\n                    this.selectedPaymentMethodCode = event.value.type;\n                }\n                else\n                {\n                    this.selectedPaymentMethodCode = null;\n                }\n            },\n\n            isExternalPaymentMethodCode: function(code)\n            {\n                var methods = this.getExternalPaymentMethods();\n                if (!methods)\n                    return false;\n\n                for (var i = 0; i < methods.length; i++)\n                {\n                    if (methods[i].code == code)\n                        return true;\n                }\n\n                return false;\n            },\n\n            getExternalPaymentMethodRedirectUrl: function(code)\n            {\n                var methods = this.getExternalPaymentMethods();\n                if (!methods)\n                    return null;\n\n                for (var i = 0; i < methods.length; i++)\n                {\n                    if (methods[i].code == code)\n                        return methods[i].redirect_url;\n                }\n\n                return null;\n            },\n\n            getElementsAmount: function()\n            {\n                var totals = quote.totals();\n\n                if (totals && totals.grand_total)\n                {\n                    // If total_segments includes a grand_total, we use that instead\n                    if (totals.total_segments && totals.total_segments.length > 0)\n                    {\n                        for (var i = 0; i < totals.total_segments.length; i++)\n                        {\n                            var segment = totals.total_segments[i];\n                            if (segment.code == \"grand_total\")\n                            {\n                                return this.convertToStripeAmount(segment.value, this.getElementsCurrency());\n                            }\n                        }\n                    }\n\n                    // Othewise use the quote grand total\n                    var amount = totals.grand_total;\n                    return this.convertToStripeAmount(amount, this.getElementsCurrency());\n                }\n\n                return 0;\n            },\n\n            getElementsCurrency: function()\n            {\n                var totals = quote.totals();\n                if (totals && totals.quote_currency_code)\n                {\n                    var currency = totals.quote_currency_code;\n                    return currency.toLowerCase();\n                }\n\n                return 'USD';\n            },\n\n            isBillingAddressSet: function()\n            {\n                return quote.billingAddress() && quote.billingAddress().canUseForBilling();\n            },\n\n            convertToStripeAmount: function(amount, currencyCode)\n            {\n                var code = currencyCode.toUpperCase();\n\n                if (this.zeroDecimalCurrencies.indexOf(code) >= 0)\n                {\n                    return Math.round(amount);\n                }\n                else if (this.threeDecimalCurrencies.indexOf(code) >= 0)\n                {\n                    return Math.round(amount * 100) * 10;\n                }\n                else\n                {\n                    return Math.round(amount * 100);\n                }\n            },\n\n            isPlaceOrderEnabled: function()\n            {\n                if (this.stripePaymentsError())\n                    return false;\n\n                if (this.permanentError())\n                    return false;\n\n                return this.isBillingAddressSet();\n            },\n\n            getAddressField: function(field)\n            {\n                if (!quote.billingAddress())\n                    return null;\n\n                var address = quote.billingAddress();\n\n                if (!address[field] || address[field].length == 0)\n                    return null;\n\n                return address[field];\n            },\n\n            getBillingDetails: function()\n            {\n                var details = {};\n                var address = {};\n\n                if (this.getAddressField('city'))\n                    address.city = this.getAddressField('city');\n\n                if (this.getAddressField('countryId'))\n                    address.country = this.getAddressField('countryId');\n\n                if (this.getAddressField('postcode'))\n                    address.postal_code = this.getAddressField('postcode');\n\n                if (this.getAddressField('region'))\n                    address.state = this.getAddressField('region');\n\n                if (this.getAddressField('street'))\n                {\n                    var street = this.getAddressField('street');\n                    address.line1 = street[0];\n\n                    if (street.length > 1)\n                        address.line2 = street[1];\n                }\n\n                if (Object.keys(address).length > 0)\n                    details.address = address;\n\n                if (this.getAddressField('telephone'))\n                    details.phone = this.getAddressField('telephone');\n\n                if (this.getAddressField('firstname'))\n                    details.name = this.getAddressField('firstname') + ' ' + this.getAddressField('lastname');\n\n                if (quote.guestEmail)\n                    details.email = quote.guestEmail;\n                else if (customerData.email)\n                    details.email = customerData.email;\n\n                if (Object.keys(details).length > 0)\n                    return details;\n\n                return null;\n            },\n\n            config: function()\n            {\n                return window.checkoutConfig.payment[this.getCode()];\n            },\n\n            isActive: function(parents)\n            {\n                return true;\n            },\n\n            placeOrder: function()\n            {\n                this.messageContainer.clear();\n\n                if (!this.isPaymentFormComplete() && !this.getPaymentMethodId())\n                    return this.showError($t('Please complete your payment details.'));\n\n                if (!this.validate())\n                    return;\n\n                this.clearErrors();\n                this.isPlaceOrderActionAllowed(false);\n                this.isLoading(true);\n                this.cvcToken(null);\n\n                var params = { };\n\n                if (this.useQuoteBillingAddress())\n                {\n                    params.payment_method_data = {\n                        billing_details: {\n                            address: this.getStripeFormattedAddress(quote.billingAddress()),\n                            email: this.getBillingEmail(),\n                            name: this.getNameFromAddress(quote.billingAddress()),\n                            phone: this.getBillingPhone()\n                        }\n                    };\n                }\n\n                if (this.hasShipping())\n                {\n                    params.shipping = {\n                        address: this.getStripeFormattedAddress(quote.shippingAddress()),\n                        name: this.getNameFromAddress(quote.shippingAddress())\n                    };\n                }\n\n                var self = this;\n\n                if (this.isSavedCardSelected() && this.selection().cvc)\n                {\n                    stripe.stripeJs.createToken('cvc_update', this.cardCvcElement).then(function(result)\n                    {\n                        if (result.error)\n                        {\n                            self.showError(result.error.message);\n                        }\n                        else if (result.token)\n                        {\n                            self.cvcToken(result.token.id);\n                            self.placeOrderWithSavedPaymentMethod.bind(self)();\n                        }\n                        else\n                        {\n                            self.showError('Could not perform CVC check.');\n                        }\n                    });\n                }\n                else if (this.isSavedPaymentMethodSelected())\n                {\n                    this.placeOrderWithSavedPaymentMethod();\n                }\n                else if (this.isExternalPaymentMethodCode(this.selectedPaymentMethodCode))\n                {\n                    this.onPaymentMethodCreatedForOrderPlacement();\n                }\n                else\n                {\n                    this.createPaymentMethod(this.onPaymentMethodCreatedForOrderPlacement.bind(this));\n                }\n\n                return false;\n            },\n\n            hasShipping: function()\n            {\n                return (quote && quote.shippingMethod() && quote.shippingMethod().method_code);\n            },\n\n            createPaymentMethod: function(callback)\n            {\n                this.paymentElementPaymentMethod(null);\n\n                var self = this;\n\n                var paymentMethodData = {\n                    elements: this.elements,\n                    params: {}\n                };\n\n                var confirmParams = this.getConfirmParams();\n                var billingDetails = null;\n                if (confirmParams &&\n                    confirmParams.confirmParams &&\n                    confirmParams.confirmParams.payment_method_data &&\n                    confirmParams.confirmParams.payment_method_data.billing_details\n                )\n                {\n                    billingDetails = confirmParams.confirmParams.payment_method_data.billing_details;\n                }\n\n                if (billingDetails)\n                {\n                    paymentMethodData.params.billing_details = confirmParams.confirmParams.payment_method_data.billing_details;\n                }\n                else\n                {\n                    return this.showError($t(\"Please specify a billing address.\"));\n                }\n\n                setTimeout(function(){\n                    // The loading mask is disabled so that the MFTF tests can continue running\n                    self.isLoading(false);\n                }, 4000);\n                this.elements.submit().then(function()\n                {\n                    stripe.stripeJs.createPaymentMethod(paymentMethodData).then(function(result)\n                    {\n                        if (result.error)\n                        {\n                            self.showError(result.error.message);\n                            console.error(result.error.message);\n                        }\n                        else\n                        {\n                            self.paymentElementPaymentMethod(result.paymentMethod);\n                            callback(result.paymentMethod);\n                        }\n                    });\n                },\n                function(result)\n                {\n                    if (result.error)\n                    {\n                        self.showError(result.error.message);\n                        console.error(result.error.message);\n                    }\n                    else\n                    {\n                        self.showError(\"A payment submission error has occurred.\");\n                        console.error(result);\n                    }\n                });\n            },\n\n            isSavedPaymentMethodSelected: function()\n            {\n                var selectedMethodType = this.getSelectedMethod(\"type\");\n\n                if (!selectedMethodType) // There is no saved PMs dropdown\n                    return false;\n\n                if (selectedMethodType != 'new') // A saved PMs is selected\n                    return true;\n\n                return false; // New PM is selected\n            },\n\n            isSavedCardSelected: function()\n            {\n                var selectedMethodType = this.getSelectedMethod(\"type\");\n\n                if (!selectedMethodType) // There is no saved PMs dropdown\n                    return false;\n\n                if (selectedMethodType == 'card') // A saved PMs is selected\n                    return true;\n\n                return false; // New PM is selected\n            },\n\n            placeOrderWithSavedPaymentMethod: function()\n            {\n                var self = this;\n                var placeNewOrder = this.placeNewOrder.bind(this);\n\n                if (this.isOrderPlaced()) // The order was already placed but either 3D Secure failed or the customer pressed the back button from an external payment page\n                {\n                    updateCartAction(this.getData(), this.onCartUpdated.bind(this));\n                }\n                else\n                {\n                    try\n                    {\n                        placeNewOrder();\n                    }\n                    catch (e)\n                    {\n                        this.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                        console.error(e.message);\n                    }\n                }\n            },\n\n            onPaymentMethodCreatedForOrderPlacement: function(paymentMethod)\n            {\n                var placeNewOrder = this.placeNewOrder.bind(this);\n                var self = this;\n\n                if (self.isOrderPlaced()) // The order was already placed but either 3D Secure failed or the customer pressed the back button from an external payment page\n                {\n                    updateCartAction(this.getData(), this.onCartUpdated.bind(this));\n                }\n                else\n                {\n                    try\n                    {\n                        placeNewOrder();\n                    }\n                    catch (e)\n                    {\n                        self.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                        console.error(e.message);\n                    }\n                }\n            },\n\n            onCartUpdated: function(result, outcome, response)\n            {\n                var placeNewOrder = this.placeNewOrder.bind(this);\n                var onOrderPlaced = this.onOrderPlaced.bind(this);\n                try\n                {\n                    var data = JSON.parse(result);\n                    if (data.error)\n                    {\n                        this.showError(data.error);\n                    }\n                    else if (data.redirect)\n                    {\n                        $.mage.redirect(data.redirect);\n                    }\n                    else if (data.placeNewOrder)\n                    {\n                        placeNewOrder();\n                    }\n                    else\n                    {\n                        onOrderPlaced();\n                    }\n                }\n                catch (e)\n                {\n                    this.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                    console.error(e.message);\n                }\n            },\n\n            placeNewOrder: function()\n            {\n                var self = this;\n\n                this.isLoading(false); // Needed for the terms and conditions checkbox\n                this.getPlaceOrderDeferredObject()\n                    .fail(this.handlePlaceOrderErrors.bind(this))\n                    .done(this.onOrderPlaced.bind(this))\n                    .always(function(response, status, xhr)\n                    {\n                        if (status != \"success\")\n                        {\n                            self.isLoading(false);\n                        }\n                    });\n            },\n\n            getSelectedMethod: function(param)\n            {\n                var selection = this.selection();\n                if (!selection)\n                    return null;\n\n                if (typeof selection[param] == \"undefined\")\n                    return null;\n\n                return selection[param];\n            },\n\n            // Called when:\n            // - A brand new order has just been placed\n            // - After updateCartAction() with placeNewOrder == false\n            onOrderPlaced: function(result, outcome, response)\n            {\n                if (!this.isOrderPlaced() && isNaN(result))\n                {\n                    return this.softCrash(\"The order was placed but the response from the server did not include a numeric order ID.\");\n                }\n                else\n                {\n                    this.isOrderPlaced(true);\n                }\n\n                this.isLoading(true);\n\n                if (this.isExternalPaymentMethodCode(this.selectedPaymentMethodCode))\n                {\n                    window.location.href = this.getExternalPaymentMethodRedirectUrl(this.selectedPaymentMethodCode);\n                    return;\n                }\n\n                var self = this;\n                var handleNextActions = this.handleNextActions.bind(this);\n                getRequiresAction(function(clientSecret)\n                {\n                    try\n                    {\n                        if (clientSecret && clientSecret.length)\n                        {\n                            stripe.authenticateCustomer(clientSecret, function(err)\n                            {\n                                if (err)\n                                    return self.showError(err);\n\n                                self.onConfirm.bind(self)();\n                            });\n                        }\n                        else\n                        {\n                            // No further actions are needed\n                            self.onConfirm(null);\n                        }\n                    }\n                    catch (e)\n                    {\n                        restoreQuoteAction();\n                        self.showError(\"The order was placed but we could not confirm if the payment was successful.\");\n                        console.error(e);\n                    }\n\n                })\n                .fail(function(result)\n                {\n                    restoreQuoteAction();\n                    self.showError(\"The order was placed but we could not confirm if the payment was successful.\");\n                    console.error(result);\n                });\n            },\n\n            isSuccessful: function(stripeObject)\n            {\n\n                if (stripeObject.status == \"requires_action\" &&\n                    stripeObject.next_action &&\n                    stripeObject.next_action.type &&\n                    stripeObject.next_action.type != \"use_stripe_sdk\"\n                )\n                {\n                    // This is the case for vouchers, where an offline payment is required\n                    return true;\n                }\n\n\n                return (['processing', 'requires_capture', 'succeeded'].indexOf(stripeObject.status) >= 0);\n            },\n\n            // Called when:\n            // - A brand new order has just been placed\n            // - After updateCartAction() with placeNewOrder == false\n            handleNextActions: function(stripeObject)\n            {\n                if (!this.isOrderPlaced())\n                {\n                    return this.softCrash(\"Cannot handleNextActions without placing the order first\");\n                }\n\n                var self = this;\n\n                if (this.isSuccessful(stripeObject))\n                {\n                    this.onConfirm(null);\n                }\n                else if (stripeObject.status == \"requires_action\")\n                {\n                    // Non-card based confirms may redirect the customer externally. We restore the quote just before it in case the\n                    // customer clicks the back button on the browser before authenticating the payment.\n                    restoreQuoteAction(function()\n                    {\n                        stripe.stripeJs.handleNextAction({\n                          clientSecret: stripeObject.client_secret\n                        }).then(self.onConfirm.bind(self));\n                    });\n                }\n                else if (stripeObject.status == \"requires_confirmation\")\n                {\n                    // This should only hit when a payment failed with a saved PM, and then the customer switched to PaymentElement to enter a new payment method\n                    restoreQuoteAction(function()\n                    {\n                        // We pass null because we do not want to update the PM. It has already been updated with stripe.updatePaymentIntent\n                        updateCartAction(self.getData(), self.onCartUpdated.bind(self));\n                    });\n                }\n                else if (stripeObject.status == \"requires_payment_method\")\n                {\n                    restoreQuoteAction(function()\n                    {\n                        updateCartAction(self.getData(), self.onCartUpdated.bind(self));\n                    });\n                }\n                else\n                {\n                    restoreQuoteAction(function()\n                    {\n                        self.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                        console.error(\"Could not finalize order bacause the payment intent is in status \" + stripeObject.status);\n                    });\n                }\n            },\n\n            getConfirmParams: function()\n            {\n                var params = {\n                    elements: this.elements,\n                    confirmParams: {\n                        return_url: this.getStripeParam(\"successUrl\")\n                    }\n                };\n\n                this.getPaymentElementOptions();\n                if (this.useQuoteBillingAddress())\n                {\n                    params.confirmParams.payment_method_data = {\n                        billing_details: {\n                            address: this.getStripeFormattedAddress(quote.billingAddress()),\n                            email: this.getBillingEmail(),\n                            name: this.getNameFromAddress(quote.billingAddress()),\n                            phone: this.getBillingPhone()\n                        }\n                    };\n                }\n\n                return params;\n            },\n\n            getStripeFormattedAddress: function(address)\n            {\n                var stripeAddress = {};\n\n                if (address.regionCode)\n                    stripeAddress.state = address.regionCode;\n                else\n                    stripeAddress.state = address.region ? address.region : null;\n\n                stripeAddress.postal_code = address.postcode ? address.postcode : null;\n                stripeAddress.country = address.countryId ? address.countryId : null;\n                stripeAddress.city = address.city ? address.city : null;\n\n                if (address.street && address.street.length > 0)\n                {\n                    stripeAddress.line1 = address.street[0];\n\n                    if (address.street.length > 1)\n                    {\n                        stripeAddress.line2 = address.street[1];\n                    }\n                    else\n                    {\n                        stripeAddress.line2 = null;\n                    }\n                }\n                else\n                {\n                    stripeAddress.line1 = null;\n                    stripeAddress.line2 = null;\n                }\n\n                return stripeAddress;\n            },\n\n            getBillingEmail: function()\n            {\n                if (quote.guestEmail)\n                {\n                    return quote.guestEmail;\n                }\n                else if (window.checkoutConfig.customerData && window.checkoutConfig.customerData.email)\n                {\n                    return window.checkoutConfig.customerData.email;\n                }\n\n                return null;\n            },\n\n            getNameFromAddress: function(address)\n            {\n                if (!address)\n                    return null;\n\n                var parts = [];\n                if (address.firstname)\n                    parts.push(address.firstname);\n\n                if (address.middlename)\n                    parts.push(address.middlename);\n\n                if (address.lastname)\n                    parts.push(address.lastname);\n\n                return parts.join(\" \");\n            },\n\n            getBillingPhone: function()\n            {\n                var billingAddress = quote.billingAddress();\n                if (!billingAddress)\n                    return null;\n\n                if (billingAddress.telephone)\n                    return billingAddress.telephone;\n\n                return null;\n            },\n\n            onConfirm: function(result)\n            {\n                if (result && result.error)\n                {\n                    this.showError(result.error.message);\n\n                    if (this.isOrderPlaced())\n                    {\n                        cancelLastOrderAction(result.error.message);\n                        this.isOrderPlaced(false);\n                    }\n                }\n                else\n                {\n                    customerData.invalidate(['cart']);\n                    // In the case of a 3DS, we redirect to stripe/payment/index so that the quote is de-activated\n                    var successUrl = this.getStripeParam(\"successUrl\");\n                    $.mage.redirect(successUrl);\n                }\n            },\n\n            /**\n             * @return {*}\n             */\n            getPlaceOrderDeferredObject: function()\n            {\n                return placeOrderAction(this.getData(), this.messageContainer);\n            },\n\n            getClientSecretFromResponse: function(response)\n            {\n                if (typeof response != \"string\")\n                {\n                    return null;\n                }\n\n                if (response.indexOf(\"Authentication Required: \") >= 0)\n                {\n                    return response.substring(\"Authentication Required: \".length);\n                }\n\n                return null;\n            },\n\n            handlePlaceOrderErrors: function (result)\n            {\n                if (result && result.responseJSON && result.responseJSON.message)\n                {\n                    var clientSecret = this.getClientSecretFromResponse(result.responseJSON.message);\n\n                    if (clientSecret)\n                    {\n                        var self = this;\n                        return stripe.authenticateCustomer(clientSecret, function(err)\n                        {\n                            if (err)\n                                return self.showError(err);\n\n                            self.placeNewOrder.bind(self)();\n                        });\n                    }\n                    else\n                    {\n                        this.showError(result.responseJSON.message);\n                    }\n                }\n                else\n                {\n                    this.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n\n                    if (result && result.responseText)\n                        console.error(result.responseText);\n                    else\n                        console.error(result);\n                }\n            },\n\n            showError: function(message)\n            {\n                this.isLoading(false);\n                this.isPlaceOrderEnabled(true);\n                this.messageContainer.addErrorMessage({ \"message\": message });\n            },\n\n            validate: function(elm)\n            {\n                return this.validateCvc() && agreementValidator.validate() && additionalValidators.validate();\n            },\n\n            validateCvc: function()\n            {\n                if (!this.selection())\n                    return true;\n\n                if (this.selection().type != \"card\")\n                    return true;\n\n                if (this.selection().cvc != 1)\n                    return true;\n\n                if (typeof this.selection().cvcError == \"undefined\")\n                {\n                    this.showError($t(\"Please enter your card's security code.\"));\n                    return false;\n                }\n                else if (!this.selection().cvcError)\n                {\n                    return true;\n                }\n                else\n                {\n                    this.showError(this.selection().cvcError);\n                    return false;\n                }\n\n                return true;\n            },\n\n            getCode: function()\n            {\n                return 'stripe_payments';\n            },\n\n            getData: function()\n            {\n                var data = {\n                    'method': this.item.method,\n                    'additional_data': {\n                        'payment_method': this.getPaymentMethodId()\n                    }\n                };\n\n                if (this.cvcToken())\n                {\n                    data.additional_data.cvc_token = this.cvcToken();\n                }\n\n                return data;\n            },\n\n            clearErrors: function()\n            {\n                this.stripePaymentsError(null);\n            }\n\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/payment/method-renderer/checkout.js":"/*browser:true*/\n/*global define*/\ndefine(\n    [\n        'ko',\n        'jquery',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Checkout/js/model/payment/additional-validators',\n        'Magento_Checkout/js/action/place-order',\n        'Magento_Checkout/js/model/full-screen-loader',\n        'Magento_Customer/js/customer-data',\n        'StripeIntegration_Payments/js/stripe',\n        'StripeIntegration_Payments/js/action/get-checkout-methods',\n        'StripeIntegration_Payments/js/action/get-checkout-session-id',\n        'Magento_Checkout/js/view/payment/default',\n        'mage/translate',\n        'stripejs',\n        'domReady!'\n    ],\n    function (\n        ko,\n        $,\n        quote,\n        additionalValidators,\n        placeOrderAction,\n        fullScreenLoader,\n        customerData,\n        stripe,\n        getCheckoutMethods,\n        getCheckoutSessionId,\n        Component,\n        $t\n    ) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                self: this,\n                template: 'StripeIntegration_Payments/payment/checkout',\n                code: \"stripe_checkout\",\n                customRedirect: true,\n                guestEmail: null,\n                methodIcons: ko.observableArray([])\n            },\n            redirectAfterPlaceOrder: false,\n\n            initObservable: function()\n            {\n                this._super().observe([\n                    'methodIcons',\n                    'permanentError'\n                ]);\n\n                var params = window.checkoutConfig.payment.stripe_payments.initParams;\n\n                stripe.initStripe(params);\n\n                var self = this;\n                var currentTotals = quote.totals();\n                var currentBillingAddress = quote.billingAddress();\n                var currentShippingAddress = quote.shippingAddress();\n                this.guestEmail = quote.guestEmail;\n\n                getCheckoutMethods(quote, self.setPaymentMethods.bind(self));\n\n                quote.billingAddress.subscribe(function(address)\n                {\n                    if (!address)\n                        return;\n\n                    if (self.isAddressSame(address, currentBillingAddress))\n                        return;\n\n                    currentBillingAddress = address;\n\n                    getCheckoutMethods(quote, self.setPaymentMethods.bind(self));\n                }, this);\n\n                quote.shippingAddress.subscribe(function(address)\n                {\n                    if (!address)\n                        return;\n\n                    if (self.isAddressSame(address, currentShippingAddress))\n                        return;\n\n                    currentShippingAddress = address;\n\n                    getCheckoutMethods(quote, self.setPaymentMethods.bind(self));\n                }, this);\n\n                quote.totals.subscribe(function (totals)\n                {\n                    if (JSON.stringify(totals.total_segments) == JSON.stringify(currentTotals.total_segments))\n                        return;\n\n                    currentTotals = totals;\n\n                    getCheckoutMethods(quote, self.setPaymentMethods.bind(self));\n                }, this);\n\n                return this;\n            },\n\n            isAddressSame: function(address1, address2)\n            {\n                var a = this.stringifyAddress(address1);\n                var b = this.stringifyAddress(address2);\n\n                return a == b;\n            },\n\n            stringifyAddress: function(address)\n            {\n                if (typeof address == \"undefined\" || !address)\n                    return null;\n\n                return JSON.stringify({\n                    \"countryId\": (typeof address.countryId != \"undefined\") ? address.countryId : \"\",\n                    \"region\": (typeof address.region != \"undefined\") ? address.region : \"\",\n                    \"city\": (typeof address.city != \"undefined\") ? address.city : \"\",\n                    \"postcode\": (typeof address.postcode != \"undefined\") ? address.postcode : \"\"\n                });\n            },\n\n            setPaymentMethods: function(response)\n            {\n                var methods = [];\n\n                if (typeof response == \"string\")\n                    response = JSON.parse(response);\n\n                if (typeof response.error != \"undefined\")\n                {\n                    this.permanentError(response.error);\n                }\n\n                if (typeof response.methods != \"undefined\" && response.methods.length > 0)\n                    methods = response.methods;\n\n                var icons = window.checkoutConfig.payment.stripe_payments.icons;\n                var self = this;\n\n                methods.forEach(function(method)\n                {\n                    if (self.hasPaymentMethod(icons, method))\n                        return;\n\n                    if (typeof window.checkoutConfig.payment.stripe_payments.pmIcons[method] != \"undefined\")\n                    {\n                        icons.push({\n                            \"code\": method,\n                            \"path\": window.checkoutConfig.payment.stripe_payments.pmIcons[method].icon,\n                            \"name\": window.checkoutConfig.payment.stripe_payments.pmIcons[method].name\n                        });\n                    }\n                    else if (method != \"card\")\n                    {\n                        icons.push({\n                            \"code\": method,\n                            \"path\": window.checkoutConfig.payment.stripe_payments.pmIcons.bank.icon,\n                            \"name\": self.methodName(method)\n                        });\n                    }\n                });\n\n                this.methodIcons(icons);\n            },\n\n            hasPaymentMethod: function(collection, code)\n            {\n                var exists = collection.filter(function (o)\n                {\n                  return o.hasOwnProperty(\"code\") && o.code == code;\n                }).length > 0;\n\n                return exists;\n            },\n\n            performRedirect: function()\n            {\n                var self = this;\n\n                getCheckoutSessionId().then(function (response)\n                {\n                    if (response && response.length && response.indexOf(\"cs_\") === 0)\n                    {\n                        self.redirect.bind(self)(response);\n                    }\n                    else\n                    {\n                        self.showError($t('Could not redirect to Stripe Checkout.'));\n                    }\n                },\n                function (e)\n                {\n                    self.showError($t('An error has occurred on the server. Could not redirect to Stripe Checkout.'));\n                    console.error(e.responseJSON.message);\n                });\n            },\n\n            checkoutPlaceOrder: function()\n            {\n                var self = this;\n\n                if (additionalValidators.validate())\n                {\n                    fullScreenLoader.startLoader();\n                    getCheckoutSessionId().then(function (response)\n                    {\n                        if (response && response.length && response.indexOf(\"cs_\") === 0)\n                        {\n                            self.redirect.bind(self)(response);\n                        }\n                        else\n                        {\n                            self.placeOrder.bind(self)(self.performRedirect.bind(self));\n                        }\n                    },\n                    function (e)\n                    {\n                        self.showError($t('An error has occurred on the server. Could not redirect to Stripe Checkout.'));\n                        console.error(e.responseJSON.message);\n                    });\n                }\n\n                return false;\n            },\n\n            placeOrder: function()\n            {\n                var self = this;\n\n                placeOrderAction(self.getData(), self.messageContainer)\n                .then(\n                    this.performRedirect.bind(this),\n                    function (e) {\n                        self.showError($t('An error has occurred. Could not redirect to Stripe Checkout.'));\n                        console.error(e.responseJSON.message);\n                    }\n                );\n\n                return false;\n            },\n\n            redirectToURL: function(url)\n            {\n                try\n                {\n                    customerData.invalidate(['cart']);\n                    $.mage.redirect(url);\n                }\n                catch (e)\n                {\n                    console.error(e);\n                }\n            },\n\n            redirect: function(sessionId)\n            {\n                try\n                {\n                    customerData.invalidate(['cart']);\n                    stripe.stripeJs.redirectToCheckout({ sessionId: sessionId }, this.onRedirectFailure.bind(this));\n                }\n                catch (e)\n                {\n                    fullScreenLoader.stopLoader();\n                    console.error(e);\n                }\n            },\n\n            onRedirectFailure: function(result)\n            {\n                if (result.error)\n                {\n                    this.showError(result.error.message);\n                }\n                else\n                {\n                    this.showError($(\"A redirect error has occurred.\"));\n                    console.error(result);\n                }\n            },\n\n            methodName: function(code)\n            {\n                if (typeof code == 'undefined')\n                    return '';\n\n                return code.charAt(0).toUpperCase() + Array.from(code).splice(1).join('');\n            },\n\n            showError: function(message)\n            {\n                fullScreenLoader.stopLoader();\n                document.getElementById('stripe-checkout-actions-toolbar').scrollIntoView(true);\n                this.messageContainer.addErrorMessage({ \"message\": message });\n            },\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/payment/method-renderer/stripe_payments_multishipping.js":"define(\n    [\n        'ko',\n        'Magento_Checkout/js/view/payment/default',\n        'Magento_Ui/js/model/messageList',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Customer/js/model/customer',\n        'StripeIntegration_Payments/js/action/post-update-cart',\n        'StripeIntegration_Payments/js/action/post-restore-quote',\n        'StripeIntegration_Payments/js/action/get-requires-action',\n        'StripeIntegration_Payments/js/view/checkout/trialing_subscriptions',\n        'StripeIntegration_Payments/js/stripe',\n        'stripe_payments_express',\n        'mage/translate',\n        'mage/url',\n        'jquery',\n        'Magento_Checkout/js/action/place-order',\n        'Magento_Checkout/js/model/payment/additional-validators',\n        'Magento_Checkout/js/action/redirect-on-success',\n        'mage/storage',\n        'mage/url',\n        'Magento_CheckoutAgreements/js/model/agreement-validator',\n        'Magento_Customer/js/customer-data',\n        'Magento_Checkout/js/model/payment-service'\n    ],\n    function (\n        ko,\n        Component,\n        globalMessageList,\n        quote,\n        customer,\n        updateCartAction,\n        restoreQuoteAction,\n        getRequiresAction,\n        trialingSubscriptions,\n        stripe,\n        stripeExpress,\n        $t,\n        url,\n        $,\n        placeOrderAction,\n        additionalValidators,\n        redirectOnSuccessAction,\n        storage,\n        urlBuilder,\n        agreementValidator,\n        customerData,\n        paymentService\n    ) {\n        'use strict';\n\n        return Component.extend({\n            externalRedirectUrl: null,\n            defaults: {\n                template: 'StripeIntegration_Payments/payment/element',\n                stripePaymentsShowApplePaySection: false\n            },\n            redirectAfterPlaceOrder: false,\n            elements: null,\n            initParams: null,\n            paymentElement: null,\n            zeroDecimalCurrencies: ['BIF','CLP','DJF','GNF','JPY','KMF','KRW','MGA','PYG','RWF','UGX','VND','VUV','XAF','XOF','XPF'],\n\n            initObservable: function ()\n            {\n                this._super()\n                    .observe([\n                        'paymentElement',\n                        'isPaymentFormComplete',\n                        'isPaymentFormVisible',\n                        'isLoading',\n                        'stripePaymentsError',\n                        'permanentError',\n                        'isOrderPlaced',\n                        'isInitializing',\n                        'isInitialized',\n                        'useQuoteBillingAddress',\n                        'cvcToken',\n                        'paymentElementPaymentMethod',\n\n                        // Saved payment methods dropdown\n                        'dropdownOptions',\n                        'selection',\n                        'isDropdownOpen'\n                    ]);\n\n                var self = this;\n\n                this.isPaymentFormVisible(false);\n                this.isOrderPlaced(false);\n                this.isInitializing(true);\n                this.isInitialized(false);\n                this.useQuoteBillingAddress(false);\n                this.cvcToken(null);\n                this.collectCvc = ko.computed(this.shouldCollectCvc.bind(this));\n                this.isAmex = ko.computed(this.isAmexSelected.bind(this));\n                this.cardCvcElement = null;\n\n                var currentTotals = quote.totals();\n                var currentShippingAddress = quote.shippingAddress();\n                var currentBillingAddress = quote.billingAddress();\n\n                quote.totals.subscribe(function (totals)\n                {\n                    if (!totals || !totals.grand_total || !totals.quote_currency_code)\n                    {\n                        return;\n                    }\n\n                    if (!currentTotals || !currentTotals.grand_total || !currentTotals.quote_currency_code)\n                    {\n                        currentTotals = totals;\n                        return;\n                    }\n\n                    var amount1 = totals.grand_total;\n                    var amount2 = currentTotals.grand_total;\n                    var currency1 = totals.quote_currency_code;\n                    var currency2 = currentTotals.quote_currency_code;\n\n                    if (amount1 === amount2 && currency1 === currency2)\n                    {\n                        return;\n                    }\n\n                    currentTotals = totals;\n\n                    self.onQuoteTotalsChanged.bind(self)();\n                    self.isOrderPlaced(false);\n                }, this);\n\n                quote.paymentMethod.subscribe(function (method)\n                {\n                    if (method.method == this.getCode() && !this.isInitializing())\n                    {\n                        // We intentionally re-create the element because its container element may have changed\n                        this.initPaymentForm();\n                    }\n                }, this);\n\n                quote.billingAddress.subscribe(function(address)\n                {\n                    if (address && self.paymentElement && self.paymentElement.update && !self.isPaymentFormComplete())\n                    {\n                        // Remove the postcode & country fields if a billing address has been specified\n                        self.paymentElement.update(self.getPaymentElementUpdateOptions());\n                    }\n                });\n\n                return this;\n            },\n\n            initSavedPaymentMethods: function()\n            {\n                // If it is already initialized, do not re-initialize\n                if (this.dropdownOptions())\n                {\n                    return;\n                }\n\n                var options = [];\n                var methods = this.getStripeParam(\"savedMethods\");\n                if (methods)\n                {\n                    for (var i in methods)\n                    {\n                        if (methods.hasOwnProperty(i))\n                        {\n                            // We do this because some themes and libraries extend all objects with their own methods\n                            options.push(methods[i]);\n                        }\n                    }\n                }\n\n                if (options.length > 0)\n                {\n                    this.isPaymentFormVisible(false);\n                    this.selection(options[0]);\n                }\n                else\n                {\n                    this.isPaymentFormVisible(true);\n                    this.selection(false);\n                }\n\n                this.dropdownOptions(options);\n            },\n\n            shouldCollectCvc: function()\n            {\n                var selection = this.selection();\n\n                if (!selection)\n                    return false;\n\n                if (selection.type != 'card')\n                    return false;\n\n                return !!selection.cvc;\n            },\n\n            isAmexSelected: function()\n            {\n                var selection = this.selection();\n\n                if (!selection)\n                    return false;\n\n                if (selection.type != 'card')\n                    return false;\n\n                return (selection.brand == \"amex\");\n            },\n\n            newPaymentMethod: function()\n            {\n                this.messageContainer.clear();\n\n                this.selection({\n                    type: 'new',\n                    value: 'new',\n                    icon: false,\n                    label: $t('New payment method')\n                });\n                this.isDropdownOpen(false);\n                this.isPaymentFormVisible(true);\n                if (!this.isInitialized())\n                {\n                    this.onContainerRendered();\n                    this.isInitialized(true);\n                }\n            },\n\n            getPaymentMethodId: function()\n            {\n                var selection = this.selection();\n\n                if (selection && typeof selection.value != \"undefined\" && selection.value != \"new\")\n                {\n                    return selection.value;\n                }\n\n                var paymentMethod = this.paymentElementPaymentMethod();\n                if (paymentMethod && paymentMethod.id)\n                {\n                    return paymentMethod.id;\n                }\n\n                return null;\n            },\n\n            toggleDropdown: function()\n            {\n                this.isDropdownOpen(!this.isDropdownOpen());\n            },\n\n            getStripeParam: function(param)\n            {\n                var params = this.getInitParams();\n\n                if (!params)\n                {\n                    return null;\n                }\n\n                if (typeof params[param] != \"undefined\")\n                {\n                    return params[param];\n                }\n\n                return null;\n            },\n\n            onQuoteTotalsChanged: function()\n            {\n                if (!this.elements || !this.elements.update)\n                {\n                    return;\n                }\n\n                try\n                {\n                    this.elements.update(this.getElementsOptions(true));\n                }\n                catch (e)\n                {\n                    this.elements.update(this.getElementsOptions(false));\n                }\n            },\n\n            getInitParams: function()\n            {\n                return window.checkoutConfig.payment.stripe_payments.initParams;\n            },\n\n            onPaymentElementContainerRendered: function()\n            {\n                var self = this;\n                this.isLoading(true);\n                stripe.initStripe(this.getInitParams(), function(err)\n                {\n                    if (err)\n                        return self.crash(err);\n\n                    self.initSavedPaymentMethods();\n                    self.initPaymentForm();\n                });\n            },\n\n            onContainerRendered: function()\n            {\n                this.onPaymentElementContainerRendered();\n            },\n\n            getCardCVCOptions: function()\n            {\n                return {\n                  style: {\n                    base: {\n                  //     iconColor: '#c4f0ff',\n                  //     color: '#fff',\n                  //     fontWeight: '500',\n                  //     fontFamily: 'Roboto, Open Sans, Segoe UI, sans-serif',\n                      fontSize: '16px',\n                  //     fontSmoothing: 'antialiased',\n                  //     ':-webkit-autofill': {\n                  //       color: '#fce883',\n                  //     },\n                  //     '::placeholder': {\n                  //       color: '#87BBFD',\n                  //     },\n                  //   },\n                  //   invalid: {\n                  //     iconColor: '#FFC7EE',\n                  //     color: '#FFC7EE',\n                    },\n                  },\n                };\n            },\n\n            onCvcContainerRendered: function()\n            {\n                var self = this;\n                var params = this.getInitParams();\n\n                stripe.initStripe(params, function(err)\n                {\n                    if (err)\n                        return self.crash(err);\n\n                    var options = {};\n                    if (params && params.locale)\n                    {\n                        options.locale = params.locale;\n                    }\n\n                    try\n                    {\n                        var elements = stripe.stripeJs.elements(options);\n                        self.cardCvcElement = elements.create('cardCvc', self.getCardCVCOptions());\n                        self.cardCvcElement.mount('#stripe-card-cvc-element');\n                        self.cardCvcElement.on('change', self.onCvcChange.bind(self));\n                    }\n                    catch (e)\n                    {\n                        this.crash(e.message);\n                    }\n                });\n            },\n\n            onCvcChange: function(event)\n            {\n                if (event.error)\n                    this.selection().cvcError = event.error.message;\n                else\n                    this.selection().cvcError = null;\n            },\n\n            crash: function(message)\n            {\n                this.isLoading(false);\n                var userError = this.getStripeParam(\"userError\");\n                if (userError)\n                    this.permanentError(userError);\n                else\n                    this.permanentError($t(\"Sorry, this payment method is not available. Please contact us for assistance.\"));\n\n                console.error(\"Error: \" + message);\n            },\n\n            softCrash: function(message)\n            {\n                var userError = this.getStripeParam(\"userError\");\n                if (userError)\n                    this.showError(userError);\n                else\n                    this.showError($t(\"Sorry, this payment method is not available. Please contact us for assistance.\"));\n\n                console.error(\"Error: \" + message);\n            },\n\n            isCollapsed: function()\n            {\n                if (this.isChecked() == this.getCode())\n                {\n                    return false;\n                }\n                else\n                {\n                    return true;\n                }\n            },\n\n            initPaymentForm: function()\n            {\n                this.isInitializing(false);\n                this.isLoading(false);\n\n                if (this.isCollapsed()) // Don't render PE with a height of 0\n                    return;\n\n                if (document.getElementById('stripe-payment-element') === null)\n                    return this.crash(\"Cannot initialize Payment Element on a DOM that does not contain a div.stripe-payment-element.\");\n\n                if (!stripe.stripeJs)\n                    return this.crash(\"Stripe.js could not be initialized.\");\n\n                if (this.getStripeParam(\"isOrderPlaced\"))\n                    this.isOrderPlaced(true);\n\n                try\n                {\n                    try\n                    {\n                        this.elements = stripe.stripeJs.elements(this.getElementsOptions(true));\n                    }\n                    catch (e)\n                    {\n                        console.warn(\"Could not filter Stripe payment method types: \" + e.message);\n                        this.elements = stripe.stripeJs.elements(this.getElementsOptions(false));\n                    }\n                    this.paymentElement = this.elements.create('payment', this.getPaymentElementOptions());\n                    this.paymentElement.mount('#stripe-payment-element');\n                    this.paymentElement.on('change', this.onChange.bind(this));\n                }\n                catch (e)\n                {\n                    this.crash(e.message);\n                }\n            },\n\n            getElementsOptions: function(filterPaymentMethods)\n            {\n                var options = window.checkoutConfig.payment.stripe_payments.elementOptions;\n\n                if (!filterPaymentMethods && options.payment_method_types)\n                    delete options.payment_method_types;\n\n                if (options.mode != \"setup\")\n                {\n                    options.amount = this.getElementsAmount();\n                    options.currency = this.getElementsCurrency();\n                }\n\n                return options;\n            },\n\n            getPaymentElementOptions: function()\n            {\n                var options = {};\n\n                var params = this.getInitParams();\n                if (params && typeof params.wallets != \"undefined\" && params.wallets)\n                    options.wallets = params.wallets;\n\n                var billingAddress = quote.billingAddress();\n\n                if (billingAddress)\n                {\n                    try\n                    {\n                        this.useQuoteBillingAddress(true);\n\n                        var hasState = (billingAddress.region || billingAddress.regionCode || billingAddress.regionId);\n\n                        options.fields = {\n                            billingDetails: {\n                                name: 'never',\n                                email: 'never',\n                                phone: (billingAddress.telephone ? 'never' : 'auto'),\n                                address: {\n                                    line1: ((billingAddress.street.length > 0) ? 'never' : 'auto'),\n                                    line2: ((billingAddress.street.length > 0) ? 'never' : 'auto'),\n                                    city: billingAddress.city ? 'never' : 'auto',\n                                    state: hasState ? 'never' : 'auto',\n                                    country: billingAddress.countryId ? 'never' : 'auto',\n                                    postalCode: billingAddress.postcode ? 'never' : 'auto'\n                                }\n                            }\n                        };\n                    }\n                    catch (e)\n                    {\n                        this.useQuoteBillingAddress(false);\n\n                        options.fields = {};\n                        console.warn('Could not retrieve billing address: '  + e.message);\n                    }\n\n                    // Set the default billing address in order to enable the Link payment method\n                    var billingDetails = this.getBillingDetails();\n\n                    if (billingDetails)\n                    {\n                        options.defaultValues = {\n                            billingDetails: billingDetails\n                        };\n                    }\n                }\n                else\n                {\n                    this.useQuoteBillingAddress(false);\n                }\n\n                if (params.layout)\n                {\n                    options.layout = params.layout;\n                }\n\n                return options;\n            },\n\n            getPaymentElementUpdateOptions: function()\n            {\n                var options = this.getPaymentElementOptions();\n\n                if (options.wallets)\n                {\n                    delete options.wallets;\n                }\n\n                return options;\n            },\n\n            onChange: function(event)\n            {\n                this.isLoading(false);\n                this.isPaymentFormComplete(event.complete);\n            },\n\n            getElementsAmount: function()\n            {\n                var totals = quote.totals();\n\n                if (totals && totals.grand_total)\n                {\n                    var amount = totals.grand_total;\n                    return this.convertToStripeAmount(amount, this.getElementsCurrency());\n                }\n\n                return 0;\n            },\n\n            getElementsCurrency: function()\n            {\n                var totals = quote.totals();\n                if (totals && totals.quote_currency_code)\n                {\n                    var currency = totals.quote_currency_code;\n                    return currency.toLowerCase();\n                }\n\n                return 'USD';\n            },\n\n            isBillingAddressSet: function()\n            {\n                return quote.billingAddress() && quote.billingAddress().canUseForBilling();\n            },\n\n            convertToStripeAmount: function(amount, currencyCode)\n            {\n                var code = currencyCode.toUpperCase();\n\n                if (this.zeroDecimalCurrencies.indexOf(code) >= 0)\n                {\n                    return Math.round(amount);\n                }\n                else\n                {\n                    return Math.round(amount * 100);\n                }\n            },\n\n            isPlaceOrderEnabled: function()\n            {\n                if (this.stripePaymentsError())\n                    return false;\n\n                if (this.permanentError())\n                    return false;\n\n                return this.isBillingAddressSet();\n            },\n\n            getAddressField: function(field)\n            {\n                if (!quote.billingAddress())\n                    return null;\n\n                var address = quote.billingAddress();\n\n                if (!address[field] || address[field].length == 0)\n                    return null;\n\n                return address[field];\n            },\n\n            getBillingDetails: function()\n            {\n                var details = {};\n                var address = {};\n\n                if (this.getAddressField('city'))\n                    address.city = this.getAddressField('city');\n\n                if (this.getAddressField('countryId'))\n                    address.country = this.getAddressField('countryId');\n\n                if (this.getAddressField('postcode'))\n                    address.postal_code = this.getAddressField('postcode');\n\n                if (this.getAddressField('region'))\n                    address.state = this.getAddressField('region');\n\n                if (this.getAddressField('street'))\n                {\n                    var street = this.getAddressField('street');\n                    address.line1 = street[0];\n\n                    if (street.length > 1)\n                        address.line2 = street[1];\n                }\n\n                if (Object.keys(address).length > 0)\n                    details.address = address;\n\n                if (this.getAddressField('telephone'))\n                    details.phone = this.getAddressField('telephone');\n\n                if (this.getAddressField('firstname'))\n                    details.name = this.getAddressField('firstname') + ' ' + this.getAddressField('lastname');\n\n                if (quote.guestEmail)\n                    details.email = quote.guestEmail;\n                else if (customerData.email)\n                    details.email = customerData.email;\n\n                if (Object.keys(details).length > 0)\n                    return details;\n\n                return null;\n            },\n\n            config: function()\n            {\n                return window.checkoutConfig.payment[this.getCode()];\n            },\n\n            isActive: function(parents)\n            {\n                return true;\n            },\n\n            placeOrder: function()\n            {\n                this.messageContainer.clear();\n\n                if (!this.isPaymentFormComplete() && !this.getPaymentMethodId())\n                    return this.showError($t('Please complete your payment details.'));\n\n                if (!this.validate())\n                    return;\n\n                this.clearErrors();\n                this.isPlaceOrderActionAllowed(false);\n                this.isLoading(true);\n                this.cvcToken(null);\n\n                var params = { };\n\n                if (this.useQuoteBillingAddress())\n                {\n                    params.payment_method_data = {\n                        billing_details: {\n                            address: this.getStripeFormattedAddress(quote.billingAddress()),\n                            email: this.getBillingEmail(),\n                            name: this.getNameFromAddress(quote.billingAddress()),\n                            phone: this.getBillingPhone()\n                        }\n                    };\n                }\n\n                if (this.hasShipping())\n                {\n                    params.shipping = {\n                        address: this.getStripeFormattedAddress(quote.shippingAddress()),\n                        name: this.getNameFromAddress(quote.shippingAddress())\n                    };\n                }\n\n                var self = this;\n\n                if (this.isSavedCardSelected() && this.selection().cvc)\n                {\n                    stripe.stripeJs.createToken('cvc_update', this.cardCvcElement).then(function(result)\n                    {\n                        if (result.error)\n                        {\n                            self.showError(result.error.message);\n                        }\n                        else if (result.token)\n                        {\n                            self.cvcToken(result.token.id);\n                            self.placeOrderWithSavedPaymentMethod.bind(self)();\n                        }\n                        else\n                        {\n                            self.showError('Could not perform CVC check.');\n                        }\n                    });\n                }\n                else if (this.isSavedPaymentMethodSelected())\n                {\n                    this.placeOrderWithSavedPaymentMethod();\n                }\n                else\n                {\n                    this.createPaymentMethod(this.onPaymentMethodCreatedForOrderPlacement.bind(this));\n                }\n\n                return false;\n            },\n\n            hasShipping: function()\n            {\n                return (quote && quote.shippingMethod() && quote.shippingMethod().method_code);\n            },\n\n            createPaymentMethod: function(callback)\n            {\n                this.paymentElementPaymentMethod(null);\n\n                var self = this;\n\n                var paymentMethodData = {\n                    elements: this.elements,\n                    params: {}\n                };\n\n                var confirmParams = this.getConfirmParams();\n                var billingDetails = null;\n                if (confirmParams &&\n                    confirmParams.confirmParams &&\n                    confirmParams.confirmParams.payment_method_data &&\n                    confirmParams.confirmParams.payment_method_data.billing_details\n                )\n                {\n                    billingDetails = confirmParams.confirmParams.payment_method_data.billing_details;\n                }\n\n                if (billingDetails)\n                {\n                    paymentMethodData.params.billing_details = confirmParams.confirmParams.payment_method_data.billing_details;\n                }\n                else\n                {\n                    return this.showError($t(\"Please specify a billing address.\"));\n                }\n\n                this.elements.submit().then(function()\n                {\n                    stripe.stripeJs.createPaymentMethod(paymentMethodData).then(function(result)\n                    {\n                        if (result.error)\n                        {\n                            self.showError(result.error.message);\n                            console.error(result.error.message);\n                        }\n                        else\n                        {\n                            self.paymentElementPaymentMethod(result.paymentMethod);\n                            callback(result.paymentMethod);\n                        }\n                    });\n                },\n                function(result)\n                {\n                    if (result.error)\n                    {\n                        self.showError(result.error.message);\n                        console.error(result.error.message);\n                    }\n                    else\n                    {\n                        self.showError(\"A payment submission error has occurred.\");\n                        console.error(result);\n                    }\n                });\n            },\n\n            isSavedPaymentMethodSelected: function()\n            {\n                var selectedMethodType = this.getSelectedMethod(\"type\");\n\n                if (!selectedMethodType) // There is no saved PMs dropdown\n                    return false;\n\n                if (selectedMethodType != 'new') // A saved PMs is selected\n                    return true;\n\n                return false; // New PM is selected\n            },\n\n            isSavedCardSelected: function()\n            {\n                var selectedMethodType = this.getSelectedMethod(\"type\");\n\n                if (!selectedMethodType) // There is no saved PMs dropdown\n                    return false;\n\n                if (selectedMethodType == 'card') // A saved PMs is selected\n                    return true;\n\n                return false; // New PM is selected\n            },\n\n            placeOrderWithSavedPaymentMethod: function()\n            {\n                var self = this;\n                var placeNewOrder = this.placeNewOrder.bind(this);\n\n                if (this.isOrderPlaced()) // The order was already placed but either 3D Secure failed or the customer pressed the back button from an external payment page\n                {\n                    updateCartAction(this.getData(), this.onCartUpdated.bind(this));\n                }\n                else\n                {\n                    try\n                    {\n                        placeNewOrder();\n                    }\n                    catch (e)\n                    {\n                        this.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                        console.error(e.message);\n                    }\n                }\n            },\n\n            onPaymentMethodCreatedForOrderPlacement: function(paymentMethod)\n            {\n                var placeNewOrder = this.placeNewOrder.bind(this);\n                var self = this;\n\n                if (self.isOrderPlaced()) // The order was already placed but either 3D Secure failed or the customer pressed the back button from an external payment page\n                {\n                    updateCartAction(this.getData(), this.onCartUpdated.bind(this));\n                }\n                else\n                {\n                    try\n                    {\n                        placeNewOrder();\n                    }\n                    catch (e)\n                    {\n                        self.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                        console.error(e.message);\n                    }\n                }\n            },\n\n            onCartUpdated: function(result, outcome, response)\n            {\n                var placeNewOrder = this.placeNewOrder.bind(this);\n                var onOrderPlaced = this.onOrderPlaced.bind(this);\n                try\n                {\n                    var data = JSON.parse(result);\n                    if (data.error)\n                    {\n                        this.showError(data.error);\n                    }\n                    else if (data.redirect)\n                    {\n                        $.mage.redirect(data.redirect);\n                    }\n                    else if (data.placeNewOrder)\n                    {\n                        placeNewOrder();\n                    }\n                    else\n                    {\n                        onOrderPlaced();\n                    }\n                }\n                catch (e)\n                {\n                    this.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                    console.error(e.message);\n                }\n            },\n\n            placeNewOrder: function()\n            {\n                var self = this;\n\n                this.isLoading(false); // Needed for the terms and conditions checkbox\n                this.getPlaceOrderDeferredObject()\n                    .fail(this.handlePlaceOrderErrors.bind(this))\n                    .done(this.onOrderPlaced.bind(this))\n                    .always(function(response, status, xhr)\n                    {\n                        if (status != \"success\")\n                        {\n                            self.isLoading(false);\n                            self.isPlaceOrderEnabled(true);\n                        }\n                    });\n            },\n\n            getSelectedMethod: function(param)\n            {\n                var selection = this.selection();\n                if (!selection)\n                    return null;\n\n                if (typeof selection[param] == \"undefined\")\n                    return null;\n\n                return selection[param];\n            },\n\n            // Called when:\n            // - A brand new order has just been placed\n            // - After updateCartAction() with placeNewOrder == false\n            onOrderPlaced: function(result, outcome, response)\n            {\n                if (!this.isOrderPlaced() && isNaN(result))\n                {\n                    return this.softCrash(\"The order was placed but the response from the server did not include a numeric order ID.\");\n                }\n                else\n                {\n                    this.isOrderPlaced(true);\n                }\n\n                this.isLoading(true);\n                var self = this;\n                var handleNextActions = this.handleNextActions.bind(this);\n                getRequiresAction(function(clientSecret)\n                {\n                    try\n                    {\n                        if (clientSecret && clientSecret.length)\n                        {\n                            stripe.stripeJs.handleNextAction({\n                              clientSecret: clientSecret\n                            }).then(self.onConfirm.bind(self));\n                        }\n                        else\n                        {\n                            // No further actions are needed\n                            self.onConfirm(null);\n                        }\n                    }\n                    catch (e)\n                    {\n                        restoreQuoteAction();\n                        self.showError(\"The order was placed but we could not confirm if the payment was successful.\");\n                        console.error(e);\n                    }\n\n                });\n            },\n\n            isSuccessful: function(stripeObject)\n            {\n\n                if (stripeObject.status == \"requires_action\" &&\n                    stripeObject.next_action &&\n                    stripeObject.next_action.type &&\n                    stripeObject.next_action.type != \"use_stripe_sdk\"\n                )\n                {\n                    // This is the case for vouchers, where an offline payment is required\n                    return true;\n                }\n\n\n                return (['processing', 'requires_capture', 'succeeded'].indexOf(stripeObject.status) >= 0);\n            },\n\n            // Called when:\n            // - A brand new order has just been placed\n            // - After updateCartAction() with placeNewOrder == false\n            handleNextActions: function(stripeObject)\n            {\n                if (!this.isOrderPlaced())\n                {\n                    return this.softCrash(\"Cannot handleNextActions without placing the order first\");\n                }\n\n                var self = this;\n\n                if (this.isSuccessful(stripeObject))\n                {\n                    this.onConfirm(null);\n                }\n                else if (stripeObject.status == \"requires_action\")\n                {\n                    // Non-card based confirms may redirect the customer externally. We restore the quote just before it in case the\n                    // customer clicks the back button on the browser before authenticating the payment.\n                    restoreQuoteAction(function()\n                    {\n                        stripe.stripeJs.handleNextAction({\n                          clientSecret: stripeObject.client_secret\n                        }).then(self.onConfirm.bind(self));\n                    });\n                }\n                else if (stripeObject.status == \"requires_confirmation\")\n                {\n                    // This should only hit when a payment failed with a saved PM, and then the customer switched to PaymentElement to enter a new payment method\n                    restoreQuoteAction(function()\n                    {\n                        // We pass null because we do not want to update the PM. It has already been updated with stripe.updatePaymentIntent\n                        updateCartAction(self.getData(), self.onCartUpdated.bind(self));\n                    });\n                }\n                else if (stripeObject.status == \"requires_payment_method\")\n                {\n                    restoreQuoteAction(function()\n                    {\n                        updateCartAction(self.getData(), self.onCartUpdated.bind(self));\n                    });\n                }\n                else\n                {\n                    restoreQuoteAction(function()\n                    {\n                        self.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                        console.error(\"Could not finalize order bacause the payment intent is in status \" + stripeObject.status);\n                    });\n                }\n            },\n\n            getConfirmParams: function()\n            {\n                var params = {\n                    elements: this.elements,\n                    confirmParams: {\n                        return_url: this.getStripeParam(\"successUrl\")\n                    }\n                };\n\n                this.getPaymentElementOptions();\n                if (this.useQuoteBillingAddress())\n                {\n                    params.confirmParams.payment_method_data = {\n                        billing_details: {\n                            address: this.getStripeFormattedAddress(quote.billingAddress()),\n                            email: this.getBillingEmail(),\n                            name: this.getNameFromAddress(quote.billingAddress()),\n                            phone: this.getBillingPhone()\n                        }\n                    };\n                }\n\n                return params;\n            },\n\n            getStripeFormattedAddress: function(address)\n            {\n                var stripeAddress = {};\n\n                stripeAddress.state = address.region ? address.region : null;\n                stripeAddress.postal_code = address.postcode ? address.postcode : null;\n                stripeAddress.country = address.countryId ? address.countryId : null;\n                stripeAddress.city = address.city ? address.city : null;\n\n                if (address.street && address.street.length > 0)\n                {\n                    stripeAddress.line1 = address.street[0];\n\n                    if (address.street.length > 1)\n                    {\n                        stripeAddress.line2 = address.street[1];\n                    }\n                    else\n                    {\n                        stripeAddress.line2 = null;\n                    }\n                }\n                else\n                {\n                    stripeAddress.line1 = null;\n                    stripeAddress.line2 = null;\n                }\n\n                return stripeAddress;\n            },\n\n            getBillingEmail: function()\n            {\n                if (quote.guestEmail)\n                {\n                    return quote.guestEmail;\n                }\n                else if (window.checkoutConfig.customerData && window.checkoutConfig.customerData.email)\n                {\n                    return window.checkoutConfig.customerData.email;\n                }\n\n                return null;\n            },\n\n            getNameFromAddress: function(address)\n            {\n                if (!address)\n                    return null;\n\n                var parts = [];\n                if (address.firstname)\n                    parts.push(address.firstname);\n\n                if (address.middlename)\n                    parts.push(address.middlename);\n\n                if (address.lastname)\n                    parts.push(address.lastname);\n\n                return parts.join(\" \");\n            },\n\n            getBillingPhone: function()\n            {\n                var billingAddress = quote.billingAddress();\n                if (!billingAddress)\n                    return null;\n\n                if (billingAddress.telephone)\n                    return billingAddress.telephone;\n\n                return null;\n            },\n\n            onConfirm: function(result)\n            {\n                this.isLoading(false);\n                if (result && result.error)\n                {\n                    this.showError(result.error.message);\n                }\n                else\n                {\n                    customerData.invalidate(['cart']);\n                    var successUrl = this.getStripeParam(\"successUrl\");\n                    $.mage.redirect(successUrl);\n                }\n            },\n\n            /**\n             * @return {*}\n             */\n            getPlaceOrderDeferredObject: function()\n            {\n                return placeOrderAction(this.getData(), this.messageContainer);\n            },\n\n            getClientSecretFromResponse: function(response)\n            {\n                if (typeof response != \"string\")\n                {\n                    return null;\n                }\n\n                if (response.indexOf(\"Authentication Required: \") >= 0)\n                {\n                    return response.substring(\"Authentication Required: \".length);\n                }\n\n                return null;\n            },\n\n            handlePlaceOrderErrors: function (result)\n            {\n                if (result && result.responseJSON && result.responseJSON.message)\n                {\n                    var clientSecret = this.getClientSecretFromResponse(result.responseJSON.message);\n\n                    if (clientSecret)\n                    {\n                        var self = this;\n                        return stripe.authenticateCustomer(clientSecret, function(err)\n                        {\n                            if (err)\n                                return self.showError(err);\n\n                            self.placeNewOrder.bind(self)();\n                        });\n                    }\n                    else\n                    {\n                        this.showError(result.responseJSON.message);\n                    }\n                }\n                else\n                {\n                    this.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n\n                    if (result && result.responseText)\n                        console.error(result.responseText);\n                    else\n                        console.error(result);\n                }\n            },\n\n            showError: function(message)\n            {\n                this.isLoading(false);\n                this.isPlaceOrderEnabled(true);\n                this.messageContainer.addErrorMessage({ \"message\": message });\n            },\n\n            validate: function(elm)\n            {\n                return this.validateCvc() && agreementValidator.validate() && additionalValidators.validate();\n            },\n\n            validateCvc: function()\n            {\n                if (!this.selection())\n                    return true;\n\n                if (this.selection().type != \"card\")\n                    return true;\n\n                if (this.selection().cvc != 1)\n                    return true;\n\n                if (typeof this.selection().cvcError == \"undefined\")\n                {\n                    this.showError($t(\"Please enter your card's security code.\"));\n                    return false;\n                }\n                else if (!this.selection().cvcError)\n                {\n                    return true;\n                }\n                else\n                {\n                    this.showError(this.selection().cvcError);\n                    return false;\n                }\n\n                return true;\n            },\n\n            getCode: function()\n            {\n                return 'stripe_payments';\n            },\n\n            getData: function()\n            {\n                var data = {\n                    'method': this.item.method,\n                    'additional_data': {\n                        'payment_method': this.getPaymentMethodId()\n                    }\n                };\n\n                if (this.cvcToken())\n                {\n                    data.additional_data.cvc_token = this.cvcToken();\n                }\n\n                return data;\n            },\n\n            clearErrors: function()\n            {\n                this.stripePaymentsError(null);\n            }\n\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/payment/method-renderer/bank_transfers.js":"define(\n    [\n        'Magento_Checkout/js/view/payment/default',\n        'Magento_Checkout/js/model/quote',\n        'StripeIntegration_Payments/js/action/post-restore-quote',\n        'StripeIntegration_Payments/js/action/get-requires-action',\n        'StripeIntegration_Payments/js/stripe',\n        'mage/translate',\n        'Magento_Checkout/js/action/place-order',\n        'Magento_Checkout/js/model/payment/additional-validators',\n        'Magento_Checkout/js/action/redirect-on-success',\n        'Magento_CheckoutAgreements/js/model/agreement-validator',\n        'Magento_Customer/js/customer-data',\n    ],\n    function (\n        Component,\n        quote,\n        restoreQuoteAction,\n        getRequiresAction,\n        stripe,\n        $t,\n        placeOrderAction,\n        additionalValidators,\n        redirectOnSuccessAction,\n        agreementValidator,\n        customerData\n    ) {\n        'use strict';\n\n        return Component.extend({\n            externalRedirectUrl: null,\n            defaults: {\n                template: 'StripeIntegration_Payments/payment/bank_transfers'\n            },\n            redirectAfterPlaceOrder: false,\n            elements: null,\n            initParams: null,\n            paymentElement: null,\n            zeroDecimalCurrencies: ['BIF','CLP','DJF','GNF','JPY','KMF','KRW','MGA','PYG','RWF','UGX','VND','VUV','XAF','XOF','XPF'],\n\n            initObservable: function ()\n            {\n                this._super()\n                    .observe([\n                        'paymentElement',\n                        'isPaymentFormComplete',\n                        'isLoading',\n                        'stripePaymentsError',\n                        'permanentError',\n                        'isInitializing',\n                        'isInitialized',\n                        'useQuoteBillingAddress',\n                        'paymentElementPaymentMethod',\n                    ]);\n\n                var self = this;\n\n                this.isInitializing(true);\n                this.isInitialized(false);\n                this.useQuoteBillingAddress(false);\n\n                quote.paymentMethod.subscribe(function (method)\n                {\n                    if (method && method.method == this.getCode() && !this.isInitializing())\n                    {\n                        // We intentionally re-create the element because its container element may have changed\n                        this.initPaymentForm();\n                    }\n                }, this);\n\n                quote.billingAddress.subscribe(function(address)\n                {\n                    if (address && self.paymentElement && self.paymentElement.update && !self.isPaymentFormComplete())\n                    {\n                        // Remove the postcode & country fields if a billing address has been specified\n                        self.paymentElement.update(self.getPaymentElementUpdateOptions());\n                    }\n                });\n\n                return this;\n            },\n\n\n            getPaymentMethodId: function()\n            {\n                var paymentMethod = this.paymentElementPaymentMethod();\n                if (paymentMethod && paymentMethod.id)\n                {\n                    return paymentMethod.id;\n                }\n\n                return null;\n            },\n\n            getStripeParam: function(param)\n            {\n                var params = this.getInitParams();\n\n                if (!params)\n                {\n                    return null;\n                }\n\n                if (typeof params[param] != \"undefined\")\n                {\n                    return params[param];\n                }\n\n                return null;\n            },\n\n            getInitParams: function()\n            {\n                return window.checkoutConfig.payment.stripe_payments_bank_transfers.initParams;\n            },\n\n            onPaymentElementContainerRendered: function()\n            {\n                var self = this;\n                this.isLoading(true);\n                stripe.initStripe(this.getInitParams(), function(err)\n                {\n                    if (err)\n                        return self.crash(err);\n\n                    self.initPaymentForm();\n                });\n            },\n\n            onContainerRendered: function()\n            {\n                this.onPaymentElementContainerRendered();\n            },\n\n            crash: function(message)\n            {\n                this.isLoading(false);\n                var userError = this.getStripeParam(\"userError\");\n                if (userError)\n                    this.permanentError(userError);\n                else\n                    this.permanentError($t(\"Sorry, this payment method is not available. Please contact us for assistance.\"));\n\n                console.error(\"Error: \" + message);\n            },\n\n            softCrash: function(message)\n            {\n                var userError = this.getStripeParam(\"userError\");\n                if (userError)\n                    this.showError(userError);\n                else\n                    this.showError($t(\"Sorry, this payment method is not available. Please contact us for assistance.\"));\n\n                console.error(\"Error: \" + message);\n            },\n\n            isCollapsed: function()\n            {\n                if (this.isChecked() == this.getCode())\n                {\n                    return false;\n                }\n                else\n                {\n                    return true;\n                }\n            },\n\n            initPaymentForm: function()\n            {\n                this.isInitializing(false);\n                this.isLoading(false);\n\n                if (this.isCollapsed()) // Don't render PE with a height of 0\n                    return;\n\n                if (document.getElementById('stripe-payment-element-bank-transfers') === null)\n                    return this.crash(\"Cannot initialize Payment Element on a DOM that does not contain a div.stripe-payment-element-bank-transfers.\");\n\n                if (!stripe.stripeJs)\n                    return this.crash(\"Stripe.js could not be initialized.\");\n\n                try\n                {\n                    this.elements = stripe.stripeJs.elements(this.getElementsOptions());\n                    this.paymentElement = this.elements.create('payment', this.getPaymentElementOptions());\n                    this.paymentElement.mount('#stripe-payment-element-bank-transfers');\n                    this.paymentElement.on('change', this.onChange.bind(this));\n                }\n                catch (e)\n                {\n                    this.crash(e.message);\n                }\n            },\n\n            getElementsOptions: function()\n            {\n                var options = window.checkoutConfig.payment.stripe_payments_bank_transfers.elementOptions;\n\n                options.amount = this.getElementsAmount();\n                options.currency = this.getElementsCurrency();\n\n                return options;\n            },\n\n            getPaymentElementOptions: function()\n            {\n                var options = {};\n\n                var billingAddress = quote.billingAddress();\n\n                if (billingAddress)\n                {\n                    try\n                    {\n                        this.useQuoteBillingAddress(true);\n\n                        var hasState = (billingAddress.region || billingAddress.regionCode || billingAddress.regionId);\n\n                        options.fields = {\n                            billingDetails: {\n                                name: 'never',\n                                email: 'never',\n                                phone: (billingAddress.telephone ? 'never' : 'auto'),\n                                address: {\n                                    line1: ((billingAddress.street.length > 0) ? 'never' : 'auto'),\n                                    line2: ((billingAddress.street.length > 0) ? 'never' : 'auto'),\n                                    city: billingAddress.city ? 'never' : 'auto',\n                                    state: hasState ? 'never' : 'auto',\n                                    country: billingAddress.countryId ? 'never' : 'auto',\n                                    postalCode: billingAddress.postcode ? 'never' : 'auto'\n                                }\n                            }\n                        };\n                    }\n                    catch (e)\n                    {\n                        this.useQuoteBillingAddress(false);\n\n                        options.fields = {};\n                        console.warn('Could not retrieve billing address: '  + e.message);\n                    }\n\n                    // Set the default billing address in order to enable the Link payment method\n                    var billingDetails = this.getBillingDetails();\n\n                    if (billingDetails)\n                    {\n                        options.defaultValues = {\n                            billingDetails: billingDetails\n                        };\n                    }\n                }\n                else\n                {\n                    this.useQuoteBillingAddress(false);\n                }\n\n                return options;\n            },\n\n            getPaymentElementUpdateOptions: function()\n            {\n                var options = this.getPaymentElementOptions();\n\n                if (options.wallets)\n                {\n                    delete options.wallets;\n                }\n\n                return options;\n            },\n\n            onChange: function(event)\n            {\n                this.isLoading(false);\n                this.isPaymentFormComplete(event.complete);\n            },\n\n            getElementsAmount: function()\n            {\n                var totals = quote.totals();\n\n                if (totals && totals.grand_total)\n                {\n                    var amount = totals.grand_total;\n                    return this.convertToStripeAmount(amount, this.getElementsCurrency());\n                }\n\n                return 0;\n            },\n\n            getElementsCurrency: function()\n            {\n                var totals = quote.totals();\n                if (totals && totals.quote_currency_code)\n                {\n                    var currency = totals.quote_currency_code;\n                    return currency.toLowerCase();\n                }\n\n                return 'USD';\n            },\n\n            isBillingAddressSet: function()\n            {\n                return quote.billingAddress() && quote.billingAddress().canUseForBilling();\n            },\n\n            convertToStripeAmount: function(amount, currencyCode)\n            {\n                var code = currencyCode.toUpperCase();\n\n                if (this.zeroDecimalCurrencies.indexOf(code) >= 0)\n                {\n                    return Math.round(amount);\n                }\n                else\n                {\n                    return Math.round(amount * 100);\n                }\n            },\n\n            isPlaceOrderEnabled: function()\n            {\n                if (this.stripePaymentsError())\n                    return false;\n\n                if (this.permanentError())\n                    return false;\n\n                return this.isBillingAddressSet();\n            },\n\n            getAddressField: function(field)\n            {\n                if (!quote.billingAddress())\n                    return null;\n\n                var address = quote.billingAddress();\n\n                if (!address[field] || address[field].length == 0)\n                    return null;\n\n                return address[field];\n            },\n\n            getBillingDetails: function()\n            {\n                var details = {};\n                var address = {};\n\n                if (this.getAddressField('city'))\n                    address.city = this.getAddressField('city');\n\n                if (this.getAddressField('countryId'))\n                    address.country = this.getAddressField('countryId');\n\n                if (this.getAddressField('postcode'))\n                    address.postal_code = this.getAddressField('postcode');\n\n                if (this.getAddressField('region'))\n                    address.state = this.getAddressField('region');\n\n                if (this.getAddressField('street'))\n                {\n                    var street = this.getAddressField('street');\n                    address.line1 = street[0];\n\n                    if (street.length > 1)\n                        address.line2 = street[1];\n                }\n\n                if (Object.keys(address).length > 0)\n                    details.address = address;\n\n                if (this.getAddressField('telephone'))\n                    details.phone = this.getAddressField('telephone');\n\n                if (this.getAddressField('firstname'))\n                    details.name = this.getAddressField('firstname') + ' ' + this.getAddressField('lastname');\n\n                if (quote.guestEmail)\n                    details.email = quote.guestEmail;\n                else if (customerData.email)\n                    details.email = customerData.email;\n\n                if (Object.keys(details).length > 0)\n                    return details;\n\n                return null;\n            },\n\n            config: function()\n            {\n                return window.checkoutConfig.payment[this.getCode()];\n            },\n\n            placeOrder: function()\n            {\n                this.messageContainer.clear();\n\n                if (!this.isPaymentFormComplete() && !this.getPaymentMethodId())\n                    return this.showError($t('Please complete your payment details.'));\n\n                if (!this.validate())\n                    return;\n\n                this.clearErrors();\n                this.isPlaceOrderActionAllowed(false);\n                this.isLoading(true);\n\n                var params = { };\n\n                if (this.useQuoteBillingAddress())\n                {\n                    params.payment_method_data = {\n                        billing_details: {\n                            address: this.getStripeFormattedAddress(quote.billingAddress()),\n                            email: this.getBillingEmail(),\n                            name: this.getNameFromAddress(quote.billingAddress()),\n                            phone: this.getBillingPhone()\n                        }\n                    };\n                }\n\n                if (this.hasShipping())\n                {\n                    params.shipping = {\n                        address: this.getStripeFormattedAddress(quote.shippingAddress()),\n                        name: this.getNameFromAddress(quote.shippingAddress())\n                    };\n                }\n\n                this.createPaymentMethod(this.onPaymentMethodCreatedForOrderPlacement.bind(this));\n\n                return false;\n            },\n\n            hasShipping: function()\n            {\n                return (quote && quote.shippingMethod() && quote.shippingMethod().method_code);\n            },\n\n            createPaymentMethod: function(callback)\n            {\n                this.paymentElementPaymentMethod(null);\n\n                var self = this;\n\n                var paymentMethodData = {\n                    elements: this.elements,\n                    params: {}\n                };\n\n                var confirmParams = this.getConfirmParams();\n                var billingDetails = null;\n                if (confirmParams &&\n                    confirmParams.confirmParams &&\n                    confirmParams.confirmParams.payment_method_data &&\n                    confirmParams.confirmParams.payment_method_data.billing_details\n                )\n                {\n                    billingDetails = confirmParams.confirmParams.payment_method_data.billing_details;\n                }\n\n                if (billingDetails)\n                {\n                    paymentMethodData.params.billing_details = confirmParams.confirmParams.payment_method_data.billing_details;\n                }\n                else\n                {\n                    return this.showError($t(\"Please specify a billing address.\"));\n                }\n\n                this.elements.submit().then(function()\n                {\n                    stripe.stripeJs.createPaymentMethod(paymentMethodData).then(function(result)\n                    {\n                        if (result.error)\n                        {\n                            self.showError(result.error.message);\n                            console.error(result.error.message);\n                        }\n                        else\n                        {\n                            self.paymentElementPaymentMethod(result.paymentMethod);\n                            callback(result.paymentMethod);\n                        }\n                    });\n                },\n                function(result)\n                {\n                    if (result.error)\n                    {\n                        self.showError(result.error.message);\n                        console.error(result.error.message);\n                    }\n                    else\n                    {\n                        self.showError(\"A payment submission error has occurred.\");\n                        console.error(result);\n                    }\n                });\n            },\n\n            onPaymentMethodCreatedForOrderPlacement: function(paymentMethod)\n            {\n                var placeNewOrder = this.placeNewOrder.bind(this);\n                var self = this;\n\n                try\n                {\n                    placeNewOrder();\n                }\n                catch (e)\n                {\n                    self.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n                    console.error(e.message);\n                }\n            },\n\n            placeNewOrder: function()\n            {\n                var self = this;\n\n                this.isLoading(false); // Needed for the terms and conditions checkbox\n                this.getPlaceOrderDeferredObject()\n                    .fail(this.handlePlaceOrderErrors.bind(this))\n                    .done(this.onOrderPlaced.bind(this))\n                    .always(function(response, status, xhr)\n                    {\n                        if (status != \"success\")\n                        {\n                            self.isLoading(false);\n                            self.isPlaceOrderEnabled(true);\n                        }\n                    });\n            },\n\n            onOrderPlaced: function(result, outcome, response)\n            {\n                this.isLoading(true);\n                var self = this;\n                getRequiresAction(function(clientSecret)\n                {\n                    try\n                    {\n                        if (clientSecret && clientSecret.length)\n                        {\n                            stripe.stripeJs.handleNextAction({\n                              clientSecret: clientSecret\n                            }).then(self.onConfirm.bind(self));\n                        }\n                        else\n                        {\n                            // No further actions are needed\n                            self.onConfirm(null);\n                        }\n                    }\n                    catch (e)\n                    {\n                        restoreQuoteAction();\n                        self.showError(\"The order was placed but we could not confirm if the payment was successful.\");\n                        console.error(e);\n                    }\n\n                });\n            },\n\n            isSuccessful: function(stripeObject)\n            {\n\n                if (stripeObject.status == \"requires_action\" &&\n                    stripeObject.next_action &&\n                    stripeObject.next_action.type &&\n                    stripeObject.next_action.type != \"use_stripe_sdk\"\n                )\n                {\n                    // This is the case for vouchers, where an offline payment is required\n                    return true;\n                }\n\n                return (['processing', 'requires_capture', 'succeeded'].indexOf(stripeObject.status) >= 0);\n            },\n\n            getConfirmParams: function()\n            {\n                var params = {\n                    elements: this.elements,\n                    confirmParams: {\n                        return_url: this.getStripeParam(\"successUrl\")\n                    }\n                };\n\n                this.getPaymentElementOptions();\n                if (this.useQuoteBillingAddress())\n                {\n                    params.confirmParams.payment_method_data = {\n                        billing_details: {\n                            address: this.getStripeFormattedAddress(quote.billingAddress()),\n                            email: this.getBillingEmail(),\n                            name: this.getNameFromAddress(quote.billingAddress()),\n                            phone: this.getBillingPhone()\n                        }\n                    };\n                }\n\n                return params;\n            },\n\n            getStripeFormattedAddress: function(address)\n            {\n                var stripeAddress = {};\n\n                stripeAddress.state = address.region ? address.region : null;\n                stripeAddress.postal_code = address.postcode ? address.postcode : null;\n                stripeAddress.country = address.countryId ? address.countryId : null;\n                stripeAddress.city = address.city ? address.city : null;\n\n                if (address.street && address.street.length > 0)\n                {\n                    stripeAddress.line1 = address.street[0];\n\n                    if (address.street.length > 1)\n                    {\n                        stripeAddress.line2 = address.street[1];\n                    }\n                    else\n                    {\n                        stripeAddress.line2 = null;\n                    }\n                }\n                else\n                {\n                    stripeAddress.line1 = null;\n                    stripeAddress.line2 = null;\n                }\n\n                return stripeAddress;\n            },\n\n            getBillingEmail: function()\n            {\n                if (quote.guestEmail)\n                {\n                    return quote.guestEmail;\n                }\n                else if (window.checkoutConfig.customerData && window.checkoutConfig.customerData.email)\n                {\n                    return window.checkoutConfig.customerData.email;\n                }\n\n                return null;\n            },\n\n            getNameFromAddress: function(address)\n            {\n                if (!address)\n                    return null;\n\n                var parts = [];\n                if (address.firstname)\n                    parts.push(address.firstname);\n\n                if (address.middlename)\n                    parts.push(address.middlename);\n\n                if (address.lastname)\n                    parts.push(address.lastname);\n\n                return parts.join(\" \");\n            },\n\n            getBillingPhone: function()\n            {\n                var billingAddress = quote.billingAddress();\n                if (!billingAddress)\n                    return null;\n\n                if (billingAddress.telephone)\n                    return billingAddress.telephone;\n\n                return null;\n            },\n\n            onConfirm: function(result)\n            {\n                this.isLoading(false);\n                if (result && result.error)\n                {\n                    this.showError(result.error.message);\n                }\n                else\n                {\n                    customerData.invalidate(['cart']);\n                    redirectOnSuccessAction.execute();\n                }\n            },\n\n            /**\n             * @return {*}\n             */\n            getPlaceOrderDeferredObject: function()\n            {\n                return placeOrderAction(this.getData(), this.messageContainer);\n            },\n\n            getClientSecretFromResponse: function(response)\n            {\n                if (typeof response != \"string\")\n                {\n                    return null;\n                }\n\n                if (response.indexOf(\"Authentication Required: \") >= 0)\n                {\n                    return response.substring(\"Authentication Required: \".length);\n                }\n\n                return null;\n            },\n\n            handlePlaceOrderErrors: function (result)\n            {\n                if (result && result.responseJSON && result.responseJSON.message)\n                {\n                    var clientSecret = this.getClientSecretFromResponse(result.responseJSON.message);\n\n                    if (clientSecret)\n                    {\n                        var self = this;\n                        return stripe.authenticateCustomer(clientSecret, function(err)\n                        {\n                            if (err)\n                                return self.showError(err);\n\n                            self.placeNewOrder.bind(self)();\n                        });\n                    }\n                    else\n                    {\n                        this.showError(result.responseJSON.message);\n                    }\n                }\n                else\n                {\n                    this.showError($t(\"The order could not be placed. Please contact us for assistance.\"));\n\n                    if (result && result.responseText)\n                        console.error(result.responseText);\n                    else\n                        console.error(result);\n                }\n            },\n\n            showError: function(message)\n            {\n                this.isLoading(false);\n                this.isPlaceOrderEnabled(true);\n                this.messageContainer.addErrorMessage({ \"message\": message });\n            },\n\n            validate: function(elm)\n            {\n                return agreementValidator.validate() && additionalValidators.validate();\n            },\n\n            getCode: function()\n            {\n                return 'stripe_payments_bank_transfers';\n            },\n\n            getData: function()\n            {\n                var data = {\n                    'method': this.item.method,\n                    'additional_data': {\n                        'payment_method': this.getPaymentMethodId(),\n                    }\n                };\n\n                return data;\n            },\n\n            clearErrors: function()\n            {\n                this.stripePaymentsError(null);\n            }\n\n        });\n    }\n);\n","StripeIntegration_Payments/js/view/multishipping/method-renderer/payment_element.js":"define(\n    [\n        'ko',\n        'StripeIntegration_Payments/js/view/payment/method-renderer/stripe_payments_multishipping',\n        'StripeIntegration_Payments/js/stripe',\n        'Magento_Ui/js/model/messageList',\n        'Magento_Checkout/js/model/quote',\n        'Magento_Customer/js/model/customer',\n        'Magento_Checkout/js/action/set-payment-information',\n        'mage/translate',\n        'mage/url',\n        'jquery',\n        'Magento_Checkout/js/model/payment/additional-validators',\n        'mage/storage',\n        'mage/url',\n        'Magento_CheckoutAgreements/js/model/agreement-validator',\n        'Magento_Customer/js/customer-data',\n        'Magento_Ui/js/modal/alert',\n        'domReady!'\n    ],\n    function (\n        ko,\n        Component,\n        stripe,\n        globalMessageList,\n        quote,\n        customer,\n        setPaymentInformationAction,\n        $t,\n        url,\n        $,\n        additionalValidators,\n        storage,\n        urlBuilder,\n        agreementValidator,\n        customerData,\n        alert\n    ) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                template: 'StripeIntegration_Payments/multishipping/payment_element',\n                continueSelector: '#payment-continue',\n                cardElement: null,\n                token: ko.observable(null),\n                params: null,\n                captureMethod: 'automatic'\n            },\n\n            initObservable: function ()\n            {\n                this._super();\n\n                $(this.continueSelector).on(\"click\", this.onContinue.bind(this));\n\n                return this;\n            },\n\n            onPaymentElementContainerRendered: function()\n            {\n                var self = this;\n                this.isLoading(true);\n\n                this.params = window.initParams;\n\n                stripe.initStripe(this.params, function(err)\n                {\n                    if (err)\n                        return self.crash(err);\n\n                    self.initSavedPaymentMethods.bind(self)();\n                    self.initPaymentForm.bind(self)();\n                });\n            },\n\n            onContainerRendered: function()\n            {\n                this.onPaymentElementContainerRendered();\n                this.isInitialized(true);\n            },\n\n            initPaymentForm: function()\n            {\n                this.isInitializing(false);\n                this.isLoading(false);\n\n                if (this.isCollapsed()) // Don't render PE with a height of 0\n                    return;\n\n                if (document.getElementById('stripe-payment-element') === null)\n                    return this.crash(\"Cannot initialize Card Element on a DOM that does not contain a div.stripe-card-element.\");\n\n                if (!stripe.stripeJs)\n                    return this.crash(\"Stripe.js could not be initialized.\");\n\n                try\n                {\n                    var elementOptions = this.getElementsOptions(true);\n                    elementOptions.setupFutureUsage = 'on_session';\n                    elementOptions.captureMethod = this.captureMethod;\n                    this.elements = stripe.stripeJs.elements(this.getElementsOptions(true));\n                }\n                catch (e)\n                {\n                    console.warn(\"Could not filter Stripe payment method types: \" + e.message);\n                    this.elements = stripe.stripeJs.elements(this.getElementsOptions(false));\n                }\n\n                this.paymentElement = this.elements.create('payment', this.getPaymentElementOptions());\n                this.paymentElement.mount('#stripe-payment-element');\n                this.paymentElement.on('change', this.onChange.bind(this));\n\n            },\n\n            onSetPaymentMethodFail: function(result)\n            {\n                this.token(null);\n                this.isLoading(false);\n                console.error(result);\n            },\n\n            onContinue: function(e)\n            {\n                // If we already have a tokenized payment method, don't do anything\n                if (this.token())\n                    return;\n\n                var self = this;\n\n                if (!this.isStripeMethodSelected())\n                    return;\n\n                e.preventDefault();\n                e.stopPropagation();\n\n                if (!this.validatePaymentMethod())\n                    return;\n\n                this.isLoading(true);\n\n                if (this.getSelectedMethod(\"type\") && this.getSelectedMethod(\"type\") != \"new\")\n                {\n                    self.token(this.getSelectedMethod(\"value\"));\n                    setPaymentInformationAction(this.messageContainer, this.getData()).then(function(){\n                        $(self.continueSelector).trigger(\"click\");\n                    }).fail(self.onSetPaymentMethodFail.bind(self));\n                }\n                else\n                {\n                    this.createPaymentMethod(function(err)\n                    {\n                        if (err)\n                            return self.showError(err);\n\n                        $(self.continueSelector).trigger(\"click\");\n                    });\n                }\n            },\n\n            createPaymentMethod: function(done)\n            {\n                var self = this;\n\n                var paymentMethodData = {\n                    elements: this.elements,\n                    params: {}\n                };\n\n                var confirmParams = this.getConfirmParams();\n                var billingDetails = null;\n                if (confirmParams &&\n                    confirmParams.confirmParams &&\n                    confirmParams.confirmParams.payment_method_data &&\n                    confirmParams.confirmParams.payment_method_data.billing_details\n                )\n                {\n                    billingDetails = confirmParams.confirmParams.payment_method_data.billing_details;\n                }\n\n                if (billingDetails)\n                {\n                    paymentMethodData.params.billing_details = confirmParams.confirmParams.payment_method_data.billing_details;\n                }\n                else\n                {\n                    return this.showError($t(\"Please specify a billing address.\"));\n                }\n\n                this.elements.submit().then(function() {\n                    stripe.stripeJs.createPaymentMethod(paymentMethodData).then(function(result)\n                    {\n                        if (result.error)\n                        {\n                            self.showError(result.error.message);\n                            console.error(result.error.message);\n                        }\n                        else\n                        {\n                            self.token(result.paymentMethod.id);\n\n                            setPaymentInformationAction(self.messageContainer, self.getData()).then(function()\n                            {\n                                done();\n                            }).fail(self.onSetPaymentMethodFail.bind(self));\n                        }\n                    });\n                });\n\n            },\n\n            getData: function()\n            {\n                var data = {\n                    'method': this.item.method,\n                    'additional_data': {\n                        'payment_method': this.token()\n                    }\n                };\n\n                return data;\n            },\n\n            showError: function(message)\n            {\n                this.isLoading(false);\n                alert({ content: message });\n            },\n\n            validatePaymentMethod: function ()\n            {\n                var methods = $('[name^=\"payment[\"]'), isValid = false;\n\n                if (methods.length === 0)\n                    this.showError( $.mage.__('We can\\'t complete your order because you don\\'t have a payment method set up.') );\n                else if (methods.filter('input:radio:checked').length)\n                    return true;\n                else\n                    this.showError( $.mage.__('Please choose a payment method.') );\n\n                return isValid;\n            },\n\n            isStripeMethodSelected: function()\n            {\n                var methods = $('[name^=\"payment[\"]');\n\n                if (methods.length === 0)\n                    return false;\n\n                var stripe = methods.filter(function(index, value)\n                {\n                    if (value.id == \"p_method_stripe_payments\")\n                        return value;\n                });\n\n                if (stripe.length == 0)\n                    return false;\n\n                return stripe[0].checked;\n            }\n        });\n    }\n);\n","StripeIntegration_Payments/js/action/list-payment-methods.js":"define(\n    [\n        'mage/url',\n        'mage/storage'\n    ],\n    function (\n        urlBuilder,\n        storage\n    ) {\n        'use strict';\n        return function (callback)\n        {\n            var serviceUrl = urlBuilder.build('rest/V1/stripe/payments/list_payment_methods');\n\n            return storage.get(serviceUrl).always(callback);\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/add-payment-method.js":"define(\n    [\n        'mage/url',\n        'mage/storage'\n    ],\n    function (\n        urlBuilder,\n        storage\n    ) {\n        'use strict';\n        return function (paymentMethodId, callback)\n        {\n            var serviceUrl = urlBuilder.build('rest/V1/stripe/payments/add_payment_method');\n\n            var payload = {\n                paymentMethodId: paymentMethodId\n            };\n\n            return storage.post(serviceUrl, JSON.stringify(payload)).always(callback);\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/delete-payment-method.js":"define(\n    [\n        'mage/url',\n        'mage/storage'\n    ],\n    function (\n        urlBuilder,\n        storage\n    ) {\n        'use strict';\n        return function (paymentMethodId, fingerprint, callback)\n        {\n            var serviceUrl = urlBuilder.build('rest/V1/stripe/payments/delete_payment_method');\n\n            var payload = {\n                paymentMethodId: paymentMethodId\n            };\n\n            if (fingerprint)\n            {\n                payload.fingerprint = fingerprint;\n            }\n\n            return storage.post(serviceUrl, JSON.stringify(payload)).always(callback);\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/post-cancel-order.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'Magento_Customer/js/customer-data',\n        'mage/storage'\n    ],\n    function (urlBuilder, customerData, storage) {\n        'use strict';\n\n        var promise = null; // If this is set, the promise is not resolved\n\n        return function (errorMessage, callback)\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/cancel_last_order', {});\n\n            var payload = {\n                errorMessage: errorMessage\n            };\n\n            customerData.invalidate(['cart']);\n\n            if (!promise)\n                promise = storage.post(serviceUrl, JSON.stringify(payload));\n            else\n                return promise.always(callback); // Stack multiple callbacks onto the promise\n\n            return promise.always(function(result, outcome, response)\n            {\n                promise = null; // Marks it as resolved\n                callback(result, outcome, response);\n            });\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/get-upcoming-invoice.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage'\n    ],\n    function (urlBuilder, storage) {\n        'use strict';\n\n        var promise = null; // If this is set, the promise is not resolved\n\n        return function (callback)\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/get_upcoming_invoice', {});\n\n            if (!promise)\n                promise = storage.get(serviceUrl);\n            else\n                return promise.always(callback); // Stack multiple callbacks onto the promise\n\n            return promise.always(function(result, outcome, response)\n            {\n                promise = null; // Marks it as resolved\n                callback(result, outcome, response);\n            });\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/get-requires-action.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'Magento_Customer/js/customer-data',\n        'mage/storage'\n    ],\n    function (urlBuilder, customerData, storage) {\n        'use strict';\n\n        var promise = null; // If this is set, the promise is not resolved\n\n        return function (callback)\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/get_requires_action', {});\n\n            customerData.invalidate(['cart']);\n\n            if (!promise)\n                promise = storage.get(serviceUrl);\n            else\n                return promise.always(callback); // Stack multiple callbacks onto the promise\n\n            return promise.always(function(result, outcome, response)\n            {\n                promise = null; // Marks it as resolved\n                callback(result, outcome, response);\n            });\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/finalize-multishipping-order.js":"define(\n    [\n        'jquery',\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Customer/js/customer-data',\n        'Magento_Ui/js/modal/alert'\n    ],\n    function ($, urlBuilder, storage, customerData, alert) {\n        'use strict';\n\n        var showError = function(message, e)\n        {\n            alert( { content: message });\n\n            if (typeof e != \"undefined\")\n                console.error(e);\n        };\n\n        return function (error)\n        {\n            customerData.invalidate(['cart']);\n\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/finalize_multishipping_order', {});\n            var payload = { error: error };\n\n            return storage.post(serviceUrl, JSON.stringify(payload))\n            .then(function(result, b, c)\n            {\n                var response = null;\n\n                try\n                {\n                    response = JSON.parse(result);\n                }\n                catch (e)\n                {\n                    return showError(\"Sorry, a server side error has occurred.\", e);\n                }\n\n                if (response.error)\n                    return showError(response.error, response.error);\n\n                if (response.redirect)\n                    return $.mage.redirect(response.redirect);\n\n                return showError(response, response);\n            })\n            .fail(function(result)\n            {\n                return showError(\"Sorry, a server side error has occurred.\", result);\n            });\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/post-update-cart.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Customer/js/customer-data'\n    ],\n    function (urlBuilder, storage, customerData) {\n        'use strict';\n        return function (data, callback)\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/update_cart', {});\n\n            // This API call may inactivate the customer cart\n            customerData.invalidate(['cart']);\n\n            if (data)\n            {\n                return storage.post(\n                    serviceUrl,\n                    JSON.stringify({ data: data })\n                ).always(callback);\n            }\n            else\n            {\n\n                return storage.post(serviceUrl).always(callback);\n            }\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/post-restore-quote.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Customer/js/customer-data',\n        'Magento_Checkout/js/model/quote'\n    ],\n    function (\n        urlBuilder,\n        storage,\n        customerData,\n        quote\n    ) {\n        'use strict';\n        return function (callback)\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/restore_quote', {});\n\n            customerData.invalidate(['cart']);\n\n            return storage.post(serviceUrl).always(callback);\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/get-checkout-session-id.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage'\n    ],\n    function (urlBuilder, storage) {\n        'use strict';\n\n        return function ()\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/get_checkout_session_id', {});\n\n            return storage.get(serviceUrl);\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/get-payment-url.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Checkout/js/model/error-processor',\n        'Magento_Checkout/js/model/full-screen-loader'\n    ],\n    function (urlBuilder, storage, errorProcessor, fullScreenLoader) {\n        'use strict';\n        return function (messageContainer) {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/redirect_url', {});\n\n            fullScreenLoader.startLoader();\n\n            return storage.get(\n                serviceUrl\n            ).fail(\n                function (response) {\n                    errorProcessor.process(response, messageContainer);\n                    fullScreenLoader.stopLoader();\n                }\n            );\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/get-trialing-subscriptions.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Checkout/js/model/error-processor',\n        'Magento_Checkout/js/model/full-screen-loader',\n        'Magento_Checkout/js/model/quote'\n    ],\n    function (urlBuilder, storage, errorProcessor, fullScreenLoader, quote) {\n        'use strict';\n        return function (quote)\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/get_trialing_subscriptions', {});\n\n            var payload = {\n                billingAddress: quote.billingAddress()\n            };\n\n            if (quote.shippingAddress())\n                payload.shippingAddress = quote.shippingAddress();\n\n            if (quote.shippingMethod())\n                payload.shippingMethod = quote.shippingMethod();\n\n            var totals = quote.totals();\n            if (typeof totals.coupon_code != \"undefined\" && totals.coupon_code && totals.coupon_code.length > 0)\n                payload.couponCode = totals.coupon_code;\n\n            return storage.post(serviceUrl, JSON.stringify(payload));\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/get-checkout-methods.js":"define(\n    [\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Checkout/js/model/error-processor',\n        'Magento_Checkout/js/model/full-screen-loader',\n        'Magento_Checkout/js/model/quote'\n    ],\n    function (urlBuilder, storage, errorProcessor, fullScreenLoader, quote) {\n        'use strict';\n\n        var timesRequested = 0;\n\n        return function (quote, onDoneCallback)\n        {\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/get_checkout_payment_methods', {});\n\n            var payload = {\n                billingAddress: quote.billingAddress()\n            };\n\n            if (quote.shippingAddress())\n                payload.shippingAddress = quote.shippingAddress();\n\n            if (quote.shippingMethod())\n                payload.shippingMethod = quote.shippingMethod();\n\n            var totals = quote.totals();\n            if (typeof totals.coupon_code != \"undefined\" && totals.coupon_code && totals.coupon_code.length > 0)\n                payload.couponCode = totals.coupon_code;\n\n            try\n            {\n                if (!payload.billingAddress.countryId.length)\n                    return;\n\n                if (!quote.isVirtual())\n                {\n                    if (!payload.shippingAddress.countryId.length)\n                        return;\n                }\n\n                if (timesRequested > 0)\n                    return;\n            }\n            catch (e)\n            {\n                return;\n            }\n\n            timesRequested++;\n            return storage.post(serviceUrl, JSON.stringify(payload)).done(onDoneCallback);\n        };\n    }\n);\n","StripeIntegration_Payments/js/action/place-multishipping-order.js":"define(\n    [\n        'jquery',\n        'Magento_Checkout/js/model/url-builder',\n        'mage/storage',\n        'Magento_Customer/js/customer-data',\n        'Magento_Ui/js/modal/alert'\n    ],\n    function ($, urlBuilder, storage, customerData, alert) {\n        'use strict';\n\n        var showError = function(message, e)\n        {\n            alert( { content: message });\n\n            if (typeof e != \"undefined\")\n                console.error(e);\n        };\n\n        return function (callback, onAuthenticationRequired)\n        {\n            customerData.invalidate(['cart']);\n\n            var serviceUrl = urlBuilder.createUrl('/stripe/payments/place_multishipping_order', {});\n\n            return storage.post(serviceUrl)\n            .then(function(result, b, c)\n            {\n                var response = null;\n\n                try\n                {\n                    response = JSON.parse(result);\n                }\n                catch (e)\n                {\n                    return showError(\"Sorry, a server side error has occurred.\", e);\n                }\n\n                if (response.error)\n                    return showError(response.error, response.error);\n\n                if (response.redirect)\n                    return $.mage.redirect(response.redirect);\n\n                if (response.authenticate)\n                    return onAuthenticationRequired(response.authenticate);\n\n                return showError(response, response);\n            })\n            .fail(function(result)\n            {\n                return showError(\"Sorry, a server side error has occurred.\", result);\n            })\n            .always(callback);\n        };\n    }\n);\n","StripeIntegration_Payments/js/mixins/messages-mixin.js":"define([], function() {\n    'use strict';\n    return function(target) {\n        return target.extend({\n            isVisible: function () {\n                var msgs = this.messageContainer.errorMessages();\n                for (var i = 0; i < msgs.length; i++)\n                {\n                    if (typeof msgs[i] != 'string')\n                        continue;\n\n                    if (msgs[i].indexOf(\"Authentication Required: \") >= 0)\n                        return false;\n                }\n                return this.isHidden(this.messageContainer.hasMessages());\n            }\n        });\n    };\n});\n","StripeIntegration_Payments/js/mixins/checkout/payment/list.js":"define([\n    'StripeIntegration_Payments/js/helper/subscriptions',\n    'mage/translate',\n],\nfunction(\n    subscriptions,\n    $t\n) {\n    'use strict';\n    return function(target) {\n        return target.extend({\n            /**\n             * Returns payment group title\n             *\n             * @param {Object} group\n             * @returns {String}\n             */\n            getGroupTitle: function (group)\n            {\n                if (subscriptions.isSubscriptionUpdate())\n                    return $t(\"Subscription Update Review\");\n\n                var title = group().title;\n\n                if (group().isDefault() && this.paymentGroupsList().length > 1) {\n                    title = this.defaultGroupTitle;\n                }\n\n                return title;\n            },\n        });\n    };\n});\n","StripeIntegration_Payments/js/mixins/checkout/summary/grand_total.js":"define([\n    'Magento_Checkout/js/model/quote',\n    'Magento_Checkout/js/model/totals',\n    'Magento_Catalog/js/price-utils',\n    'StripeIntegration_Payments/js/view/checkout/trialing_subscriptions',\n    'StripeIntegration_Payments/js/view/checkout/summary/prorations'\n], function (\n    quote,\n    totals,\n    priceUtils,\n    trialingSubscriptions,\n    prorations\n) {\n    'use strict';\n\n    return function (grandTotal)\n    {\n        return grandTotal.extend(\n        {\n            totals: quote.getTotals(),\n\n            getValue: function()\n            {\n                var price = 0;\n\n                if (totals && totals.getSegment('grand_total'))\n                {\n                    price = parseFloat(totals.getSegment('grand_total').value);\n                    price += trialingSubscriptions().getPureValue();\n                    price += prorations().getPureValue();\n                }\n\n                return grandTotal().getFormattedPrice(price);\n            },\n\n            getBaseValue: function () {\n                var price = 0;\n\n                if (totals && totals.getSegment('base_grand_total'))\n                {\n                    price = parseFloat(totals.getSegment('base_grand_total').value);\n                    price += trialingSubscriptions().getBasePureValue();\n                    price += prorations().getBasePureValue();\n                }\n\n                return priceUtils.formatPrice(price, quote.getBasePriceFormat());\n            },\n\n            getTaxAmount: function()\n            {\n                if (totals.getSegment('tax_amount'))\n                {\n                    // Tax exclusive settings\n                    return parseFloat(totals.getSegment('tax_amount').value);\n                }\n\n                if (totals.getSegment('tax'))\n                {\n                    // Tax inclusive settings\n                    return parseFloat(totals.getSegment('tax').value);\n                }\n\n                // Core implementation should handle both cases\n                var total = this.totals();\n                if (total && total.tax_amount) {\n                    return total.tax_amount;\n                }\n\n                return 0;\n            },\n\n            getGrandTotalExclTax: function()\n            {\n                var price = 0;\n\n                if (totals.getSegment('grand_total'))\n                {\n                    price = parseFloat(totals.getSegment('grand_total').value);\n                    price -= parseFloat(this.getTaxAmount());\n                    price += trialingSubscriptions().getTaxAmount();\n                    price += trialingSubscriptions().getPureValue();\n                    price += prorations().getPureValue();\n                }\n\n                return grandTotal().getFormattedPrice(price);\n            }\n        });\n    };\n});\n","StripeIntegration_Payments/js/helper/subscriptions.js":"define(\n    [\n        'ko'\n    ],\n    function (\n        ko\n    ) {\n        'use strict';\n\n        return {\n            isSubscriptionUpdate: function()\n            {\n                return !!(window.checkoutConfig &&\n                    window.checkoutConfig.payment &&\n                    window.checkoutConfig.payment.stripe_payments &&\n                    window.checkoutConfig.payment.stripe_payments.subscriptionUpdateDetails);\n            },\n\n            getConfig: function(key)\n            {\n                var config = null;\n\n                if (window.checkoutConfig && window.checkoutConfig.payment && window.checkoutConfig.payment.stripe_payments)\n                {\n                    config = window.checkoutConfig.payment.stripe_payments;\n                }\n\n                if (!config || !config.subscriptionUpdateDetails)\n                {\n                    return null;\n                }\n\n                if (!config.subscriptionUpdateDetails[key])\n                {\n                    return \"--\";\n                }\n\n                return config.subscriptionUpdateDetails[key];\n            },\n\n            getSuccessUrl: function()\n            {\n                return this.getConfig(\"success_url\");\n            },\n\n            getCancelUrl: function()\n            {\n                return this.getConfig(\"cancel_url\");\n            },\n\n            displaySidebar: function()\n            {\n                return this.isSubscriptionUpdate();\n                    // && !window.checkoutConfig.payment.stripe_payments.subscriptionUpdateDetails.is_virtual\n                    // && window.location.href.indexOf('#payment') < 0;\n            }\n        };\n    }\n);\n","StripeIntegration_Payments/js/model/upcomingInvoice.js":"define(\n    [\n        'ko',\n        'Magento_Checkout/js/model/quote',\n        'StripeIntegration_Payments/js/action/get-upcoming-invoice',\n    ],\n    function (\n        ko,\n        quote,\n        getUpcomingInvoiceAction\n    ) {\n        'use strict';\n\n        return {\n            upcomingInvoiceRequest: null,\n            initialized: false,\n            currentTotals: null,\n            callbacks: [],\n\n            initialize: function()\n            {\n                if (this.initialized)\n                    return;\n\n                this.initialized = true;\n\n                this.watchTotals();\n                getUpcomingInvoiceAction(this.upcomingInvoiceChanged.bind(this));\n            },\n\n            watchTotals: function()\n            {\n                this.currentTotals = quote.totals();\n                var upcomingInvoiceChanged = this.upcomingInvoiceChanged.bind(this);\n                var self = this;\n\n                quote.totals.subscribe(function (totals)\n                {\n                    if (JSON.stringify(totals.total_segments) == JSON.stringify(self.currentTotals.total_segments))\n                        return;\n\n                    self.currentTotals = totals;\n\n                    getUpcomingInvoiceAction(upcomingInvoiceChanged);\n                }, self);\n            },\n\n            upcomingInvoiceChanged: function(result, outcome, response)\n            {\n                this.upcomingInvoiceRequest = {\n                    result: result,\n                    outcome: outcome,\n                    response: response\n                };\n\n                for (var i = 0; i < this.callbacks.length; i++)\n                {\n                    this.callbacks[i](result, outcome, response);\n                }\n            },\n\n            onChange: function(callback)\n            {\n                this.callbacks.push(callback);\n\n                if (this.upcominInvoiceRequest)\n                {\n                    callback(this.upcominInvoiceRequest.result, this.upcominInvoiceRequest.outcome, this.upcominInvoiceRequest.response);\n                }\n            }\n        };\n    }\n);\n","Webkul_PrivateShop/js/view/wishlist-view.js":"/**\n * Webkul Software\n *\n * @category  Webkul\n * @package   Webkul_PrivateShop\n * @author    Webkul Software Private Limited\n * @copyright Webkul Software Private Limited (https://webkul.com)\n * @license   https://store.webkul.com/license.html\n */\ndefine(\n    ['jquery'],\n    function ($) {\n        $.widget(\n            'webkul.privateProductLabel',\n            {\n                _create: function () {\n                    var self = this;\n                    $(\".price-box\").each(function () {\n                        var id= $(this).attr('data-product-id');\n                        var self1 = this;\n                        $.ajax({\n                            url: self.options.labetData.url,\n                            type: 'POST',\n                            data: { id : id},\n                            dataType: 'json',\n                            success: function (response) {\n                                if (response == 'true') {\n                                    $($(self1).parent().find(\"a\").find(\"span\").find(\"span\"))\n                                        .append(self.options.labetData.html);\n                                    $($(self1).parent().parent('.product-item-info').find(\"a\").find(\"span\").find(\"span\"))\n                                        .append(self.options.labetData.html);\n                                    $($(self1).parent().parent().find(\"div.product-item-img\").find(\"a.product-image\"))\n                                        .prepend(self.options.labetData.html);\n                                    $($(self1).parent().parent().find(\"div.product-item-photo\"))\n                                        .prepend(self.options.labetData.html);\n                                }                        \n                            }\n                        })\n                    });\n                }\n            }\n        );\n        return $.webkul.privateProductLabel;\n    }\n);","Webkul_PrivateShop/js/view/category-view.js":"/**\n * Webkul Software\n *\n * @category  Webkul\n * @package   Webkul_PrivateShop\n * @author    Webkul Software Private Limited\n * @copyright Webkul Software Private Limited (https://webkul.com)\n * @license   https://store.webkul.com/license.html\n */\ndefine(\n    ['jquery'],\n    function ($) {\n        $.widget(\n            'webkul.privateProductLabel',\n            {\n                _create: function () {\n                    var self = this;\n                    $(\".private-label-available\").each(function () {\n                        if ($(this).val() == 1) {\n                            $($(this).parent().find(\"a\").find(\"span\").find(\"span\"))\n                                .append(self.options.labetData.html);\n                            $($(this).parent().parent('.product-item-info').find(\"a\").find(\"span\").find(\"span\"))\n                                .append(self.options.labetData.html);\n\n                            $($(this).parent().parent().find(\"div.product-item-img\").find(\"a.product-image\"))\n                                .prepend(self.options.labetData.html);\n\n                            $($(this).parent().parent().find(\"div.product-item-photo\"))\n                                .prepend(self.options.labetData.html);\n                        }\n                    });\n                }\n            }\n        );\n        return $.webkul.privateProductLabel;\n    }\n);","Webkul_PrivateShop/js/view/product-view.js":"/**\n * Webkul Software\n *\n * @category  Webkul\n * @package   Webkul_PrivateShop\n * @author    Webkul Software Private Limited\n * @copyright Webkul Software Private Limited (https://webkul.com)\n * @license   https://store.webkul.com/license.html\n */\ndefine(\n    [\n        'jquery'\n    ],\n    function ($) {\n        $.widget(\n            'private.viewProduct',\n            {\n                _create: function () {\n                    var self = this;\n                    $(\".product.media\").prepend(self.options.labetData.html);\n                }\n            }\n        );\n        return $.private.viewProduct;\n    }\n);","Magento_Captcha/js/captcha.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     * @api\n     */\n    $.widget('mage.captcha', {\n        options: {\n            refreshClass: 'refreshing',\n            reloadSelector: '.captcha-reload',\n            imageSelector: '.captcha-img',\n            imageLoader: ''\n        },\n\n        /**\n         * Method binds click event to reload image\n         * @private\n         */\n        _create: function () {\n            this.element.on('click', this.options.reloadSelector, $.proxy(this.refresh, this));\n        },\n\n        /**\n         * Method triggers an AJAX request to refresh the CAPTCHA image\n         */\n        refresh: function () {\n            var imageLoader = this.options.imageLoader;\n\n            if (imageLoader) {\n                this.element.find(this.options.imageSelector).attr('src', imageLoader);\n            }\n            this.element.addClass(this.options.refreshClass);\n\n            $.ajax({\n                url: this.options.url,\n                type: 'post',\n                dataType: 'json',\n                context: this,\n                data: {\n                    'formId': this.options.type\n                },\n\n                /**\n                 * @param {Object} response\n                 */\n                success: function (response) {\n                    if (response.imgSrc) {\n                        this.element.find(this.options.imageSelector).attr('src', response.imgSrc);\n                    }\n                },\n\n                /** Complete callback. */\n                complete: function () {\n                    this.element.removeClass(this.options.refreshClass);\n                }\n            });\n        }\n    });\n\n    return $.mage.captcha;\n});\n","Magento_Captcha/js/view/checkout/loginCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Captcha/js/view/checkout/defaultCaptcha',\n    'Magento_Captcha/js/model/captchaList',\n    'Magento_Customer/js/action/login',\n    'underscore'\n],\nfunction (defaultCaptcha, captchaList, loginAction, _) {\n    'use strict';\n\n    return defaultCaptcha.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            var self = this,\n                currentCaptcha;\n\n            this._super();\n            currentCaptcha = captchaList.getCaptchaByFormId(this.formId);\n\n            if (currentCaptcha != null) {\n                currentCaptcha.setIsVisible(true);\n                this.setCurrentCaptcha(currentCaptcha);\n\n                loginAction.registerLoginCallback(function (loginData) {\n                    if (loginData['captcha_form_id'] &&\n                        loginData['captcha_form_id'] === self.formId &&\n                        self.isRequired()\n                    ) {\n                        _.defer(self.refresh.bind(self));\n                    }\n                });\n            }\n        }\n    });\n});\n","Magento_Captcha/js/view/checkout/defaultCaptcha.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiComponent',\n    'Magento_Captcha/js/model/captcha',\n    'Magento_Captcha/js/model/captchaList',\n    'Magento_Customer/js/customer-data',\n    'underscore'\n], function ($, Component, Captcha, captchaList, customerData, _) {\n    'use strict';\n\n    var captchaConfig;\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Captcha/checkout/captcha'\n        },\n        dataScope: 'global',\n        currentCaptcha: null,\n        subscribedFormIds: [],\n\n        /**\n         * @return {*}\n         */\n        captchaValue: function () {\n            return this.currentCaptcha.getCaptchaValue();\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            if (window[this.configSource] && window[this.configSource].captcha) {\n                captchaConfig = window[this.configSource].captcha;\n                $.each(captchaConfig, function (formId, captchaData) {\n                    var captcha;\n\n                    captchaData.formId = formId;\n                    captcha = Captcha(captchaData);\n                    this.checkCustomerData(formId, customerData.get('captcha')(), captcha);\n                    this.subscribeCustomerData(formId, captcha);\n                    captchaList.add(captcha);\n                }.bind(this));\n            }\n        },\n\n        /**\n         * Check customer data for captcha configuration.\n         *\n         * @param {String} formId\n         * @param {Object} captchaData\n         * @param {Object} captcha\n         */\n        checkCustomerData: function (formId, captchaData, captcha) {\n            if (!_.isEmpty(captchaData) &&\n                !_.isEmpty(captchaData[formId]) &&\n                captchaData[formId].timestamp > captcha.timestamp\n            ) {\n                if (!captcha.isRequired() && captchaData[formId].isRequired) {\n                    captcha.refresh();\n                }\n                captcha.isRequired(captchaData[formId].isRequired);\n                captcha.timestamp = captchaData[formId].timestamp;\n            }\n        },\n\n        /**\n         * Subscribe for customer data updates.\n         *\n         * @param {String} formId\n         * @param {Object} captcha\n         */\n        subscribeCustomerData: function (formId, captcha) {\n            if (this.subscribedFormIds.includes(formId) === false) {\n                this.subscribedFormIds.push(formId);\n                customerData.get('captcha').subscribe(function (captchaData) {\n                    this.checkCustomerData(formId, captchaData, captcha);\n                }.bind(this));\n            }\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        getIsLoading: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.isLoading : false;\n        },\n\n        /**\n         * @return {null|Object}\n         */\n        getCurrentCaptcha: function () {\n            return this.currentCaptcha;\n        },\n\n        /**\n         * @param {Object} captcha\n         */\n        setCurrentCaptcha: function (captcha) {\n            this.currentCaptcha = captcha;\n        },\n\n        /**\n         * @return {String|null}\n         */\n        getFormId: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getFormId() : null;\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        getIsVisible: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsVisible() : false;\n        },\n\n        /**\n         * @param {Boolean} flag\n         */\n        setIsVisible: function (flag) {\n            this.currentCaptcha.setIsVisible(flag);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isRequired: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsRequired() : false;\n        },\n\n        /**\n         * Set isRequired on current captcha model.\n         *\n         * @param {Boolean} flag\n         */\n        setIsRequired: function (flag) {\n            this.currentCaptcha.setIsRequired(flag);\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isCaseSensitive: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getIsCaseSensitive() : false;\n        },\n\n        /**\n         * @return {String|Number|null}\n         */\n        imageHeight: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getImageHeight() : null;\n        },\n\n        /**\n         * @return {String|null}\n         */\n        getImageSource: function () {\n            return this.currentCaptcha !== null ? this.currentCaptcha.getImageSource() : null;\n        },\n\n        /**\n         * Refresh captcha.\n         */\n        refresh: function () {\n            this.currentCaptcha.refresh();\n        }\n    });\n});\n","Magento_Captcha/js/action/refresh.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery', 'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n\n    return function (refreshUrl, formId, imageSource) {\n        return $.ajax({\n            url: urlBuilder.build(refreshUrl),\n            type: 'POST',\n            data: JSON.stringify({\n                'formId': formId\n            }),\n            global: false,\n            contentType: 'application/json'\n        }).done(\n            function (response) {\n                if (response.imgSrc) {\n                    imageSource(response.imgSrc);\n                }\n            }\n        );\n    };\n});\n","Magento_Captcha/js/model/captchaList.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery'], function ($) {\n    'use strict';\n\n    var captchaList = [];\n\n    return {\n        /**\n         * @param {Object} captcha\n         */\n        add: function (captcha) {\n            captchaList.push(captcha);\n        },\n\n        /**\n         * @param {String} formId\n         * @return {Object}\n         */\n        getCaptchaByFormId: function (formId) {\n            var captcha = null;\n\n            $.each(captchaList, function (key, item) {\n                if (formId === item.formId) {\n                    captcha = item;\n\n                    return false;\n                }\n            });\n\n            return captcha;\n        },\n\n        /**\n         * @return {Array}\n         */\n        getCaptchaList: function () {\n            return captchaList;\n        }\n    };\n});\n","Magento_Captcha/js/model/captcha.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_Captcha/js/action/refresh'\n], function ($, ko, refreshAction) {\n    'use strict';\n\n    return function (captchaData) {\n        return {\n            formId: captchaData.formId,\n            imageSource: ko.observable(captchaData.imageSrc),\n            visibility: ko.observable(false),\n            captchaValue: ko.observable(null),\n            isRequired: ko.observable(captchaData.isRequired),\n            isCaseSensitive: captchaData.isCaseSensitive,\n            imageHeight: captchaData.imageHeight,\n            refreshUrl: captchaData.refreshUrl,\n            isLoading: ko.observable(false),\n            timestamp: null,\n\n            /**\n             * @return {String}\n             */\n            getFormId: function () {\n                return this.formId;\n            },\n\n            /**\n             * @param {String} formId\n             */\n            setFormId: function (formId) {\n                this.formId = formId;\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsVisible: function () {\n                return this.visibility();\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsVisible: function (flag) {\n                this.visibility(flag);\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsRequired: function () {\n                return this.isRequired();\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsRequired: function (flag) {\n                this.isRequired(flag);\n            },\n\n            /**\n             * @return {Boolean}\n             */\n            getIsCaseSensitive: function () {\n                return this.isCaseSensitive;\n            },\n\n            /**\n             * @param {Boolean} flag\n             */\n            setIsCaseSensitive: function (flag) {\n                this.isCaseSensitive = flag;\n            },\n\n            /**\n             * @return {String|Number}\n             */\n            getImageHeight: function () {\n                return this.imageHeight;\n            },\n\n            /**\n             * @param {String|Number}height\n             */\n            setImageHeight: function (height) {\n                this.imageHeight = height;\n            },\n\n            /**\n             * @return {String}\n             */\n            getImageSource: function () {\n                return this.imageSource;\n            },\n\n            /**\n             * @param {String} imageSource\n             */\n            setImageSource: function (imageSource) {\n                this.imageSource(imageSource);\n            },\n\n            /**\n             * @return {String}\n             */\n            getRefreshUrl: function () {\n                return this.refreshUrl;\n            },\n\n            /**\n             * @param {String} url\n             */\n            setRefreshUrl: function (url) {\n                this.refreshUrl = url;\n            },\n\n            /**\n             * @return {*}\n             */\n            getCaptchaValue: function () {\n                return this.captchaValue;\n            },\n\n            /**\n             * @param {*} value\n             */\n            setCaptchaValue: function (value) {\n                this.captchaValue(value);\n            },\n\n            /**\n             * Refresh captcha.\n             */\n            refresh: function () {\n                var refresh,\n                    self = this;\n\n                this.isLoading(true);\n\n                refresh = refreshAction(this.getRefreshUrl(), this.getFormId(), this.getImageSource());\n                $.when(refresh).done(function () {\n                    self.isLoading(false);\n                });\n            }\n        };\n    };\n});\n","Magento_Sales/js/gift-message.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.giftMessage', {\n        options: {\n            rowPrefix: '#order-item-row-', // Selector prefix for item's row in the table.\n            linkPrefix: '#order-item-gift-message-link-', // Selector prefix for the 'Gift Message' link.\n            duration: 100, // Toggle duration.\n            expandedClass: 'expanded', // Class added/removed to/from the 'Gift Message' link.\n            expandedContentClass: 'expanded-content', // Class added/removed to/from the 'Gift Message' content.\n            lastClass: 'last' // Class added/removed to/from the last item's row in the products table.\n        },\n\n        /**\n         * Bind a click handler on the widget's element to toggle the gift message.\n         * @private\n         */\n        _create: function () {\n            this.element.on('click', $.proxy(this._toggleGiftMessage, this));\n        },\n\n        /**\n         * Toggle the display of the item's corresponding gift message.\n         * @private\n         * @param {jQuery.Event} event - Click event.\n         */\n        _toggleGiftMessage: function (event) {\n            var element = $(event.target), // Click target. The 'Gift Message' link or 'Close' button.\n                options = this.options, // Cached widget options.\n                itemId = element.data('item-id'), // The individual item's numeric id.\n                link = $(options.linkPrefix + itemId), // The 'Gift Message' expandable link.\n                row = $(options.rowPrefix + itemId), // The item's row in the products table.\n                region = $('#' + element.attr('aria-controls')); // The gift message container region.\n\n            region.toggleClass(options.expandedContentClass, options.duration, function () {\n                if (region.attr('aria-expanded') === 'true') {\n                    region.attr('aria-expanded', 'false');\n\n                    if (region.hasClass(options.lastClass)) {\n                        row.addClass(options.lastClass);\n                    }\n                } else {\n                    region.attr('aria-expanded', 'true');\n\n                    if (region.hasClass(options.lastClass)) {\n                        row.removeClass(options.lastClass);\n                    }\n                }\n                link.toggleClass(options.expandedClass);\n            });\n            event.preventDefault(); // Prevent event propagation and avoid going to the link's href.\n        }\n    });\n\n    return $.mage.giftMessage;\n});\n","Magento_Sales/js/orders-returns.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.ordersReturns', {\n        options: {\n            zipCode: '#oar-zip', // Search by zip code.\n            emailAddress: '#oar-email', // Search by email address.\n            searchType: '#quick-search-type-id' // Search element used for choosing between the two.\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            $(this.options.searchType).on('change', $.proxy(this._showIdentifyBlock, this)).trigger('change');\n        },\n\n        /**\n         * Show either the search by zip code option or the search by email address option.\n         * @private\n         * @param {jQuery.Event} e - Change event. Event target value is either 'zip' or 'email'.\n         */\n        _showIdentifyBlock: function (e) {\n            var value = $(e.target).val();\n\n            $(this.options.zipCode).toggle(value === 'zip');\n            $(this.options.emailAddress).toggle(value === 'email');\n        }\n    });\n\n    return $.mage.ordersReturns;\n});\n","Magento_Sales/js/view/last-ordered-items.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    'underscore'\n], function (Component, customerData, _) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            isShowAddToCart: false\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.lastOrderedItems = customerData.get('last-ordered-items');\n            this.lastOrderedItems.subscribe(this.checkSalableItems.bind(this));\n            this.checkSalableItems();\n\n            return this;\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('isShowAddToCart');\n\n            return this;\n        },\n\n        /**\n         * Check if items is_saleable and change add to cart button visibility.\n         */\n        checkSalableItems: function () {\n            var isShowAddToCart = _.some(this.lastOrderedItems().items, {\n                'is_saleable': true\n            });\n\n            this.isShowAddToCart(isShowAddToCart);\n        }\n    });\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/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/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/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/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/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        if (!$.cookieStorage.isSet('mage-cache-sessid')) {\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            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                sectionData = storage.get(sectionName);\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/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/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/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/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/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/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/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        /** Init popup login window */\n        setModalElement: 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/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/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/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/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/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/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","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_Directory/js/region-updater.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/template',\n    'underscore',\n    'jquery-ui-modules/widget',\n    'mage/validation'\n], function ($, mageTemplate, _) {\n    'use strict';\n\n    $.widget('mage.directoryRegionUpdater', {\n        options: {\n            regionTemplate:\n                '<option value=\"<%- data.value %>\" <% if (data.isSelected) { %>selected=\"selected\"<% } %>>' +\n                '<%- data.title %>' +\n                '</option>',\n            isRegionRequired: true,\n            isZipRequired: true,\n            isCountryRequired: true,\n            currentRegion: null,\n            isMultipleCountriesAllowed: true\n        },\n\n        /**\n         *\n         * @private\n         */\n        _create: function () {\n            this._initCountryElement();\n\n            this.currentRegionOption = this.options.currentRegion;\n            this.regionTmpl = mageTemplate(this.options.regionTemplate);\n\n            this._updateRegion(this.element.find('option:selected').val());\n\n            $(this.options.regionListId).on('change', $.proxy(function (e) {\n                this.setOption = false;\n                this.currentRegionOption = $(e.target).val();\n            }, this));\n\n            $(this.options.regionInputId).on('focusout', $.proxy(function () {\n                this.setOption = true;\n            }, this));\n        },\n\n        /**\n         *\n         * @private\n         */\n        _initCountryElement: function () {\n\n            if (this.options.isMultipleCountriesAllowed) {\n                this.element.parents('div.field').show();\n                this.element.on('change', $.proxy(function (e) {\n                    // clear region inputs on country change\n                    $(this.options.regionListId).val('');\n                    $(this.options.regionInputId).val('');\n                    this._updateRegion($(e.target).val());\n                }, this));\n\n                if (this.options.isCountryRequired) {\n                    this.element.addClass('required-entry');\n                    this.element.parents('div.field').addClass('required');\n                }\n            } else {\n                this.element.parents('div.field').hide();\n            }\n        },\n\n        /**\n         * Remove options from dropdown list\n         *\n         * @param {Object} selectElement - jQuery object for dropdown list\n         * @private\n         */\n        _removeSelectOptions: function (selectElement) {\n            selectElement.find('option').each(function (index) {\n                if (index) {\n                    $(this).remove();\n                }\n            });\n        },\n\n        /**\n         * Render dropdown list\n         * @param {Object} selectElement - jQuery object for dropdown list\n         * @param {String} key - region code\n         * @param {Object} value - region object\n         * @private\n         */\n        _renderSelectOption: function (selectElement, key, value) {\n            selectElement.append($.proxy(function () {\n                var name = value.name.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, '\\\\$&'),\n                    tmplData,\n                    tmpl;\n\n                if (value.code && $(name).is('span')) {\n                    key = value.code;\n                    value.name = $(name).text();\n                }\n\n                tmplData = {\n                    value: key,\n                    title: value.name,\n                    isSelected: false\n                };\n\n                if (this.options.defaultRegion === key) {\n                    tmplData.isSelected = true;\n                }\n\n                tmpl = this.regionTmpl({\n                    data: tmplData\n                });\n\n                return $(tmpl);\n            }, this));\n        },\n\n        /**\n         * Takes clearError callback function as first option\n         * If no form is passed as option, look up the closest form and call clearError method.\n         * @private\n         */\n        _clearError: function () {\n            var args = ['clearError', this.options.regionListId, this.options.regionInputId, this.options.postcodeId];\n\n            if (this.options.clearError && typeof this.options.clearError === 'function') {\n                this.options.clearError.call(this);\n            } else {\n                if (!this.options.form) {\n                    this.options.form = this.element.closest('form').length ? $(this.element.closest('form')[0]) : null;\n                }\n\n                this.options.form = $(this.options.form);\n\n                this.options.form && this.options.form.data('validator') &&\n                this.options.form.validation.apply(this.options.form, _.compact(args));\n\n                // Clean up errors on region & zip fix\n                $(this.options.regionInputId).removeClass('mage-error').parent().find('[generated]').remove();\n                $(this.options.regionListId).removeClass('mage-error').parent().find('[generated]').remove();\n                $(this.options.postcodeId).removeClass('mage-error').parent().find('[generated]').remove();\n            }\n        },\n\n        /**\n         * Update dropdown list based on the country selected\n         *\n         * @param {String} country - 2 uppercase letter for country code\n         * @private\n         */\n        _updateRegion: function (country) {\n            // Clear validation error messages\n            var regionList = $(this.options.regionListId),\n                regionInput = $(this.options.regionInputId),\n                postcode = $(this.options.postcodeId),\n                label = regionList.parent().siblings('label'),\n                container = regionList.parents('div.field'),\n                regionsEntries,\n                regionId,\n                regionData;\n\n            this._clearError();\n            this._checkRegionRequired(country);\n\n            // Populate state/province dropdown list if available or use input box\n            if (this.options.regionJson[country]) {\n                this._removeSelectOptions(regionList);\n                regionsEntries = _.pairs(this.options.regionJson[country]);\n                $.each(regionsEntries, $.proxy(function (key, value) {\n                    regionData = value[1];\n                    regionId = regionData.id;\n                    this._renderSelectOption(regionList, regionId.toString(), regionData);\n                }, this));\n\n                if (this.currentRegionOption) {\n                    regionList.val(this.currentRegionOption);\n                }\n\n                if (this.setOption) {\n                    regionList.find('option').filter(function () {\n                        return this.text === regionInput.val();\n                    }).attr('selected', true);\n                }\n\n                if (this.options.isRegionRequired) {\n                    regionList.addClass('required-entry').removeAttr('disabled');\n                    container.addClass('required').show();\n                } else {\n                    regionList.removeClass('required-entry validate-select').removeAttr('data-validate');\n                    container.removeClass('required');\n\n                    if (!this.options.optionalRegionAllowed) { //eslint-disable-line max-depth\n                        regionList.hide();\n                        container.hide();\n                    } else {\n                        regionList.removeAttr('disabled').show();\n                    }\n                }\n\n                regionList.show();\n                regionInput.hide();\n                label.attr('for', regionList.attr('id'));\n            } else {\n                this._removeSelectOptions(regionList);\n\n                if (this.options.isRegionRequired) {\n                    regionInput.addClass('required-entry').removeAttr('disabled');\n                    container.addClass('required').show();\n                } else {\n                    if (!this.options.optionalRegionAllowed) { //eslint-disable-line max-depth\n                        regionInput.attr('disabled', 'disabled');\n                        container.hide();\n                    }\n                    container.removeClass('required');\n                    regionInput.removeClass('required-entry');\n                }\n\n                regionList.removeClass('required-entry').prop('disabled', 'disabled').hide();\n                regionInput.show();\n                label.attr('for', regionInput.attr('id'));\n            }\n\n            // If country is in optionalzip list, make postcode input not required\n            if (this.options.isZipRequired) {\n                $.inArray(country, this.options.countriesWithOptionalZip) >= 0 ?\n                    postcode.removeClass('required-entry').closest('.field').removeClass('required') :\n                    postcode.addClass('required-entry').closest('.field').addClass('required');\n            }\n\n            // Add defaultvalue attribute to state/province select element\n            regionList.attr('defaultvalue', this.options.defaultRegion);\n            this.options.form.find('[type=\"submit\"]').removeAttr('disabled').show();\n        },\n\n        /**\n         * Check if the selected country has a mandatory region selection\n         *\n         * @param {String} country - Code of the country - 2 uppercase letter for country code\n         * @private\n         */\n        _checkRegionRequired: function (country) {\n            var self = this;\n\n            this.options.isRegionRequired = false;\n            $.each(this.options.regionJson.config['regions_required'], function (index, elem) {\n                if (elem === country) {\n                    self.options.isRegionRequired = true;\n                }\n            });\n        }\n    });\n\n    return $.mage.directoryRegionUpdater;\n});\n","Magento_Theme/js/cookie-status.js":"define([\n    'jquery',\n    'Magento_Ui/js/modal/modal',\n    'mage/translate'\n], function ($, modal) {\n    'use strict';\n\n    $.widget('mage.cookieStatus', {\n        options: {\n            type: 'popup',\n            responsive: true,\n            innerScroll: true,\n            autoOpen: true,\n            buttons: [{\n                text: $.mage.__('Close'),\n                class: 'cookie-status',\n\n                /**\n                 * Callback for click event\n                 */\n                click: function () {\n                    this.closeModal();\n                }\n            }]\n        },\n\n        /**\n         * Init object\n         * @private\n         */\n        _init: function () {\n\n            if (!navigator.cookieEnabled) {\n                modal(this.options, $('#cookie-status'));\n            }\n        }\n    });\n\n    return $.mage.cookieStatus;\n});\n","Magento_Theme/js/row-builder.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * JQuery UI Widget declaration: 'mage.rowBuilder'\n *\n * @api\n */\ndefine([\n    'jquery',\n    'mage/template',\n    'jquery-ui-modules/widget'\n], function ($, mageTemplate) {\n    'use strict';\n\n    $.widget('mage.rowBuilder', {\n\n        /**\n         * options with default values for setting up the template\n         */\n        options: {\n            //Default template options\n            rowTemplate: '#template-registrant',\n            rowContainer: '#registrant-container',\n            //Row index used by the template rows.\n            rowIndex: 0,\n            //Row count: Should not be set externally\n            rowCount: 0,\n            rowParentElem: '<li></li>',\n            rowContainerClass: 'fields',\n            addRowBtn: '#add-registrant-button',\n            btnRemoveIdPrefix: 'btn-remove',\n            btnRemoveSelector: '.btn-remove',\n            rowIdPrefix: 'row',\n            //This class is added to rows added after the first one. Adds the dotted separator\n            additionalRowClass: 'add-row',\n\n            /*\n             This is provided during widget instantiation. eg :\n             formDataPost : {\"formData\":formData,\"templateFields\":['field1-name','field2-name'] }\n             -\"formData\" is the multi-dimensional array of form field values : [['a','b'],['c','b']]\n             received from the server and encoded\n             -\"templateFields\" are the input fields in the template with index suffixed after the field name\n             eg field1-name{index}\n             */\n            formDataPost: null,\n            //Default selectors for add element of a template\n            addEventSelector: 'button',\n            //Default selectors for remove markup elements of a template\n            remEventSelector: 'a',\n            //This option allows adding first row delete option and a row separator\n            hideFirstRowAddSeparator: true,\n            //Max rows - This option should be set when instantiating the widget\n            maxRows: 1000,\n            maxRowsMsg: '#max-registrant-message'\n        },\n\n        /**\n         * Initialize create\n         * @private\n         */\n        _create: function () {\n            this.rowTemplate = mageTemplate(this.options.rowTemplate);\n\n            this.options.rowCount = this.options.rowIndex = 0;\n\n            //On document ready related tasks\n            $($.proxy(this.ready, this));\n\n            //Binding template-wide events handlers for adding and removing rows\n            this.element.on(\n                'click',\n                this.options.addEventSelector + this.options.addRowBtn,\n                $.proxy(this.handleAdd, this)\n            );\n            this.element.on(\n                'click',\n                this.options.remEventSelector + this.options.btnRemoveSelector,\n                $.proxy(this.handleRemove, this)\n            );\n        },\n\n        /**\n         * Initialize template\n         * @public\n         */\n        ready: function () {\n            if (this.options.formDataPost &&\n                this.options.formDataPost.formData &&\n                this.options.formDataPost.formData.length\n            ) {\n                this.processFormDataArr(this.options.formDataPost);\n            } else if (this.options.rowIndex === 0 && this.options.maxRows !== 0) {\n                //If no form data , then add default row\n                this.addRow(0);\n            }\n        },\n\n        /**\n         * Process and loop through all row data to create preselected values. This is used for any error on submit.\n         * For complex implementations the inheriting widget can override this behavior\n         * @public\n         * @param {Object} formDataArr\n         */\n        processFormDataArr: function (formDataArr) {\n            var formData = formDataArr.formData,\n                templateFields = formDataArr.templateFields,\n                formRow,\n                i, j;\n\n            for (i = this.options.rowIndex = 0; i < formData.length; this.options.rowIndex = i++) {\n                this.addRow(i);\n\n                formRow = formData[i];\n\n                for (j = 0; j < formRow.length; j++) {\n                    this.setFieldById(templateFields[j] + i, formRow[j]);\n                }\n            }\n\n        },\n\n        /**\n         * Initialize and create markup for template row. Add it to the parent container.\n         * The template processing will substitute row index at all places marked with _index_ in the template\n         * using the template\n         * @public\n         * @param {Number} index - current index/count of the created template. This will be used as the id\n         * @return {*}\n         */\n        addRow: function (index) {\n            var row = $(this.options.rowParentElem),\n                tmpl;\n\n            row.addClass(this.options.rowContainerClass).attr('id', this.options.rowIdPrefix + index);\n\n            tmpl = this.rowTemplate({\n                data: {\n                    _index_: index\n                }\n            });\n\n            $(tmpl).appendTo(row);\n\n            $(this.options.rowContainer).append(row).trigger('contentUpdated');\n\n            row.addClass(this.options.additionalRowClass);\n\n            //Remove 'delete' link and additionalRowClass for first row\n            if (this.options.rowIndex === 0 && this.options.hideFirstRowAddSeparator) {\n                $('#' + this._esc(this.options.btnRemoveIdPrefix) + '0').remove();\n                $('#' + this._esc(this.options.rowIdPrefix) + '0').removeClass(this.options.additionalRowClass);\n            }\n\n            this.maxRowCheck(++this.options.rowCount);\n\n            return row;\n        },\n\n        /**\n         * Remove return item information row\n         * @public\n         * @param {*} rowIndex - return item information row index\n         * @return {Boolean}\n         */\n        removeRow: function (rowIndex) {\n            $('#' + this._esc(this.options.rowIdPrefix) + rowIndex).remove();\n            this.maxRowCheck(--this.options.rowCount);\n\n            return false;\n        },\n\n        /**\n         * Function to check if maximum rows are exceeded and render/hide maxMsg and Add btn\n         * @public\n         * @param {Number} rowIndex\n         */\n        maxRowCheck: function (rowIndex) {\n            var addRowBtn = $(this.options.addRowBtn),\n                maxRowMsg = $(this.options.maxRowsMsg);\n\n            //liIndex starts from 0\n            if (rowIndex >= this.options.maxRows) {\n                addRowBtn.hide();\n                maxRowMsg.show();\n            } else if (addRowBtn.is(':hidden')) {\n                addRowBtn.show();\n                maxRowMsg.hide();\n            }\n        },\n\n        /**\n         * Set the value on given element\n         * @public\n         * @param {String} domId\n         * @param {String} value\n         */\n        setFieldById: function (domId, value) {\n            var x = $('#' + this._esc(domId));\n\n            if (x.length) {\n\n                if (x.is(':checkbox')) {\n                    x.attr('checked', true);\n                } else if (x.is('option')) {\n                    x.attr('selected', 'selected');\n                } else {\n                    x.val(value);\n                }\n            }\n        },\n\n        /**\n         * Delegated handler for adding a row\n         * @public\n         * @return {Boolean}\n         */\n        handleAdd: function () {\n            this.addRow(++this.options.rowIndex);\n\n            return false;\n        },\n\n        /**\n         * Delegated handler for removing a selected row\n         * @public\n         * @param {Object} e - Native event object\n         * @return {Boolean}\n         */\n        handleRemove: function (e) {\n            this.removeRow($(e.currentTarget).closest('[id^=\"' + this.options.btnRemoveIdPrefix + '\"]')\n                .attr('id').replace(this.options.btnRemoveIdPrefix, ''));\n\n            return false;\n        },\n\n        /**\n         * Utility function to add escape chars for jquery selector strings\n         * @private\n         * @param {String} str - String to be processed\n         * @return {String}\n         */\n        _esc: function (str) {\n            return str ? str.replace(/([ ;&,.+*~\\':\"!\\^$\\[\\]()=>|\\/@])/g, '\\\\$1') : str;\n        }\n    });\n\n    return $.mage.rowBuilder;\n});\n","Magento_Theme/js/theme.js":"/**\n * Copyright \u00a9 2015 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\nrequire([\n    'jquery',\n    'mage/smart-keyboard-handler',\n    'mage/mage',\n    'domReady!'\n], function ($, keyboardHandler) {\n    'use strict';\n    $(document).ready(function(){\n        $('.cart-summary').mage('sticky', {\n            container: '#maincontent'\n        });\n\n        $('.panel.header .header.links').clone().appendTo('#store\\\\.links');\n    });\n    keyboardHandler.apply();\n});\nrequire([\n    'jquery'\n], function ($) {\n    (function() {\n        var ev = new $.Event('classadded'),\n            orig = $.fn.addClass;\n        $.fn.addClass = function() {\n            $(this).trigger(ev, arguments);\n            return orig.apply(this, arguments);\n        }\n    })();\n    $.fn.extend({\n        scrollToMe: function(){\n            if($(this).length){\n                var top = $(this).offset().top - 100;\n                $('html,body').animate({scrollTop: top}, 300);\n            }\n        },\n        scrollToJustMe: function(){\n            if($(this).length){\n                var top = jQuery(this).offset().top;\n                $('html,body').animate({scrollTop: top}, 300);\n            }\n        }\n    });\n    $(document).ready(function(){\n        var windowScroll_t;\n        $(window).scroll(function(){\n            clearTimeout(windowScroll_t);\n            windowScroll_t = setTimeout(function(){\n                if(jQuery(this).scrollTop() > 100){\n                    $('#totop').fadeIn();\n                }else{\n                    $('#totop').fadeOut();\n                }\n            }, 500);\n        });\n        $('#totop').off(\"click\").on(\"click\",function(){\n            $('html, body').animate({scrollTop: 0}, 600);\n        });\n        if ($('body').hasClass('checkout-cart-index')) {\n            if ($('#co-shipping-method-form .fieldset.rates').length > 0 && $('#co-shipping-method-form .fieldset.rates :checked').length === 0) {\n                $('#block-shipping').on('collapsiblecreate', function () {\n                    $('#block-shipping').collapsible('forceActivate');\n                });\n            }\n        }\n        $(\".products-grid .weltpixel-quickview\").each(function(){\n            $(this).parent().parent().addClass('has-quickview');\n            if($(this).parents('.product-type-advanced').find(\".product-item-photo.porto-tb-featured-image .icon-absolute\").length > 0){\n              $(this).appendTo($(this).parents('.product-type-advanced').find(\".product-item-photo .porto-tb-featured-image .product-item-inner .product-item-actions\"));\n            }else{\n              $(this).appendTo($(this).parent().parent().children(\".product-item-photo\"));\n            }\n        });\n        $(\".word-rotate\").each(function() {\n\n            var $this = $(this),\n                itemsWrapper = $(this).find(\".word-rotate-items\"),\n                items = itemsWrapper.find(\"> span\"),\n                firstItem = items.eq(0),\n                firstItemClone = firstItem.clone(),\n                itemHeight = 0,\n                currentItem = 1,\n                currentTop = 0;\n\n            itemHeight = firstItem.height();\n\n            itemsWrapper.append(firstItemClone);\n\n            $this\n                .height(itemHeight)\n                .addClass(\"active\");\n\n            setInterval(function() {\n                currentTop = (currentItem * itemHeight);\n\n                itemsWrapper.animate({\n                    top: -(currentTop) + \"px\"\n                }, 300, function() {\n                    currentItem++;\n                    if(currentItem > items.length) {\n                        itemsWrapper.css(\"top\", 0);\n                        currentItem = 1;\n                    }\n                });\n\n            }, 2000);\n\n        });\n        $(\".top-links-icon\").off(\"click\").on(\"click\", function(e){\n            if($(this).parent().children(\"ul.links\").hasClass(\"show\")) {\n                $(this).parent().children(\"ul.links\").removeClass(\"show\");\n            } else {\n                $(this).parent().children(\"ul.links\").addClass(\"show\");\n            }\n            e.stopPropagation();\n        });\n        $(\".top-links-icon\").parent().click(function(e){\n            e.stopPropagation();\n        });\n        $(\".search-toggle-icon\").click(function(e){\n            if($(this).parent().children(\".block-search\").hasClass(\"show\")) {\n                $(this).parent().children(\".block-search\").removeClass(\"show\");\n                $(this).removeClass('open');\n            } else {\n                $(this).parent().children(\".block-search\").addClass(\"show\");\n                $(this).addClass('open');\n            }\n            e.stopPropagation();\n        });\n        $(\".search-toggle-icon\").parent().click(function(e){\n            e.stopPropagation();\n        });\n        $(\"html,body\").click(function(){\n            $(\".search-toggle-icon\").parent().children(\".block-search\").removeClass(\"show\");\n            $('.autocomplete-suggestions').hide();\n            $(\".search-toggle-icon\").removeClass('open');\n            $(\".top-links-icon\").parent().children(\"ul.links\").removeClass(\"show\");\n        });\n\n        /********************* Qty Holder **************************/\n        $(document).on(\"click\", \".qtyplus\", function(e) {\n            // Stop acting like a button\n            e.preventDefault();\n            // Get its current value\n            var currentVal = parseInt($(this).parents('form').find('input[name=\"qty\"]').val());\n            // If is not undefined\n            if (!isNaN(currentVal)) {\n                // Increment\n                $(this).parents('form').find('input[name=\"qty\"]').val(currentVal + 1);\n            } else {\n                // Otherwise put a 0 there\n                $(this).parents('form').find('input[name=\"qty\"]').val(0);\n            }\n        });\n        // This button will decrement the value till 0\n        $(document).on(\"click\", \".qtyminus\", function(e) {\n            // Stop acting like a button\n            e.preventDefault();\n            // Get the field name\n            fieldName = $(this).attr('field');\n            // Get its current value\n            var currentVal = parseInt($(this).parents('form').find('input[name=\"qty\"]').val());\n            // If it isn't undefined or its greater than 0\n            if (!isNaN(currentVal) && currentVal > 0) {\n                // Decrement one\n                $(this).parents('form').find('input[name=\"qty\"]').val(currentVal - 1);\n            } else {\n                // Otherwise put a 0 there\n                $(this).parents('form').find('input[name=\"qty\"]').val(0);\n            }\n        });\n        $(\".qty-inc\").unbind('click').click(function(){\n            if($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").is(':enabled')){\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val((+$(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() + 1) || 0);\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").trigger('change');\n                $(this).focus();\n            }\n        });\n        $(\".qty-dec\").unbind('click').click(function(){\n            if($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").is(':enabled')){\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val(($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() - 1 > 0) ? ($(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").val() - 1) : 0);\n                $(this).parents('.field.qty,.control.qty').find(\"input.input-text.qty\").trigger('change');\n                $(this).focus();\n            }\n        });\n    });\n});\nrequire([\n    'jquery',\n    'lazyload'\n], function ($) {\n    $(document).ready(function(){\n        $(\"img.porto-lazyload:not(.porto-lazyload-loaded)\").lazyload({effect:\"fadeIn\", effect_speed: 400 });\n        if ($('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').length) {\n            $('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('initialized.owl.carousel', function() {\n                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n            });\n            $('.porto-lazyload:not(.porto-lazyload-loaded)').closest('.owl-carousel').on('changed.owl.carousel', function() {\n                $(this).find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n            });\n        }\n        window.setTimeout(function(){\n            $('.sidebar-filterproducts').find('.porto-lazyload:not(.porto-lazyload-loaded)').trigger('appear');\n        },500);\n    });\n});\n","Magento_Theme/js/view/add-home-breadcrumb.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/* eslint-disable max-nested-callbacks, no-undef */\ndefine([\n    'jquery',\n    'Magento_Theme/js/model/breadcrumb-list',\n    'mage/translate'\n], function ($, breadcrumbList) {\n    'use strict';\n\n    /**\n     * @return {Object}\n     */\n    var homeCrumb = function () {\n        return {\n            name: 'home',\n            label: $.mage.__('Home'),\n            title: $.mage.__('Go to Home Page'),\n            link: BASE_URL || ''\n        };\n    };\n\n    return function (breadcrumb) {\n\n        breadcrumbList.unshift(homeCrumb());\n\n        return breadcrumb;\n    };\n});\n","Magento_Theme/js/view/breadcrumbs.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/template',\n    'Magento_Theme/js/model/breadcrumb-list',\n    'text!Magento_Theme/templates/breadcrumbs.html',\n    'jquery-ui-modules/widget'\n], function ($, mageTemplate, breadcrumbList, tpl) {\n    'use strict';\n\n    /**\n     * Breadcrumb Widget.\n     */\n    $.widget('mage.breadcrumbs', {\n\n        /** @inheritdoc */\n        _init: function () {\n            this._super();\n            this._render();\n        },\n\n        /**\n         * Render breadcrumb.\n         *\n         * @private\n         */\n        _render: function () {\n            var html,\n                crumbs = breadcrumbList,\n                template = mageTemplate(tpl);\n\n            this._decorate(crumbs);\n\n            html = template({\n                'breadcrumbs': crumbs\n            });\n\n            if (html.length) {\n                $(this.element).html(html);\n            }\n        },\n\n        /**\n         * Decorate list.\n         *\n         * @param {Array} list\n         * @private\n         */\n        _decorate: function (list) {\n\n            if (list.length) {\n                list[0].first = true;\n            }\n\n            if (list.length > 1) {\n                list[list.length - 1].last = true;\n            }\n        }\n    });\n\n    return $.mage.breadcrumbs;\n});\n","Magento_Theme/js/view/messages.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    'uiComponent',\n    'Magento_Customer/js/customer-data',\n    'underscore',\n    'escaper',\n    'jquery/jquery-storageapi'\n], function ($, Component, customerData, _, escaper) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            cookieMessages: [],\n            messages: [],\n            allowedTags: ['div', 'span', 'b', 'strong', 'i', 'em', 'u', 'a']\n        },\n\n        /**\n         * Extends Component object by storage observable messages.\n         */\n        initialize: function () {\n            this._super();\n\n            this.cookieMessages = _.unique($.cookieStorage.get('mage-messages'), 'text');\n            this.messages = customerData.get('messages').extend({\n                disposableCustomerData: 'messages'\n            });\n\n            // Force to clean obsolete messages\n            if (!_.isEmpty(this.messages().messages)) {\n                customerData.set('messages', {});\n            }\n\n            $.mage.cookies.set('mage-messages', '', {\n                samesite: 'strict',\n                domain: ''\n            });\n        },\n\n        /**\n         * Prepare the given message to be rendered as HTML\n         *\n         * @param {String} message\n         * @return {String}\n         */\n        prepareMessageForHtml: function (message) {\n            return escaper.escapeHtml(message, this.allowedTags);\n        }\n    });\n});\n","Magento_Theme/js/model/breadcrumb-list.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","Magento_Wishlist/js/wishlist.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    'mage/template',\n    'Magento_Ui/js/modal/alert',\n    'jquery-ui-modules/widget',\n    'mage/validation/validation',\n    'mage/dataPost'\n], function ($, mageTemplate, alert) {\n    'use strict';\n\n    $.widget('mage.wishlist', {\n        options: {\n            dataAttribute: 'item-id',\n            nameFormat: 'qty[{0}]',\n            btnRemoveSelector: '[data-role=remove]',\n            qtySelector: '[data-role=qty]',\n            addToCartSelector: '[data-role=tocart]',\n            addAllToCartSelector: '[data-role=all-tocart]',\n            commentInputType: 'textarea',\n            infoList: false\n        },\n\n        /**\n         * Bind handlers to events.\n         */\n        _create: function () {\n            var _this = this;\n\n            if (!this.options.infoList) {\n                this.element\n                    .on('addToCart', function (event, context) {\n                        var urlParams;\n\n                        event.stopPropagation(event);\n                        $(context).data('stop-processing', true);\n                        urlParams = _this._getItemsToCartParams(\n                            $(context).parents('[data-row=product-item]').find(_this.options.addToCartSelector)\n                        );\n                        $.mage.dataPost().postData(urlParams);\n\n                        return false;\n                    })\n                    .on('click', this.options.btnRemoveSelector, $.proxy(function (event) {\n                        event.preventDefault();\n                        $.mage.dataPost().postData($(event.currentTarget).data('post-remove'));\n                    }, this))\n                    .on('click', this.options.addToCartSelector, $.proxy(this._beforeAddToCart, this))\n                    .on('click', this.options.addAllToCartSelector, $.proxy(this._addAllWItemsToCart, this))\n                    .on('focusin focusout', this.options.commentInputType, $.proxy(this._focusComment, this));\n            }\n\n            // Setup validation for the form\n            this.element.mage('validation', {\n                /** @inheritdoc */\n                errorPlacement: function (error, element) {\n                    error.insertAfter(element.next());\n                }\n            });\n        },\n\n        /**\n         * Process data before add to cart\n         *\n         * - update item's qty value.\n         *\n         * @param {Event} event\n         * @private\n         */\n        _beforeAddToCart: function (event) {\n            var elem = $(event.currentTarget),\n                itemId = elem.data(this.options.dataAttribute),\n                qtyName = $.validator.format(this.options.nameFormat, itemId),\n                qtyValue = elem.parents().find('[name=\"' + qtyName + '\"]').val(),\n                params = elem.data('post');\n\n            if (params) {\n                params.data = $.extend({}, params.data, {\n                    'qty': qtyValue\n                });\n                elem.data('post', params);\n            }\n        },\n\n        /**\n         * Add wish list items to cart.\n         * @private\n         * @param {jQuery} elem - clicked 'add to cart' button\n         */\n        _getItemsToCartParams: function (elem) {\n            var itemId, url, qtyName, qtyValue;\n\n            if (elem.data(this.options.dataAttribute)) {\n                itemId = elem.data(this.options.dataAttribute);\n                url = this.options.addToCartUrl;\n                qtyName = $.validator.format(this.options.nameFormat, itemId);\n                qtyValue = elem.parents().find('[name=\"' + qtyName + '\"]').val();\n                url.data.item = itemId;\n                url.data.qty = qtyValue;\n\n                return url;\n            }\n        },\n\n        /**\n         * Add all wish list items to cart\n         * @private\n         */\n        _addAllWItemsToCart: function () {\n            var urlParams = this.options.addAllToCartUrl,\n                separator = urlParams.action.indexOf('?') >= 0 ? '&' : '?';\n\n            this.element.find(this.options.qtySelector).each(function (index, element) {\n                urlParams.action += separator + $(element).prop('name') + '=' + encodeURIComponent($(element).val());\n                separator = '&';\n            });\n            $.mage.dataPost().postData(urlParams);\n        },\n\n        /**\n         * Toggle comment string.\n         * @private\n         * @param {Event} e\n         */\n        _focusComment: function (e) {\n            var commentInput = e.currentTarget;\n\n            if (commentInput.value === '' || commentInput.value === this.options.commentString) {\n                commentInput.value = commentInput.value === this.options.commentString ?\n                    '' : this.options.commentString;\n            }\n        }\n    });\n\n    // Extension for mage.wishlist - Select All checkbox\n    $.widget('mage.wishlist', $.mage.wishlist, {\n        options: {\n            selectAllCheckbox: '#select-all',\n            parentContainer: '#wishlist-table'\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            var selectAllCheckboxParent, checkboxCount;\n\n            this._super();\n            selectAllCheckboxParent = $(this.options.selectAllCheckbox).parents(this.options.parentContainer);\n            checkboxCount = selectAllCheckboxParent\n                .find('input:checkbox:not(' + this.options.selectAllCheckbox + ')').length;\n            // If Select all checkbox is checked, check all item checkboxes, if unchecked, uncheck all item checkboxes\n            $(this.options.selectAllCheckbox).on('click', function () {\n                selectAllCheckboxParent.find('input:checkbox').attr('checked', $(this).is(':checked'));\n            });\n            // If all item checkboxes are checked, check select all checkbox,\n            // if not all item checkboxes are checked, uncheck select all checkbox\n            selectAllCheckboxParent.on(\n                'click',\n                'input:checkbox:not(' + this.options.selectAllCheckbox + ')',\n                $.proxy(function () {\n                    var checkedCount = selectAllCheckboxParent\n                        .find('input:checkbox:checked:not(' + this.options.selectAllCheckbox + ')').length;\n\n                    $(this.options.selectAllCheckbox).attr('checked', checkboxCount === checkedCount);\n                }, this)\n            );\n        }\n    });\n    // Extension for mage.wishlist info add to cart\n    $.widget('mage.wishlist', $.mage.wishlist, {\n        /** @inheritdoc */\n        _create: function () {\n            this._super();\n\n            if (this.options.infoList) {\n                this.element.on('addToCart', $.proxy(function (event, context) {\n                    this.element.find('input:checkbox').attr('checked', false);\n                    $(context).closest('tr').find('input:checkbox').attr('checked', true);\n                    this.element.trigger('submit');\n                }, this));\n                this._checkBoxValidate();\n            }\n        },\n\n        /**\n         * validate checkbox selection.\n         * @private\n         */\n        _checkBoxValidate: function () {\n            this.element.validation({\n                submitHandler: $.proxy(function (form) {\n                    if ($(form).find('input:checkbox:checked').length) {\n                        form.submit();\n                    } else {\n                        alert({\n                            content: this.options.checkBoxValidationMessage\n                        });\n                    }\n                }, this)\n            });\n        }\n    });\n\n    // Extension for mage.wishlist - Add Wishlist item to Gift Registry\n    $.widget('mage.wishlist', $.mage.wishlist, {\n        options: {\n            formTmplSelector: '#form-tmpl',\n            formTmplId: '#wishlist-hidden-form'\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            var _this = this;\n\n            this._super();\n            this.element.on('click', '[data-wishlist-to-giftregistry]', function () {\n                var json = $(this).data('wishlist-to-giftregistry'),\n                    tmplJson = {\n                        item: json.itemId,\n                        entity: json.entity,\n                        url: json.url\n                    },\n                    html = mageTemplate(_this.options.formTmplSelector, {\n                        data: tmplJson\n                    });\n\n                $(html).appendTo('body');\n                $(_this.options.formTmplId).trigger('submit');\n            });\n        }\n    });\n\n    return $.mage.wishlist;\n});\n","Magento_Wishlist/js/search.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.wishlistSearch', {\n\n        /**\n         * Bind handlers to events\n         */\n        _create: function () {\n            this.element.on('change', $.proxy(this._toggleForm, this));\n        },\n\n        /**\n         * Toggle Form\n         * @private\n         */\n        _toggleForm: function () {\n            switch (this.element.val()) {\n                case 'name':\n                    $(this.options.emailFormSelector).hide();\n                    $(this.options.nameFormSelector).show();\n                    break;\n\n                case 'email':\n                    $(this.options.nameFormSelector).hide();\n                    $(this.options.emailFormSelector).show();\n                    break;\n                default:\n                    $(this.options.emailFormSelector).add(this.options.nameFormSelector).hide();\n            }\n        }\n    });\n\n    return $.mage.wishlistSearch;\n});\n","Magento_Wishlist/js/add-to-wishlist.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.addToWishlist', {\n        options: {\n            bundleInfo: 'div.control [name^=bundle_option]',\n            configurableInfo: '.super-attribute-select',\n            groupedInfo: '#super-product-table input',\n            downloadableInfo: '#downloadable-links-list input',\n            customOptionsInfo: '.product-custom-option',\n            qtyInfo: '#qty',\n            actionElement: '[data-action=\"add-to-wishlist\"]',\n            productListWrapper: '.product-item-info',\n            productPageWrapper: '.product-info-main'\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this._bind();\n        },\n\n        /**\n         * @private\n         */\n        _bind: function () {\n            var options = this.options,\n                dataUpdateFunc = '_updateWishlistData',\n                validateProductQty = '_validateWishlistQty',\n                changeCustomOption = 'change ' + options.customOptionsInfo,\n                changeQty = 'change ' + options.qtyInfo,\n                updateWishlist = 'click ' + options.actionElement,\n                events = {},\n                key;\n\n            if ('productType' in options) {\n                if (typeof options.productType === 'string') {\n                    options.productType = [options.productType];\n                }\n            } else {\n                options.productType = [];\n            }\n\n            events[changeCustomOption] = dataUpdateFunc;\n            events[changeQty] = dataUpdateFunc;\n            events[updateWishlist] = validateProductQty;\n\n            for (key in options.productType) {\n                if (options.productType.hasOwnProperty(key) && options.productType[key] + 'Info' in options) {\n                    events['change ' + options[options.productType[key] + 'Info']] = dataUpdateFunc;\n                }\n            }\n            this._on(events);\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _updateWishlistData: function (event) {\n            var dataToAdd = {},\n                isFileUploaded = false,\n                handleObjSelector = null,\n                self = this;\n\n            if (event.handleObj.selector == this.options.qtyInfo) { //eslint-disable-line eqeqeq\n                this._updateAddToWishlistButton({}, event);\n                event.stopPropagation();\n\n                return;\n            }\n\n            handleObjSelector = $(event.currentTarget).closest('form').find(event.handleObj.selector);\n\n            handleObjSelector.each(function (index, element) {\n                if ($(element).is('input[type=text]') ||\n                    $(element).is('input[type=email]') ||\n                    $(element).is('input[type=number]') ||\n                    $(element).is('input[type=hidden]') ||\n                    $(element).is('input[type=checkbox]:checked') ||\n                    $(element).is('input[type=radio]:checked') ||\n                    $(element).is('textarea') ||\n                    $('#' + element.id + ' option:selected').length\n                ) {\n                    if ($(element).data('selector') || $(element).attr('name')) {\n                        dataToAdd = $.extend({}, dataToAdd, self._getElementData(element));\n                    }\n\n                    return;\n                }\n\n                if ($(element).is('input[type=file]') && $(element).val()) {\n                    isFileUploaded = true;\n                }\n            });\n\n            if (isFileUploaded) {\n                this.bindFormSubmit();\n            }\n            this._updateAddToWishlistButton(dataToAdd, event);\n            event.stopPropagation();\n        },\n\n        /**\n         * @param {Object} dataToAdd\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _updateAddToWishlistButton: function (dataToAdd, event) {\n            var self = this,\n                buttons = this._getAddToWishlistButton(event);\n\n            buttons.each(function (index, element) {\n                var params = $(element).data('post'),\n                    currentTarget = event.currentTarget,\n                    targetElement,\n                    targetValue;\n\n                if (!params) {\n                    params = {\n                        'data': {}\n                    };\n                } else if ($(currentTarget).data('selector') || $(currentTarget).attr('name')) {\n                    targetElement = self._getElementData(currentTarget);\n                    targetValue = Object.keys(targetElement)[0];\n\n                    if (params.data.hasOwnProperty(targetValue) && !dataToAdd.hasOwnProperty(targetValue)) {\n                        delete params.data[targetValue];\n                    }\n                }\n\n                params.data = $.extend({}, params.data, dataToAdd, {\n                    'qty': $(self.options.qtyInfo).val()\n                });\n                $(element).data('post', params);\n            });\n        },\n\n        /**\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _getAddToWishlistButton: function (event) {\n            var productListWrapper = $(event.currentTarget).closest(this.options.productListWrapper);\n\n            if (productListWrapper.length) {\n                return productListWrapper.find(this.options.actionElement);\n            }\n\n            return $(this.options.actionElement);\n        },\n\n        /**\n         * @param {Object} array1\n         * @param {Object} array2\n         * @return {Object}\n         * @private\n         * @deprecated\n         */\n        _arrayDiffByKeys: function (array1, array2) {\n            var result = {};\n\n            $.each(array1, function (key, value) {\n                if (key.indexOf('option') === -1) {\n                    return;\n                }\n\n                if (!array2[key]) {\n                    result[key] = value;\n                }\n            });\n\n            return result;\n        },\n\n        /**\n         * @param {HTMLElement} element\n         * @return {Object}\n         * @private\n         */\n        _getElementData: function (element) {\n            var data, elementName, elementValue;\n\n            element = $(element);\n            data = {};\n            elementName = element.data('selector') ? element.data('selector') : element.attr('name');\n            elementValue = element.val();\n\n            if (element.is('select[multiple]') && elementValue !== null) {\n                if (elementName.substr(elementName.length - 2) == '[]') { //eslint-disable-line eqeqeq\n                    elementName = elementName.substring(0, elementName.length - 2);\n                }\n                $.each(elementValue, function (key, option) {\n                    data[elementName + '[' + option + ']'] = option;\n                });\n            } else if (elementName.substr(elementName.length - 2) == '[]') { //eslint-disable-line eqeqeq, max-depth\n                elementName = elementName.substring(0, elementName.length - 2);\n\n                data[elementName + '[' + elementValue + ']'] = elementValue;\n            } else {\n                data[elementName] = elementValue;\n            }\n\n            return data;\n        },\n\n        /**\n         * @param {Object} params\n         * @param {Object} dataToAdd\n         * @private\n         * @deprecated\n         */\n        _removeExcessiveData: function (params, dataToAdd) {\n            var dataToRemove = this._arrayDiffByKeys(params.data, dataToAdd);\n\n            $.each(dataToRemove, function (key) {\n                delete params.data[key];\n            });\n        },\n\n        /**\n         * Bind form submit.\n         */\n        bindFormSubmit: function () {\n            var self = this;\n\n            $('[data-action=\"add-to-wishlist\"]').on('click', function (event) {\n                var element, params, form, action;\n\n                event.stopPropagation();\n                event.preventDefault();\n\n                element = $('input[type=file]' + self.options.customOptionsInfo);\n                params = $(event.currentTarget).data('post');\n                form = $(element).closest('form');\n                action = params.action;\n\n                if (params.data.id) {\n                    $('<input>', {\n                        type: 'hidden',\n                        name: 'id',\n                        value: params.data.id\n                    }).appendTo(form);\n                }\n\n                if (params.data.uenc) {\n                    action += 'uenc/' + params.data.uenc;\n                }\n\n                $(form).attr('action', action).trigger('submit');\n            });\n        },\n\n        /**\n         * Validate product quantity before updating Wish List\n         *\n         * @param {jQuery.Event} event\n         * @private\n         */\n        _validateWishlistQty: function (event) {\n            var element = $(this.options.qtyInfo);\n\n            if (!(element.validation() && element.validation('isValid'))) {\n                event.preventDefault();\n                event.stopPropagation();\n\n                return;\n            }\n        }\n    });\n\n    return $.mage.addToWishlist;\n});\n","Magento_Wishlist/js/view/wishlist.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.wishlist = customerData.get('wishlist');\n        }\n    });\n});\n","Magento_Wishlist/js/product/addtowishlist-button.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/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         * Get request POST data.\n         *\n         * @param {Object} row\n         * @return {String}\n         */\n        getDataPost: function (row) {\n            return uencProcessor(row['extension_attributes']['wishlist_button'].url);\n        },\n\n        /**\n         * Check if component must be shown.\n         *\n         * @return {Boolean}\n         */\n        isAllowed: function () {\n            return columnStatusValidator.isValid(this.source(), 'add_to_wishlist', '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_Downloadable/js/downloadable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'jquery-ui-modules/widget',\n    'Magento_Catalog/js/price-box'\n], function ($) {\n    'use strict';\n\n    /**\n     * Downloadable widget\n     */\n    $.widget('mage.downloadable', {\n        options: {\n            priceHolderSelector: '.price-box',\n            linkElement: '',\n            allElements: ''\n        },\n\n        /**\n         * @inheritdoc\n         */\n        _init: function initLinks() {\n            var element = this.element,\n                options = $(this.options.linkElement, element);\n\n            options.trigger('change');\n        },\n\n        /**\n         *  @inheritdoc\n         */\n        _create: function () {\n            var self = this;\n\n            this.element.find(this.options.linkElement).on('change', $.proxy(function () {\n                this._reloadPrice();\n            }, this));\n\n            this.element.find(this.options.allElements).on('change', function () {\n                if (this.checked) {\n                    $('label[for=\"' + this.id + '\"] > span').text($(this).attr('data-checked'));\n                    self.element.find(self.options.linkElement + ':not(:checked)').each(function () {\n                        $(this).trigger('click');\n                    });\n                } else {\n                    $('[for=\"' + this.id + '\"] > span').text($(this).attr('data-notchecked'));\n                    self.element.find(self.options.linkElement + ':checked').each(function () {\n                        $(this).trigger('click');\n                    });\n                }\n            });\n\n            this._reloadPrice();\n        },\n\n        /**\n         * Reload product price with selected link price included\n         * @private\n         */\n        _reloadPrice: function () {\n            var finalPrice = 0,\n                basePrice = 0;\n\n            this.element.find(this.options.linkElement + ':checked').each($.proxy(function (index, element) {\n                finalPrice += this.options.config.links[$(element).val()].finalPrice;\n                basePrice += this.options.config.links[$(element).val()].basePrice;\n            }, this));\n\n            $(this.options.priceHolderSelector).trigger('updatePrice', {\n                'prices': {\n                    'finalPrice': {\n                        'amount': finalPrice\n                    },\n                    'basePrice': {\n                        'amount': basePrice\n                    }\n                }\n            });\n\n            this.reloadAllCheckText();\n        },\n\n        /**\n         * Reload all-elements-checkbox's label\n         * @private\n         */\n        reloadAllCheckText: function () {\n            var allChecked = true,\n                allElementsCheck = $(this.options.allElements),\n                allElementsLabel = $('label[for=\"' + allElementsCheck.attr('id') + '\"] > span');\n\n            $(this.options.linkElement).each(function () {\n                if (!this.checked) {\n                    allChecked = false;\n                }\n            });\n\n            if (allChecked) {\n                allElementsLabel.text(allElementsCheck.attr('data-checked'));\n                allElementsCheck.prop('checked', true);\n            } else {\n                allElementsLabel.text(allElementsCheck.attr('data-notchecked'));\n                allElementsCheck.prop('checked', false);\n            }\n        }\n    });\n\n    return $.mage.downloadable;\n});\n","Magento_Newsletter/js/newsletter-sign-up.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'uiElement',\n    'mage/url',\n    'subscriptionStatusResolver',\n    'mage/validation'\n], function ($, Component, urlBuilder, subscriptionStatusResolver) {\n    'use strict';\n\n    return Component.extend({\n\n        defaults: {\n            signUpElement: '',\n            submitButton: '',\n            element: null\n        },\n\n        /** @inheritdoc */\n        initialize: function (config, element) {\n            this._super();\n            this.element = element;\n            $(element).on('change', $.proxy(this.updateSignUpStatus, this));\n            this.updateSignUpStatus();\n        },\n\n        /**\n         * Send status request and update subscription element according to result.\n         */\n        updateSignUpStatus: function () {\n            var element = $(this.element),\n                email = element.val(),\n                self = this,\n                newsletterSubscription;\n\n            if ($(self.signUpElement).is(':checked')) {\n                return;\n            }\n\n            if (!email || !$.validator.methods['validate-email'].call(this, email, element)) {\n                return;\n            }\n\n            newsletterSubscription = $.Deferred();\n\n            $(self.submitButton).prop('disabled', true);\n\n            subscriptionStatusResolver(email, newsletterSubscription);\n\n            $.when(newsletterSubscription).done(function (isSubscribed) {\n                if (isSubscribed) {\n                    $(self.signUpElement).prop('checked', true);\n                }\n            }).always(function () {\n                $(self.submitButton).prop('disabled', false);\n            });\n        }\n    });\n});\n","Magento_Newsletter/js/subscription-status-resolver.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/url'\n], function ($, urlBuilder) {\n    'use strict';\n\n    return function (email, deferred) {\n        return $.getJSON(\n            urlBuilder.build('newsletter/ajax/status'),\n            {\n                email: email\n            }\n        ).done(function (response) {\n            if (response.errors) {\n                deferred.reject();\n            } else {\n                deferred.resolve(response.subscribed);\n            }\n        }).fail(function () {\n            deferred.reject();\n        });\n    };\n});\n","Magento_Review/js/process-reviews.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'tabs',\n    'collapsible'\n], function ($) {\n    'use strict';\n\n    /**\n     * @param {String} url\n     * @param {*} fromPages\n     */\n    function processReviews(url, fromPages) {\n        $.ajax({\n            url: url,\n            cache: true,\n            dataType: 'html',\n            showLoader: false,\n            loaderContext: $('.product.data.items')\n        }).done(function (data) {\n            $('#product-review-container').html(data).trigger('contentUpdated'); \n            if($('.product.info.detailed').hasClass('vertical')) {\n              $('#product-review-container').parent().parent().css(\"min-height\",$('#product-review-container').parent().outerHeight()+\"px\");\n            }\n\n            $('[data-role=\"product-review\"] .pages a').each(function (index, element) {\n                $(element).on('click', function (event) { //eslint-disable-line max-nested-callbacks\n                    processReviews($(element).attr('href'), true);\n                    event.preventDefault();\n                });\n            });\n        }).always(function () {\n            if (fromPages == true) { //eslint-disable-line eqeqeq\n                $('html, body').animate({\n                    scrollTop: $('#reviews').offset().top - 50\n                }, 300);\n            }\n        });\n    }\n\n    return function (config) {\n        var reviewTab = $(config.reviewsTabSelector),\n            requiredReviewTabRole = 'tab';\n\n        if (reviewTab.attr('role') === requiredReviewTabRole && reviewTab.hasClass('active')) {\n            processReviews(config.productReviewUrl, location.hash === '#reviews');\n        } else {\n            reviewTab.one('beforeOpen', function () {\n                processReviews(config.productReviewUrl);\n            });\n        }\n\n        $(function () {\n            $('.product-info-main .reviews-actions a').on('click', function (event) {\n                var anchor, addReviewBlock;\n\n                event.preventDefault();\n                anchor = $(this).attr('href').replace(/^.*?(#|$)/, '');\n                addReviewBlock = $('#' + anchor);\n\n                if (addReviewBlock.length) {\n                    $('.product.data.items [data-role=\"content\"]').each(function (index) { //eslint-disable-line\n                        if (this.id == 'reviews') { //eslint-disable-line eqeqeq\n                            $('.product.data.items').tabs('activate', index);\n                        }\n                    });\n                    $('html, body').animate({\n                        scrollTop: addReviewBlock.offset().top - 50\n                    }, 300);\n                }\n\n            });\n        });\n    };\n});\n","Magento_Review/js/validate-review.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'jquery/validate',\n    'mage/translate'\n], function ($) {\n    'use strict';\n\n    $.validator.addMethod(\n        'rating-required', function (value) {\n            return value !== undefined;\n        }, $.mage.__('Please select one of each of the ratings above.'));\n});\n","Magento_Review/js/error-placement.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, element) {\n        $(element).mage('validation', {\n            /** @inheritdoc */\n            errorPlacement: function (error, el) {\n\n                if (el.parents('#product-review-table').length) {\n                    $('#product-review-table').siblings(this.errorElement + '.' + this.errorClass).remove();\n                    $('#product-review-table').after(error);\n                } else {\n                    el.after(error);\n                }\n            }\n        });\n    };\n});\n","Magento_Review/js/submit-review.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            if ($(this).valid()) {\n                $(this).find('.submit').attr('disabled', true);\n            }\n        });\n    };\n});\n","Magento_Review/js/view/review.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    'Magento_Customer/js/view/customer'\n], function (Component, customerData) {\n    'use strict';\n\n    return Component.extend({\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.review = customerData.get('review').extend({\n                disposableCustomerData: 'review'\n            });\n        },\n\n        /**\n         * @return {*}\n         */\n        nickname: function () {\n            return this.review().nickname || customerData.get('customer')().firstname;\n        }\n    });\n});\n","Magento_Reports/js/recently-viewed.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    'jquery-ui-modules/widget'\n], function ($) {\n    'use strict';\n\n    $.widget('mage.recentlyViewedProducts', {\n        options: {\n            localStorageKey: 'recently-viewed-products',\n            productBlock: '#widget_viewed_item',\n            viewedContainer: 'ol'\n        },\n\n        /**\n         * Bind events to the appropriate handlers.\n         * @private\n         */\n        _create: function () {\n            var productHtml = $(this.options.productBlock).html(),\n                productSku = $(this.options.productBlock).data('sku'),\n                products = JSON.parse(window.localStorage.getItem(this.options.localStorageKey)),\n                productsLength, maximum, showed, index;\n\n            if (products) {\n                productsLength = products.sku.length;\n                maximum = $(this.element).data('count');\n                showed = 0;\n\n                for (index = 0; index <= productsLength; index++) {\n                    if (products.sku[index] == productSku || showed >= maximum) { //eslint-disable-line\n                        products.sku.splice(index, 1);\n                        products.html.splice(index, 1);\n                    } else {\n                        $(this.element).find(this.options.viewedContainer).append(products.html[index]);\n                        $(this.element).show();\n                        showed++;\n                    }\n                }\n                $(this.element).find(this.options.productBlock).show();\n            } else {\n                products = {};\n                products.sku = [];\n                products.html = [];\n            }\n            products.sku.unshift(productSku);\n            products.html.unshift(productHtml);\n            window.localStorage.setItem(this.options.localStorageKey, JSON.stringify(products));\n        }\n    });\n\n    return $.mage.recentlyViewedProducts;\n});\n","Magento_PageCache/js/page-cache.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'domReady',\n    'consoleLogger',\n    'Magento_PageCache/js/form-key-provider',\n    'jquery-ui-modules/widget',\n    'mage/cookies'\n], function ($, domReady, consoleLogger, formKeyInit) {\n    'use strict';\n\n    /**\n     * Helper. Generate random string\n     * TODO: Merge with mage/utils\n     * @param {String} chars - list of symbols\n     * @param {Number} length - length for need string\n     * @returns {String}\n     */\n    function generateRandomString(chars, length) {\n        var result = '';\n\n        length = length > 0 ? length : 1;\n\n        while (length--) {\n            result += chars[Math.round(Math.random() * (chars.length - 1))];\n        }\n\n        return result;\n    }\n\n    /**\n     * Nodes tree to flat list converter\n     * @returns {Array}\n     */\n    $.fn.comments = function () {\n        var elements = [],\n            contents,\n            elementContents;\n\n        /**\n         * @param {jQuery} element - Comment holder\n         */\n        (function lookup(element) {\n            var iframeHostName;\n\n            // prevent cross origin iframe content reading\n            if ($(element).prop('tagName') === 'IFRAME') {\n                iframeHostName = $('<a>').prop('href', $(element).prop('src'))\n                    .prop('hostname');\n\n                if (window.location.hostname !== iframeHostName) {\n                    return [];\n                }\n            }\n\n            /**\n             * Rewrite jQuery contents().\n             *\n             * @param {jQuery} elem\n             */\n            contents = function (elem) {\n                return $.map(elem, function (el) {\n                    try {\n                        return el.nodeName.toLowerCase() === 'iframe' ?\n                            el.contentDocument || (el.contentWindow ? el.contentWindow.document : []) :\n                            $.merge([], el.childNodes);\n                    } catch (e) {\n                        consoleLogger.error(e);\n\n                        return [];\n                    }\n                });\n            };\n\n            elementContents = contents($(element));\n\n            $.each(elementContents, function (index, el) {\n                switch (el.nodeType) {\n                    case 1: // ELEMENT_NODE\n                        lookup(el);\n                        break;\n\n                    case 8: // COMMENT_NODE\n                        elements.push(el);\n                        break;\n\n                    case 9: // DOCUMENT_NODE\n                        lookup($(el).find('body'));\n                        break;\n                }\n            });\n        })(this);\n\n        return elements;\n    };\n\n    /**\n     * FormKey Widget - this widget is generating from key, saves it to cookie and\n     * @deprecated see Magento/PageCache/view/frontend/web/js/form-key-provider.js\n     */\n    $.widget('mage.formKey', {\n        options: {\n            inputSelector: 'input[name=\"form_key\"]',\n            allowedCharacters: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',\n            length: 16\n        },\n\n        /**\n         * Creates widget 'mage.formKey'\n         * @private\n         */\n        _create: function () {\n            var formKey = $.mage.cookies.get('form_key'),\n                options = {\n                    secure: window.cookiesConfig ? window.cookiesConfig.secure : false\n                };\n\n            if (!formKey) {\n                formKey = generateRandomString(this.options.allowedCharacters, this.options.length);\n                $.mage.cookies.set('form_key', formKey, options);\n            }\n            $(this.options.inputSelector).val(formKey);\n        }\n    });\n\n    /**\n     * PageCache Widget\n     * Handles additional ajax request for rendering user private content.\n     */\n    $.widget('mage.pageCache', {\n        options: {\n            url: '/',\n            patternPlaceholderOpen: /^ BLOCK (.+) $/,\n            patternPlaceholderClose: /^ \\/BLOCK (.+) $/,\n            versionCookieName: 'private_content_version',\n            handles: []\n        },\n\n        /**\n         * Creates widget 'mage.pageCache'\n         * @private\n         */\n        _create: function () {\n            var placeholders,\n                version = $.mage.cookies.get(this.options.versionCookieName);\n\n            if (!version) {\n                return;\n            }\n            placeholders = this._searchPlaceholders(this.element.comments());\n\n            if (placeholders && placeholders.length) {\n                this._ajax(placeholders, version);\n            }\n        },\n\n        /**\n         * Parse page for placeholders.\n         * @param {Array} elements\n         * @returns {Array}\n         * @private\n         */\n        _searchPlaceholders: function (elements) {\n            var placeholders = [],\n                tmp = {},\n                ii,\n                len,\n                el, matches, name;\n\n            if (!(elements && elements.length)) {\n                return placeholders;\n            }\n\n            for (ii = 0, len = elements.length; ii < len; ii++) {\n                el = elements[ii];\n                matches = this.options.patternPlaceholderOpen.exec(el.nodeValue);\n                name = null;\n\n                if (matches) {\n                    name = matches[1];\n                    tmp[name] = {\n                        name: name,\n                        openElement: el\n                    };\n                } else {\n                    matches = this.options.patternPlaceholderClose.exec(el.nodeValue);\n\n                    if (matches) { //eslint-disable-line max-depth\n                        name = matches[1];\n\n                        if (tmp[name]) { //eslint-disable-line max-depth\n                            tmp[name].closeElement = el;\n                            placeholders.push(tmp[name]);\n                            delete tmp[name];\n                        }\n                    }\n                }\n            }\n\n            return placeholders;\n        },\n\n        /**\n         * Parse for page and replace placeholders\n         * @param {Object} placeholder\n         * @param {Object} html\n         * @protected\n         */\n        _replacePlaceholder: function (placeholder, html) {\n            var startReplacing = false,\n                prevSibling = null,\n                parent, contents, yy, len, element;\n\n            if (!placeholder || !html) {\n                return;\n            }\n\n            parent = $(placeholder.openElement).parent();\n            contents = parent.contents();\n\n            for (yy = 0, len = contents.length; yy < len; yy++) {\n                element = contents[yy];\n\n                if (element == placeholder.openElement) { //eslint-disable-line eqeqeq\n                    startReplacing = true;\n                }\n\n                if (startReplacing) {\n                    $(element).remove();\n                } else if (element.nodeType != 8) { //eslint-disable-line eqeqeq\n                    //due to comment tag doesn't have siblings we try to find it manually\n                    prevSibling = element;\n                }\n\n                if (element == placeholder.closeElement) { //eslint-disable-line eqeqeq\n                    break;\n                }\n            }\n\n            if (prevSibling) {\n                $(prevSibling).after(html);\n            } else {\n                $(parent).prepend(html);\n            }\n\n            // trigger event to use mage-data-init attribute\n            $(parent).trigger('contentUpdated');\n        },\n\n        /**\n         * AJAX helper\n         * @param {Object} placeholders\n         * @param {String} version\n         * @private\n         */\n        _ajax: function (placeholders, version) {\n            var ii,\n                data = {\n                    blocks: [],\n                    handles: this.options.handles,\n                    originalRequest: this.options.originalRequest,\n                    version: version\n                };\n\n            for (ii = 0; ii < placeholders.length; ii++) {\n                data.blocks.push(placeholders[ii].name);\n            }\n            data.blocks = JSON.stringify(data.blocks.sort());\n            data.handles = JSON.stringify(data.handles);\n            data.originalRequest = JSON.stringify(data.originalRequest);\n            $.ajax({\n                url: this.options.url,\n                data: data,\n                type: 'GET',\n                cache: true,\n                dataType: 'json',\n                context: this,\n\n                /**\n                 * Response handler\n                 * @param {Object} response\n                 */\n                success: function (response) {\n                    var placeholder, i;\n\n                    for (i = 0; i < placeholders.length; i++) {\n                        placeholder = placeholders[i];\n\n                        if (response.hasOwnProperty(placeholder.name)) {\n                            this._replacePlaceholder(placeholder, response[placeholder.name]);\n                        }\n                    }\n                }\n            });\n        }\n    });\n\n    domReady(function () {\n        formKeyInit();\n    });\n\n    return {\n        'pageCache': $.mage.pageCache,\n        'formKey': $.mage.formKey\n    };\n});\n","Magento_PageCache/js/form-key-provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(function () {\n    'use strict';\n\n    return function (settings) {\n        var formKey,\n            inputElements,\n            inputSelector = 'input[name=\"form_key\"]';\n\n        /**\n         * Set form_key cookie\n         * @private\n         */\n        function setFormKeyCookie(value) {\n            var expires,\n                secure,\n                date = new Date(),\n                cookiesConfig = window.cookiesConfig || {},\n                isSecure = !!cookiesConfig.secure,\n                samesite = cookiesConfig.samesite || 'lax';\n\n            date.setTime(date.getTime() + 86400000);\n            expires = '; expires=' + date.toUTCString();\n            secure = isSecure ? '; secure' : '';\n            samesite = '; samesite=' + samesite;\n\n            document.cookie = 'form_key=' + (value || '') + expires + secure + '; path=/' + samesite;\n        }\n\n        /**\n         * Retrieves form key from cookie\n         * @private\n         */\n        function getFormKeyCookie() {\n            var cookie,\n                i,\n                nameEQ = 'form_key=',\n                cookieArr = document.cookie.split(';');\n\n            for (i = 0; i < cookieArr.length; i++) {\n                cookie = cookieArr[i];\n\n                while (cookie.charAt(0) === ' ') {\n                    cookie = cookie.substring(1, cookie.length);\n                }\n\n                if (cookie.indexOf(nameEQ) === 0) {\n                    return cookie.substring(nameEQ.length, cookie.length);\n                }\n            }\n\n            return null;\n        }\n\n        /**\n         * Get form key from UI input hidden\n         * @private\n         */\n        function getFormKeyFromUI() {\n            return document.querySelector(inputSelector).value;\n        }\n\n        /**\n         * Generate form key string\n         * @private\n         */\n        function generateFormKeyString() {\n            var result = '',\n                length = 16,\n                chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n            while (length--) {\n                result += chars[Math.round(Math.random() * (chars.length - 1))];\n            }\n\n            return result;\n        }\n\n        /**\n         * Init form_key inputs with value\n         * @private\n         */\n        function initFormKey() {\n            formKey = getFormKeyCookie();\n\n            if (settings && settings.isPaginationCacheEnabled && !formKey) {\n                formKey = getFormKeyFromUI();\n                setFormKeyCookie(formKey);\n            }\n\n            if (!formKey) {\n                formKey = generateFormKeyString();\n                setFormKeyCookie(formKey);\n            }\n            inputElements = document.querySelectorAll(inputSelector);\n\n            if (inputElements.length) {\n                Array.prototype.forEach.call(inputElements, function (element) {\n                    element.setAttribute('value', formKey);\n                });\n            }\n        }\n\n        initFormKey();\n    };\n});\n","Magento_ConfigurableProduct/js/configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore',\n    'mage/template',\n    'mage/translate',\n    'priceUtils',\n    'priceBox',\n    'jquery-ui-modules/widget',\n    'jquery/jquery.parsequery',\n    'fotoramaVideoEvents'\n], function ($, _, mageTemplate, $t, priceUtils) {\n    'use strict';\n\n    $.widget('mage.configurable', {\n        options: {\n            superSelector: '.super-attribute-select',\n            selectSimpleProduct: '[name=\"selected_configurable_option\"]',\n            priceHolderSelector: '.price-box',\n            spConfig: {},\n            state: {},\n            priceFormat: {},\n            optionTemplate: '<%- data.label %>' +\n            '<% if (typeof data.finalPrice.value !== \"undefined\") { %>' +\n            ' <%- data.finalPrice.formatted %>' +\n            '<% } %>',\n            mediaGallerySelector: '[data-gallery-role=gallery-placeholder]',\n            mediaGalleryInitial: null,\n            slyOldPriceSelector: '.sly-old-price',\n            normalPriceLabelSelector: '.product-info-main .normal-price .price-label',\n\n            /**\n             * Defines the mechanism of how images of a gallery should be\n             * updated when user switches between configurations of a product.\n             *\n             * As for now value of this option can be either 'replace' or 'prepend'.\n             *\n             * @type {String}\n             */\n            gallerySwitchStrategy: 'replace',\n            tierPriceTemplateSelector: '#tier-prices-template',\n            tierPriceBlockSelector: '[data-role=\"tier-price-block\"]',\n            tierPriceTemplate: '',\n            selectorProduct: '.product-info-main',\n            selectorProductPrice: '[data-role=priceBox]',\n            qtyInfo: '#qty'\n        },\n\n        /**\n         * Creates widget\n         * @private\n         */\n        _create: function () {\n            // Initial setting of various option values\n            this._initializeOptions();\n\n            // Override defaults with URL query parameters and/or inputs values\n            this._overrideDefaults();\n\n            // Change events to check select reloads\n            this._setupChangeEvents();\n\n            // Fill state\n            this._fillState();\n\n            // Setup child and prev/next settings\n            this._setChildSettings();\n\n            // Setup/configure values to inputs\n            this._configureForValues();\n\n            $(this.element).trigger('configurable.initialized');\n            $(this.options.qtyInfo).on('input', this._reloadPrice.bind(this));\n        },\n\n        /**\n         * Initialize tax configuration, initial settings, and options values.\n         * @private\n         */\n        _initializeOptions: function () {\n            var options = this.options,\n                gallery = $(options.mediaGallerySelector),\n                priceBoxOptions = $(this.options.priceHolderSelector).priceBox('option').priceConfig || null;\n\n            if (priceBoxOptions && priceBoxOptions.optionTemplate) {\n                options.optionTemplate = priceBoxOptions.optionTemplate;\n            }\n\n            if (priceBoxOptions && priceBoxOptions.priceFormat) {\n                options.priceFormat = priceBoxOptions.priceFormat;\n            }\n            options.optionTemplate = mageTemplate(options.optionTemplate);\n            options.tierPriceTemplate = $(this.options.tierPriceTemplateSelector).html();\n\n            options.settings = options.spConfig.containerId ?\n                $(options.spConfig.containerId).find(options.superSelector) :\n                $(options.superSelector);\n\n            options.values = options.spConfig.defaultValues || {};\n            options.parentImage = $('[data-role=base-image-container] img').attr('src');\n\n            this.inputSimpleProduct = this.element.find(options.selectSimpleProduct);\n\n            gallery.data('gallery') ?\n                this._onGalleryLoaded(gallery) :\n                gallery.on('gallery:loaded', this._onGalleryLoaded.bind(this, gallery));\n\n        },\n\n        /**\n         * Override default options values settings with either URL query parameters or\n         * initialized inputs values.\n         * @private\n         */\n        _overrideDefaults: function () {\n            var hashIndex = window.location.href.indexOf('#');\n\n            if (hashIndex !== -1) {\n                this._parseQueryParams(window.location.href.substr(hashIndex + 1));\n            }\n\n            if (this.options.spConfig.inputsInitialized) {\n                this._setValuesByAttribute();\n            }\n\n            this._setInitialOptionsLabels();\n        },\n\n        /**\n         * Parse query parameters from a query string and set options values based on the\n         * key value pairs of the parameters.\n         * @param {*} queryString - URL query string containing query parameters.\n         * @private\n         */\n        _parseQueryParams: function (queryString) {\n            var queryParams = $.parseQuery({\n                query: queryString\n            });\n\n            $.each(queryParams, $.proxy(function (key, value) {\n                if (this.options.spConfig.attributes[key] !== undefined &&\n                    _.find(this.options.spConfig.attributes[key].options, function (element) {\n                        return element.id === value;\n                    })) {\n                    this.options.values[key] = value;\n                }\n            }, this));\n        },\n\n        /**\n         * Override default options values with values based on each element's attribute\n         * identifier.\n         * @private\n         */\n        _setValuesByAttribute: function () {\n            this.options.values = {};\n            $.each(this.options.settings, $.proxy(function (index, element) {\n                var attributeId;\n\n                if (element.value) {\n                    attributeId = element.id.replace(/[a-z]*/, '');\n\n                    if (this.options.spConfig.attributes[attributeId] !== undefined &&\n                        _.find(this.options.spConfig.attributes[attributeId].options, function (optionElement) {\n                            return optionElement.id === element.value;\n                        })) {\n                        this.options.values[attributeId] = element.value;\n                    }\n                }\n            }, this));\n        },\n\n        /**\n         * Set additional field with initial label to be used when switching between options with different prices.\n         * @private\n         */\n        _setInitialOptionsLabels: function () {\n            $.each(this.options.spConfig.attributes, $.proxy(function (index, element) {\n                $.each(element.options, $.proxy(function (optIndex, optElement) {\n                    this.options.spConfig.attributes[index].options[optIndex].initialLabel = optElement.label;\n                }, this));\n            }, this));\n        },\n\n        /**\n         * Set up .on('change') events for each option element to configure the option.\n         * @private\n         */\n        _setupChangeEvents: function () {\n            $.each(this.options.settings, $.proxy(function (index, element) {\n                $(element).on('change', this, this._configure);\n            }, this));\n        },\n\n        /**\n         * Iterate through the option settings and set each option's element configuration,\n         * attribute identifier. Set the state based on the attribute identifier.\n         * @private\n         */\n        _fillState: function () {\n            $.each(this.options.settings, $.proxy(function (index, element) {\n                var attributeId = element.id.replace(/[a-z]*/, '');\n\n                if (attributeId && this.options.spConfig.attributes[attributeId]) {\n                    element.config = this.options.spConfig.attributes[attributeId];\n                    element.attributeId = attributeId;\n                    this.options.state[attributeId] = false;\n                }\n            }, this));\n        },\n\n        /**\n         * Set each option's child settings, and next/prev option setting. Fill (initialize)\n         * an option's list of selections as needed or disable an option's setting.\n         * @private\n         */\n        _setChildSettings: function () {\n            var childSettings = [],\n                settings = this.options.settings,\n                index = settings.length,\n                option;\n\n            while (index--) {\n                option = settings[index];\n\n                if (index) {\n                    option.disabled = true;\n                } else {\n                    this._fillSelect(option);\n                }\n\n                _.extend(option, {\n                    childSettings: childSettings.slice(),\n                    prevSetting: settings[index - 1],\n                    nextSetting: settings[index + 1]\n                });\n\n                childSettings.push(option);\n            }\n        },\n\n        /**\n         * Setup for all configurable option settings. Set the value of the option and configure\n         * the option, which sets its state, and initializes the option's choices, etc.\n         * @private\n         */\n        _configureForValues: function () {\n            if (this.options.values) {\n                this.options.settings.each($.proxy(function (index, element) {\n                    var attributeId = element.attributeId;\n\n                    element.value = this.options.values[attributeId] || '';\n                    this._configureElement(element);\n                }, this));\n            }\n        },\n\n        /**\n         * Event handler for configuring an option.\n         * @private\n         * @param {Object} event - Event triggered to configure an option.\n         */\n        _configure: function (event) {\n            event.data._configureElement(this);\n        },\n\n        /**\n         * Configure an option, initializing it's state and enabling related options, which\n         * populates the related option's selection and resets child option selections.\n         * @private\n         * @param {*} element - The element associated with a configurable option.\n         */\n        _configureElement: function (element) {\n            this.simpleProduct = this._getSimpleProductId(element);\n\n            if (element.value) {\n                this.options.state[element.config.id] = element.value;\n\n                if (element.nextSetting) {\n                    element.nextSetting.disabled = false;\n                    this._fillSelect(element.nextSetting);\n                    this._resetChildren(element.nextSetting);\n                } else {\n                    if (!!document.documentMode) { //eslint-disable-line\n                        this.inputSimpleProduct.val(element.options[element.selectedIndex].config.allowedProducts[0]);\n                    } else {\n                        this.inputSimpleProduct.val(element.selectedOptions[0].config.allowedProducts[0]);\n                    }\n                }\n            } else {\n                this._resetChildren(element);\n            }\n\n            this._reloadPrice();\n            this._displayRegularPriceBlock(this.simpleProduct);\n            this._displayTierPriceBlock(this.simpleProduct);\n            this._displayNormalPriceLabel();\n            this._changeProductImage();\n        },\n\n        /**\n         * Change displayed product image according to chosen options of configurable product\n         *\n         * @private\n         */\n        _changeProductImage: function () {\n            var images,\n                initialImages = this.options.mediaGalleryInitial,\n                gallery = $(this.options.mediaGallerySelector).data('gallery');\n\n            if (_.isUndefined(gallery)) {\n                $(this.options.mediaGallerySelector).on('gallery:loaded', function () {\n                    this._changeProductImage();\n                }.bind(this));\n\n                return;\n            }\n\n            images = this.options.spConfig.images[this.simpleProduct];\n\n            if (images) {\n                images = this._sortImages(images);\n\n                if (this.options.gallerySwitchStrategy === 'prepend') {\n                    images = images.concat(initialImages);\n                }\n\n                images = $.extend(true, [], images);\n                images = this._setImageIndex(images);\n\n                gallery.updateData(images);\n                this._addFotoramaVideoEvents(false);\n            } else {\n                gallery.updateData(initialImages);\n                this._addFotoramaVideoEvents(true);\n            }\n        },\n\n        /**\n         * Add video events\n         *\n         * @param {Boolean} isInitial\n         * @private\n         */\n        _addFotoramaVideoEvents: function (isInitial) {\n            if (_.isUndefined($.mage.AddFotoramaVideoEvents)) {\n                return;\n            }\n\n            if (isInitial) {\n                $(this.options.mediaGallerySelector).AddFotoramaVideoEvents();\n\n                return;\n            }\n\n            $(this.options.mediaGallerySelector).AddFotoramaVideoEvents({\n                selectedOption: this.simpleProduct,\n                dataMergeStrategy: this.options.gallerySwitchStrategy\n            });\n        },\n\n        /**\n         * Sorting images array\n         *\n         * @private\n         */\n        _sortImages: function (images) {\n            return _.sortBy(images, function (image) {\n                return image.position;\n            });\n        },\n\n        /**\n         * Set correct indexes for image set.\n         *\n         * @param {Array} images\n         * @private\n         */\n        _setImageIndex: function (images) {\n            var length = images.length,\n                i;\n\n            for (i = 0; length > i; i++) {\n                images[i].i = i + 1;\n            }\n\n            return images;\n        },\n\n        /**\n         * For a given option element, reset all of its selectable options. Clear any selected\n         * index, disable the option choice, and reset the option's state if necessary.\n         * @private\n         * @param {*} element - The element associated with a configurable option.\n         */\n        _resetChildren: function (element) {\n            if (element.childSettings) {\n                _.each(element.childSettings, function (set) {\n                    set.selectedIndex = 0;\n                    set.disabled = true;\n                });\n\n                if (element.config) {\n                    this.options.state[element.config.id] = false;\n                }\n            }\n        },\n\n        /**\n         * Populates an option's selectable choices.\n         * @private\n         * @param {*} element - Element associated with a configurable option.\n         */\n        _fillSelect: function (element) {\n            var attributeId = element.id.replace(/[a-z]*/, ''),\n                options = this._getAttributeOptions(attributeId),\n                prevConfig,\n                index = 1,\n                allowedProducts,\n                allowedProductsByOption,\n                allowedProductsAll,\n                i,\n                j,\n                finalPrice = parseFloat(this.options.spConfig.prices.finalPrice.amount),\n                optionFinalPrice,\n                optionPriceDiff,\n                optionPrices = this.options.spConfig.optionPrices,\n                allowedOptions = [],\n                indexKey,\n                allowedProductMinPrice,\n                allowedProductsAllMinPrice,\n                canDisplayOutOfStockProducts = false,\n                filteredSalableProducts;\n\n            this._clearSelect(element);\n            element.options[0] = new Option('', '');\n            element.options[0].innerHTML = this.options.spConfig.chooseText;\n            prevConfig = false;\n\n            if (element.prevSetting) {\n                prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];\n            }\n\n            if (options) {\n                for (indexKey in this.options.spConfig.index) {\n                    /* eslint-disable max-depth */\n                    if (this.options.spConfig.index.hasOwnProperty(indexKey)) {\n                        allowedOptions = allowedOptions.concat(_.values(this.options.spConfig.index[indexKey]));\n                    }\n                }\n\n                if (prevConfig) {\n                    allowedProductsByOption = {};\n                    allowedProductsAll = [];\n\n                    for (i = 0; i < options.length; i++) {\n                        /* eslint-disable max-depth */\n                        for (j = 0; j < options[i].products.length; j++) {\n                            // prevConfig.config can be undefined\n                            if (prevConfig.config &&\n                                prevConfig.config.allowedProducts &&\n                                prevConfig.config.allowedProducts.indexOf(options[i].products[j]) > -1) {\n                                if (!allowedProductsByOption[i]) {\n                                    allowedProductsByOption[i] = [];\n                                }\n                                allowedProductsByOption[i].push(options[i].products[j]);\n                                allowedProductsAll.push(options[i].products[j]);\n                            }\n                        }\n                    }\n\n                    if (typeof allowedProductsAll[0] !== 'undefined' &&\n                        typeof optionPrices[allowedProductsAll[0]] !== 'undefined') {\n                        allowedProductsAllMinPrice = this._getAllowedProductWithMinPrice(allowedProductsAll);\n                        finalPrice = parseFloat(optionPrices[allowedProductsAllMinPrice].finalPrice.amount);\n                    }\n                }\n\n                for (i = 0; i < options.length; i++) {\n                    if (prevConfig && typeof allowedProductsByOption[i] === 'undefined') {\n                        continue; //jscs:ignore disallowKeywords\n                    }\n\n                    allowedProducts = prevConfig ? allowedProductsByOption[i] : options[i].products.slice(0);\n                    optionPriceDiff = 0;\n\n                    if (typeof allowedProducts[0] !== 'undefined' &&\n                        typeof optionPrices[allowedProducts[0]] !== 'undefined') {\n                        allowedProductMinPrice = this._getAllowedProductWithMinPrice(allowedProducts);\n                        optionFinalPrice = parseFloat(optionPrices[allowedProductMinPrice].finalPrice.amount);\n                        optionPriceDiff = optionFinalPrice - finalPrice;\n                        options[i].label = options[i].initialLabel;\n\n                        if (optionPriceDiff !== 0) {\n                            options[i].label += ' ' + priceUtils.formatPriceLocale(\n                                optionPriceDiff,\n                                this.options.priceFormat,\n                                true\n                            );\n                        }\n                    }\n\n                    if (allowedProducts.length > 0 || _.include(allowedOptions, options[i].id)) {\n                        options[i].allowedProducts = allowedProducts;\n                        element.options[index] = new Option(this._getOptionLabel(options[i]), options[i].id);\n\n                        if (this.options.spConfig.canDisplayShowOutOfStockStatus) {\n                            filteredSalableProducts = $(this.options.spConfig.salable[attributeId][options[i].id]).\n                            filter(options[i].allowedProducts);\n                            canDisplayOutOfStockProducts = filteredSalableProducts.length === 0;\n                        }\n\n                        if (typeof options[i].price !== 'undefined') {\n                            element.options[index].setAttribute('price', options[i].price);\n                        }\n\n                        if (allowedProducts.length === 0 || canDisplayOutOfStockProducts) {\n                            element.options[index].disabled = true;\n                        }\n\n                        element.options[index].config = options[i];\n                        index++;\n                    }\n\n                    /* eslint-enable max-depth */\n                }\n            }\n        },\n\n        /**\n         * Generate the label associated with a configurable option. This includes the option's\n         * label or value and the option's price.\n         * @private\n         * @param {*} option - A single choice among a group of choices for a configurable option.\n         * @return {String} The option label with option value and price (e.g. Black +1.99)\n         */\n        _getOptionLabel: function (option) {\n            return option.label;\n        },\n\n        /**\n         * Removes an option's selections.\n         * @private\n         * @param {*} element - The element associated with a configurable option.\n         */\n        _clearSelect: function (element) {\n            var i;\n\n            for (i = element.options.length - 1; i >= 0; i--) {\n                element.remove(i);\n            }\n        },\n\n        /**\n         * Retrieve the attribute options associated with a specific attribute Id.\n         * @private\n         * @param {Number} attributeId - The id of the attribute whose configurable options are sought.\n         * @return {Object} Object containing the attribute options.\n         */\n        _getAttributeOptions: function (attributeId) {\n            if (this.options.spConfig.attributes[attributeId]) {\n                return this.options.spConfig.attributes[attributeId].options;\n            }\n        },\n\n        /**\n         * Reload the price of the configurable product incorporating the prices of all of the\n         * configurable product's option selections.\n         */\n        _reloadPrice: function () {\n            $(this.options.priceHolderSelector).trigger('updatePrice', this._getPrices());\n        },\n\n        /**\n         * Get product various prices\n         * @returns {{}}\n         * @private\n         */\n        _getPrices: function () {\n            var prices = {},\n                elements = _.toArray(this.options.settings),\n                allowedProduct;\n\n            _.each(elements, function (element) {\n                var selected = element.options[element.selectedIndex],\n                    config = selected && selected.config,\n                    priceValue = this._calculatePrice({});\n\n                if (config && config.allowedProducts.length === 1) {\n                    priceValue = this._calculatePrice(config);\n                } else if (element.value) {\n                    allowedProduct = this._getAllowedProductWithMinPrice(config.allowedProducts);\n                    priceValue = this._calculatePrice({\n                        'allowedProducts': [\n                            allowedProduct\n                        ]\n                    });\n                }\n\n                if (!_.isEmpty(priceValue)) {\n                    prices.prices = priceValue;\n                }\n            }, this);\n\n            return prices;\n        },\n\n        /**\n         * Get product with minimum price from selected options.\n         *\n         * @param {Array} allowedProducts\n         * @returns {String}\n         * @private\n         */\n        _getAllowedProductWithMinPrice: function (allowedProducts) {\n            var optionPrices = this.options.spConfig.optionPrices,\n                product = {},\n                optionMinPrice, optionFinalPrice;\n\n            _.each(allowedProducts, function (allowedProduct) {\n                optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount);\n\n                if (_.isEmpty(product) || optionFinalPrice < optionMinPrice) {\n                    optionMinPrice = optionFinalPrice;\n                    product = allowedProduct;\n                }\n            }, this);\n\n            return product;\n        },\n\n        /**\n         * Returns prices for configured products\n         *\n         * @param {*} config - Products configuration\n         * @returns {*}\n         * @private\n         */\n        _calculatePrice: function (config) {\n            var displayPrices = $(this.options.priceHolderSelector).priceBox('option').prices,\n                newPrices = this.options.spConfig.optionPrices[_.first(config.allowedProducts)] || {};\n\n            _.each(displayPrices, function (price, code) {\n                displayPrices[code].amount = newPrices[code] ? newPrices[code].amount - displayPrices[code].amount : 0;\n            });\n\n            return displayPrices;\n        },\n\n        /**\n         * Returns Simple product Id\n         *  depending on current selected option.\n         *\n         * @private\n         * @param {HTMLElement} element\n         * @returns {String|undefined}\n         */\n        _getSimpleProductId: function (element) {\n            // TODO: Rewrite algorithm. It should return ID of\n            //        simple product based on selected options.\n            var allOptions = element.config.options,\n                value = element.value,\n                config;\n\n            config = _.filter(allOptions, function (option) {\n                return option.id === value;\n            });\n            config = _.first(config);\n\n            return _.isEmpty(config) ?\n                undefined :\n                _.first(config.allowedProducts);\n\n        },\n\n        /**\n         * Show or hide regular price block\n         *\n         * @param {*} optionId\n         * @private\n         */\n        _displayRegularPriceBlock: function (optionId) {\n            var shouldBeShown = true,\n                $priceBox = this.element.parents(this.options.selectorProduct)\n                    .find(this.options.selectorProductPrice);\n\n            _.each(this.options.settings, function (element) {\n                if (element.value === '') {\n                    shouldBeShown = false;\n                }\n            });\n\n            if (shouldBeShown &&\n                this.options.spConfig.optionPrices[optionId].oldPrice.amount !==\n                this.options.spConfig.optionPrices[optionId].finalPrice.amount\n            ) {\n                $(this.options.slyOldPriceSelector).show();\n            } else {\n                $(this.options.slyOldPriceSelector).hide();\n            }\n\n            $(document).trigger('updateMsrpPriceBlock',\n                [\n                    optionId,\n                    this.options.spConfig.optionPrices,\n                    $priceBox\n                ]\n            );\n        },\n\n        /**\n         * Show or hide normal price label\n         *\n         * @private\n         */\n        _displayNormalPriceLabel: function () {\n            var shouldBeShown = false;\n\n            _.each(this.options.settings, function (element) {\n                if (element.value === '') {\n                    shouldBeShown = true;\n                }\n            });\n\n            if (shouldBeShown) {\n                $(this.options.normalPriceLabelSelector).show();\n            } else {\n                $(this.options.normalPriceLabelSelector).hide();\n            }\n        },\n\n        /**\n         * Callback which fired after gallery gets initialized.\n         *\n         * @param {HTMLElement} element - DOM element associated with gallery.\n         */\n        _onGalleryLoaded: function (element) {\n            var galleryObject = element.data('gallery');\n\n            this.options.mediaGalleryInitial = galleryObject.returnCurrentImages();\n        },\n\n        /**\n         * Show or hide tier price block\n         *\n         * @param {*} optionId\n         * @private\n         */\n        _displayTierPriceBlock: function (optionId) {\n            var tierPrices = typeof optionId != 'undefined' && this.options.spConfig.optionPrices[optionId].tierPrices;\n\n            if (_.isArray(tierPrices) && tierPrices.length > 0) {\n\n                if (this.options.tierPriceTemplate) {\n                    $(this.options.tierPriceBlockSelector).html(\n                        mageTemplate(this.options.tierPriceTemplate, {\n                            'tierPrices': tierPrices,\n                            '$t': $t,\n                            'currencyFormat': this.options.spConfig.currencyFormat,\n                            'priceUtils': priceUtils\n                        })\n                    ).show();\n                }\n            } else {\n                $(this.options.tierPriceBlockSelector).hide();\n            }\n        }\n    });\n\n    return $.mage.configurable;\n});\n","Magento_ConfigurableProduct/js/catalog-add-to-cart.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\nrequire([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    /**\n     * Add selected configurable attributes to redirect url\n     *\n     * @see Magento_Catalog/js/catalog-add-to-cart\n     */\n    $('body').on('catalogCategoryAddToCartRedirect', function (event, data) {\n        $(data.form).find('select[name*=\"super\"]').each(function (index, item) {\n            data.redirectParameters.push(item.config.id + '=' + $(item).val());\n        });\n    });\n});\n","Magento_ConfigurableProduct/js/catalog-add-to-cart-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'jquery',\n    'Magento_ConfigurableProduct/js/product/view/product-info-resolver'\n], function (_, $, productInfoResolver) {\n    'use strict';\n\n    return function (widget) {\n\n        $.widget('mage.catalogAddToCart', widget, {\n            /**\n             * @param {jQuery} form\n             */\n            ajaxSubmit: function (form) {\n                var isConfigurable = !!_.find(form.serializeArray(), function (item) {\n                    return item.name.indexOf('super_attribute') !== -1;\n                });\n\n                if (isConfigurable) {\n                    this.options.productInfoResolver = productInfoResolver;\n                }\n\n                return this._super(form);\n            }\n        });\n\n        return $.mage.catalogAddToCart;\n    };\n});\n","Magento_ConfigurableProduct/js/configurable-customer-data.js":"require([\n    'jquery',\n    'Magento_ConfigurableProduct/js/options-updater'\n], function ($, Updater) {\n    'use strict';\n\n    var selectors = {\n            formSelector: '#product_addtocart_form'\n        },\n        configurableWidgetName = 'mageConfigurable',\n        widgetInitEvent = 'configurable.initialized',\n\n    /**\n    * Sets all configurable attribute's selected values\n    */\n    updateConfigurableOptions = function () {\n        var configurableWidget = $(selectors.formSelector).data(configurableWidgetName);\n\n        if (!configurableWidget) {\n            return;\n        }\n        configurableWidget.options.values = this.productOptions || {};\n        configurableWidget._configureForValues();\n    },\n    updater = new Updater(widgetInitEvent, updateConfigurableOptions);\n\n    updater.listen();\n});\n","Magento_ConfigurableProduct/js/options-updater.js":"define([\n    'jquery',\n    'underscore',\n    'Magento_Customer/js/customer-data',\n    'domReady!'\n], function ($, _, customerData) {\n    'use strict';\n\n    var selectors = {\n        formSelector: '#product_addtocart_form',\n        productIdSelector: '#product_addtocart_form [name=\"product\"]',\n        itemIdSelector: '#product_addtocart_form [name=\"item\"]'\n    },\n    cartData = customerData.get('cart'),\n    productId = $(selectors.productIdSelector).val(),\n    itemId = $(selectors.itemIdSelector).val(),\n\n    /**\n    * set productOptions according to cart data from customer-data\n    *\n    * @param {Object} data - cart data from customer-data\n    * @returns {Boolean} - whether the new options differ from previous\n    */\n    setProductOptions = function (data) {\n        var changedProductOptions;\n\n        if (!(data && data.items && data.items.length && productId)) {\n            return false;\n        }\n        changedProductOptions = _.find(data.items, function (item) {\n            if (item['item_id'] === itemId) {\n                return item['product_id'] === productId;\n            }\n        });\n        changedProductOptions = changedProductOptions && changedProductOptions.options &&\n            changedProductOptions.options.reduce(function (obj, val) {\n                obj[val['option_id']] = val['option_value'];\n\n                return obj;\n            }, {});\n\n        if (JSON.stringify(this.productOptions || {}) === JSON.stringify(changedProductOptions || {})) {\n            return false;\n        }\n\n        this.productOptions = changedProductOptions;\n\n        return true;\n    },\n\n    /**\n    * Listens to update of cart data or options initialization and update selected option according to customer data\n    *\n    */\n    listen = function () {\n        cartData.subscribe(function (updateCartData) {\n            if (this.setProductOptions(updateCartData)) {\n                this.updateOptions();\n            }\n        }.bind(this));\n        $(selectors.formSelector).on(this.eventName, function () {\n            this.setProductOptions(cartData());\n            this.updateOptions();\n        }.bind(this));\n    },\n\n    /**\n    * Updater constructor function\n    *\n    */\n    Updater = function (eventName, updateOptionsCallback) {\n        if (this instanceof Updater) {\n            this.eventName = eventName;\n            this.updateOptions = updateOptionsCallback;\n            this.productOptions = {};\n        }\n    };\n\n    Updater.prototype.setProductOptions = setProductOptions;\n    Updater.prototype.listen = listen;\n\n    return Updater;\n});\n","Magento_ConfigurableProduct/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 configurable products in form.\n     *\n     * @param {jQuery} $form\n     * @return {Array}\n     */\n    return function ($form) {\n        var optionValues = [],\n            product = _.findWhere($form.serializeArray(), {\n                name: 'product'\n            }),\n            productId;\n\n        if (!_.isUndefined(product)) {\n            productId = product.value;\n            _.each($form.serializeArray(), function (item) {\n                if (item.name.indexOf('super_attribute') !== -1) {\n                    optionValues.push(item.value);\n                }\n            });\n            optionValues.sort();\n            productInfo().push(\n                {\n                    'id': productId,\n                    'optionValues': optionValues\n                }\n            );\n        }\n\n        return _.uniq(productInfo(), function (item) {\n            var optionValuesStr = item.optionValues ? item.optionValues.join() : '';\n\n            return item.id + optionValuesStr;\n        });\n    };\n});\n\n","Magento_CatalogSearch/js/search-terms-log.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mageUtils'\n], function ($, utils) {\n    'use strict';\n\n    return function (data) {\n        $.ajax({\n            method: 'GET',\n            url: data.url,\n            data: {\n                'q': utils.getUrlParameters(window.location.href).q\n            }\n        });\n    };\n});\n","Magento_Shipping/js/view/checkout/shipping/shipping-policy.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_Shipping/js/model/config'\n\n], function (Component, config) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_Shipping/checkout/shipping/shipping-policy'\n        },\n        config: config()\n    });\n});\n","Magento_Shipping/js/model/config.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 function () {\n        return window.checkoutConfig.shippingPolicy;\n    };\n});\n","Magento_Search/js/form-mini.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    'mage/template',\n    'matchMedia',\n    'jquery-ui-modules/widget',\n    'jquery-ui-modules/core',\n    'mage/translate'\n], function ($, _, mageTemplate, mediaCheck) {\n    'use strict';\n\n    /**\n     * Check whether the incoming string is not empty or if doesn't consist of spaces.\n     *\n     * @param {String} value - Value to check.\n     * @returns {Boolean}\n     */\n    function isEmpty(value) {\n        return value.length === 0 || value == null || /^\\s+$/.test(value);\n    }\n\n    $.widget('mage.quickSearch', {\n        options: {\n            autocomplete: 'off',\n            minSearchLength: 3,\n            responseFieldElements: 'ul li',\n            selectClass: 'selected',\n            template:\n                '<li class=\"<%- data.row_class %>\" id=\"qs-option-<%- data.index %>\" role=\"option\">' +\n                '<span class=\"qs-option-name\">' +\n                ' <%- data.title %>' +\n                '</span>' +\n                '<span aria-hidden=\"true\" class=\"amount\">' +\n                '<%- data.num_results %>' +\n                '</span>' +\n                '</li>',\n            submitBtn: 'button[type=\"submit\"]',\n            searchLabel: '[data-role=minisearch-label]',\n            isExpandable: null,\n            suggestionDelay: 300\n        },\n\n        /** @inheritdoc */\n        _create: function () {\n            this.responseList = {\n                indexList: null,\n                selected: null\n            };\n            this.autoComplete = $(this.options.destinationSelector);\n            this.searchForm = $(this.options.formSelector);\n            this.submitBtn = this.searchForm.find(this.options.submitBtn)[0];\n            this.searchLabel = this.searchForm.find(this.options.searchLabel);\n            this.isExpandable = this.options.isExpandable;\n\n            _.bindAll(this, '_onKeyDown', '_onPropertyChange', '_onSubmit');\n\n            this.submitBtn.disabled = true;\n\n            this.element.attr('autocomplete', this.options.autocomplete);\n\n            mediaCheck({\n                media: '(max-width: 768px)',\n                entry: function () {\n                    this.isExpandable = true;\n                }.bind(this),\n                exit: function () {\n                    this.isExpandable = true;\n                }.bind(this)\n            });\n\n            this.searchLabel.on('click', function (e) {\n                // allow input to lose its' focus when clicking on label\n                if (this.isExpandable && this.isActive()) {\n                    e.preventDefault();\n                }\n            }.bind(this));\n\n            this.element.on('blur', $.proxy(function () {\n                if (!this.searchLabel.hasClass('active')) {\n                    return;\n                }\n\n                setTimeout($.proxy(function () {\n                    if (this.autoComplete.is(':hidden')) {\n                        this.setActiveState(false);\n                    } else {\n                        this.element.trigger('focus');\n                    }\n                    this.autoComplete.hide();\n                    this._updateAriaHasPopup(false);\n                }, this), 250);\n            }, this));\n\n            if (this.element.get(0) === document.activeElement) {\n                this.setActiveState(true);\n            }\n\n            this.element.on('focus', this.setActiveState.bind(this, true));\n            this.element.on('keydown', this._onKeyDown);\n            // Prevent spamming the server with requests by waiting till the user has stopped typing for period of time\n            this.element.on('input propertychange', _.debounce(this._onPropertyChange, this.options.suggestionDelay));\n\n            this.searchForm.on('submit', $.proxy(function (e) {\n                this._onSubmit(e);\n                this._updateAriaHasPopup(false);\n            }, this));\n        },\n\n        /**\n         * Checks if search field is active.\n         *\n         * @returns {Boolean}\n         */\n        isActive: function () {\n            return this.searchLabel.hasClass('active');\n        },\n\n        /**\n         * Sets state of the search field to provided value.\n         *\n         * @param {Boolean} isActive\n         */\n        setActiveState: function (isActive) {\n            var searchValue;\n\n            this.searchForm.toggleClass('active', isActive);\n            this.searchLabel.toggleClass('active', isActive);\n\n            if (this.isExpandable) {\n                this.element.attr('aria-expanded', isActive);\n                searchValue = this.element.val();\n                this.element.val('');\n                this.element.val(searchValue);\n            }\n        },\n\n        /**\n         * @private\n         * @return {Element} The first element in the suggestion list.\n         */\n        _getFirstVisibleElement: function () {\n            return this.responseList.indexList ? this.responseList.indexList.first() : false;\n        },\n\n        /**\n         * @private\n         * @return {Element} The last element in the suggestion list.\n         */\n        _getLastElement: function () {\n            return this.responseList.indexList ? this.responseList.indexList.last() : false;\n        },\n\n        /**\n         * @private\n         * @param {Boolean} show - Set attribute aria-haspopup to \"true/false\" for element.\n         */\n        _updateAriaHasPopup: function (show) {\n            if (show) {\n                this.element.attr('aria-haspopup', 'true');\n            } else {\n                this.element.attr('aria-haspopup', 'false');\n            }\n        },\n\n        /**\n         * Clears the item selected from the suggestion list and resets the suggestion list.\n         * @private\n         * @param {Boolean} all - Controls whether to clear the suggestion list.\n         */\n        _resetResponseList: function (all) {\n            this.responseList.selected = null;\n\n            if (all === true) {\n                this.responseList.indexList = null;\n            }\n        },\n\n        /**\n         * Executes when the search box is submitted. Sets the search input field to the\n         * value of the selected item.\n         * @private\n         * @param {Event} e - The submit event\n         */\n        _onSubmit: function (e) {\n            var value = this.element.val();\n\n            if (isEmpty(value)) {\n                e.preventDefault();\n            }\n\n            if (this.responseList.selected) {\n                this.element.val(this.responseList.selected.find('.qs-option-name').text());\n            }\n        },\n\n        /**\n         * Executes when keys are pressed in the search input field. Performs specific actions\n         * depending on which keys are pressed.\n         * @private\n         * @param {Event} e - The key down event\n         * @return {Boolean} Default return type for any unhandled keys\n         */\n        _onKeyDown: function (e) {\n            var keyCode = e.keyCode || e.which;\n\n            switch (keyCode) {\n                case $.ui.keyCode.HOME:\n                    if (this._getFirstVisibleElement()) {\n                        this._getFirstVisibleElement().addClass(this.options.selectClass);\n                        this.responseList.selected = this._getFirstVisibleElement();\n                    }\n                    break;\n\n                case $.ui.keyCode.END:\n                    if (this._getLastElement()) {\n                        this._getLastElement().addClass(this.options.selectClass);\n                        this.responseList.selected = this._getLastElement();\n                    }\n                    break;\n\n                case $.ui.keyCode.ESCAPE:\n                    this._resetResponseList(true);\n                    this.autoComplete.hide();\n                    break;\n\n                case $.ui.keyCode.ENTER:\n                    if (this.element.val().length >= parseInt(this.options.minSearchLength, 10)) {\n                        this.searchForm.trigger('submit');\n                        e.preventDefault();\n                    }\n                    break;\n\n                case $.ui.keyCode.DOWN:\n                    if (this.responseList.indexList) {\n                        if (!this.responseList.selected) {  //eslint-disable-line max-depth\n                            this._getFirstVisibleElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getFirstVisibleElement();\n                        } else if (!this._getLastElement().hasClass(this.options.selectClass)) {\n                            this.responseList.selected = this.responseList.selected\n                                .removeClass(this.options.selectClass).next().addClass(this.options.selectClass);\n                        } else {\n                            this.responseList.selected.removeClass(this.options.selectClass);\n                            this._getFirstVisibleElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getFirstVisibleElement();\n                        }\n                        this.element.val(this.responseList.selected.find('.qs-option-name').text());\n                        this.element.attr('aria-activedescendant', this.responseList.selected.attr('id'));\n                        this._updateAriaHasPopup(true);\n                        this.autoComplete.show();\n                    }\n                    break;\n\n                case $.ui.keyCode.UP:\n                    if (this.responseList.indexList !== null) {\n                        if (!this._getFirstVisibleElement().hasClass(this.options.selectClass)) {\n                            this.responseList.selected = this.responseList.selected\n                                .removeClass(this.options.selectClass).prev().addClass(this.options.selectClass);\n\n                        } else {\n                            this.responseList.selected.removeClass(this.options.selectClass);\n                            this._getLastElement().addClass(this.options.selectClass);\n                            this.responseList.selected = this._getLastElement();\n                        }\n                        this.element.val(this.responseList.selected.find('.qs-option-name').text());\n                        this.element.attr('aria-activedescendant', this.responseList.selected.attr('id'));\n                        this._updateAriaHasPopup(true);\n                        this.autoComplete.show();\n                    }\n                    break;\n                default:\n                    return true;\n            }\n        },\n\n        /**\n         * Executes when the value of the search input field changes. Executes a GET request\n         * to populate a suggestion list based on entered text. Handles click (select), hover,\n         * and mouseout events on the populated suggestion list dropdown.\n         * @private\n         */\n        _onPropertyChange: function () {\n            var searchField = this.element,\n                clonePosition = {\n                    position: 'absolute',\n                    // Removed to fix display issues\n                    // left: searchField.offset().left,\n                    // top: searchField.offset().top + searchField.outerHeight(),\n                    width: searchField.outerWidth()\n                },\n                source = this.options.template,\n                template = mageTemplate(source),\n                dropdown = $('<ul role=\"listbox\"></ul>'),\n                value = this.element.val();\n\n            this.submitBtn.disabled = true;\n\n            if (value.length >= parseInt(this.options.minSearchLength, 10)) {\n                this.submitBtn.disabled = false;\n\n                if (this.options.url !== '') { //eslint-disable-line eqeqeq\n                    $.getJSON(this.options.url, {\n                        q: value\n                    }, $.proxy(function (data) {\n                        if (data.length) {\n                            $.each(data, function (index, element) {\n                                var html;\n\n                                element.index = index;\n                                html = template({\n                                    data: element\n                                });\n                                dropdown.append(html);\n                            });\n\n                            this._resetResponseList(true);\n\n                            this.responseList.indexList = this.autoComplete.html(dropdown)\n                                .css(clonePosition)\n                                .show()\n                                .find(this.options.responseFieldElements + ':visible');\n\n                            this.element.removeAttr('aria-activedescendant');\n\n                            if (this.responseList.indexList.length) {\n                                this._updateAriaHasPopup(true);\n                            } else {\n                                this._updateAriaHasPopup(false);\n                            }\n\n                            this.responseList.indexList\n                                .on('click', function (e) {\n                                    this.responseList.selected = $(e.currentTarget);\n                                    this.searchForm.trigger('submit');\n                                }.bind(this))\n                                .on('mouseenter mouseleave', function (e) {\n                                    this.responseList.indexList.removeClass(this.options.selectClass);\n                                    $(e.target).addClass(this.options.selectClass);\n                                    this.responseList.selected = $(e.target);\n                                    this.element.attr('aria-activedescendant', $(e.target).attr('id'));\n                                }.bind(this))\n                                .on('mouseout', function (e) {\n                                    if (!this._getLastElement() &&\n                                        this._getLastElement().hasClass(this.options.selectClass)) {\n                                        $(e.target).removeClass(this.options.selectClass);\n                                        this._resetResponseList(false);\n                                    }\n                                }.bind(this));\n                        } else {\n                            this._resetResponseList(true);\n                            this.autoComplete.hide();\n                            this._updateAriaHasPopup(false);\n                            this.element.removeAttr('aria-activedescendant');\n                        }\n                    }, this));\n                }\n            } else {\n                this._resetResponseList(true);\n                this.autoComplete.hide();\n                this._updateAriaHasPopup(false);\n                this.element.removeAttr('aria-activedescendant');\n            }\n        }\n    });\n\n    return $.mage.quickSearch;\n});\n","Magento_Vault/js/view/payment/vault.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\n/* @api */\ndefine([\n    'underscore',\n    'uiComponent',\n    'Magento_Checkout/js/model/payment/renderer-list',\n    'uiLayout',\n    'uiRegistry'\n], function (_, Component, rendererList, layout, registry) {\n    'use strict';\n\n    var vaultGroupName = 'vaultGroup';\n\n    layout([{\n        name: vaultGroupName,\n        component: 'Magento_Checkout/js/model/payment/method-group',\n        alias: 'vault',\n        sortOrder: 10\n    }]);\n\n    registry.get(vaultGroupName, function (vaultGroup) {\n        _.each(window.checkoutConfig.payment.vault, function (config, index) {\n            rendererList.push(\n                {\n                    type: index,\n                    config: config.config,\n                    component: config.component,\n                    group: vaultGroup,\n\n                    /**\n                     * Custom payment method types comparator\n                     * @param {String} typeA\n                     * @param {String} typeB\n                     * @return {Boolean}\n                     */\n                    typeComparatorCallback: function (typeA, typeB) {\n                        // vault token items have the same name as vault payment without index\n                        return typeA.substring(0, typeA.lastIndexOf('_')) === typeB;\n                    }\n                }\n            );\n        });\n    });\n\n    /**\n     * Add view logic here if needed\n     */\n    return Component.extend({});\n});\n","Magento_Vault/js/view/payment/vault-enabler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\n/* @api */\ndefine(\n    [\n        'uiElement'\n    ],\n    function (\n        Component\n    ) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                isActivePaymentTokenEnabler: true\n            },\n\n            /**\n             * @param {String} paymentCode\n             */\n            setPaymentCode: function (paymentCode) {\n                this.paymentCode = paymentCode;\n            },\n\n            /**\n             * @returns {Object}\n             */\n            initObservable: function () {\n                this._super()\n                    .observe([\n                        'isActivePaymentTokenEnabler'\n                    ]);\n\n                return this;\n            },\n\n            /**\n             * @param {Object} data\n             */\n            visitAdditionalData: function (data) {\n                if (!this.isVaultEnabled()) {\n                    return;\n                }\n\n                if (!('additional_data' in data)) {\n                    data['additional_data'] = {};\n                }\n\n                data['additional_data']['is_active_payment_token_enabler'] = this.isActivePaymentTokenEnabler();\n            },\n\n            /**\n             * @returns {Boolean}\n             */\n            isVaultEnabled: function () {\n                return typeof window.checkoutConfig.vault[this.paymentCode] !== 'undefined' &&\n                    window.checkoutConfig.vault[this.paymentCode]['is_enabled'] === true;\n            }\n        });\n    }\n);\n","Magento_Vault/js/view/payment/method-renderer/vault.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n\ndefine(\n    [\n        'Magento_Checkout/js/view/payment/default',\n        'Magento_Checkout/js/action/select-payment-method',\n        'Magento_Checkout/js/checkout-data'\n    ],\n    function (Component, selectPaymentMethod, checkoutData) {\n        'use strict';\n\n        return Component.extend({\n            defaults: {\n                template: 'Magento_Vault/payment/form'\n            },\n\n            /**\n             * @returns {exports.initObservable}\n             */\n            initObservable: function () {\n                this._super()\n                    .observe([]);\n\n                return this;\n            },\n\n            /**\n             * @returns\n             */\n            selectPaymentMethod: function () {\n                selectPaymentMethod(\n                    {\n                        method: this.getId()\n                    }\n                );\n                checkoutData.setSelectedPaymentMethod(this.getId());\n\n                return true;\n            },\n\n            /**\n             * @returns {String}\n             */\n            getTitle: function () {\n                return '';\n            },\n\n            /**\n             * @returns {String}\n             */\n            getToken: function () {\n                return '';\n            },\n\n            /**\n             * @returns {String}\n             */\n            getId: function () {\n                return this.index;\n            },\n\n            /**\n             * @returns {String}\n             */\n            getCode: function () {\n                return this.code;\n            },\n\n            /**\n             * Get last 4 digits of card\n             * @returns {String}\n             */\n            getMaskedCard: function () {\n                return '';\n            },\n\n            /**\n             * Get expiration date\n             * @returns {String}\n             */\n            getExpirationDate: function () {\n                return '';\n            },\n\n            /**\n             * Get card type\n             * @returns {String}\n             */\n            getCardType: function () {\n                return '';\n            },\n\n            /**\n             * @param {String} type\n             * @returns {Boolean}\n             */\n            getIcons: function (type) {\n                return window.checkoutConfig.payment.ccform.icons.hasOwnProperty(type) ?\n                    window.checkoutConfig.payment.ccform.icons[type]\n                    : false;\n            },\n\n            /**\n             * Return state of place order button.\n             *\n             * @return {Boolean}\n             */\n            isButtonActive: function () {\n                return this.isActive() && this.isPlaceOrderActionAllowed();\n            },\n\n            /**\n             * Check if payment is active.\n             *\n             * @return {Boolean}\n             */\n            isActive: function () {\n                return this.isChecked() === this.getId();\n            },\n\n            /**\n             * @returns {*}\n             */\n            getData: function () {\n                var data = {\n                    method: this.getCode()\n                };\n\n                data['additional_data'] = {};\n                data['additional_data']['public_hash'] = this.getToken();\n\n                return data;\n            }\n        });\n    }\n);\n","Magento_Vault/js/customer_account/deleteWidget.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/modalToggle',\n    'mage/translate'\n], function ($, modalToggle) {\n    'use strict';\n\n    return function (config, deleteButton) {\n        config.buttons = [\n            {\n                text: $.mage.__('Cancel'),\n                class: 'action secondary cancel'\n            }, {\n                text: $.mage.__('Delete'),\n                class: 'action primary',\n\n                /**\n                 * Default action on button click\n                 */\n                click: function (event) { //eslint-disable-line no-unused-vars\n                    $(deleteButton.form).trigger('submit');\n                }\n            }\n        ];\n\n        modalToggle(config, deleteButton);\n    };\n});\n","Magento_GiftMessage/js/gift-options.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.giftOptions', {\n        options: {\n            mageError: 'mage-error',\n            noDisplay: 'no-display',\n            requiredEntry: 'required-entry'\n        },\n\n        /**\n         * Initial toggle of the various gift options after widget instantiation.\n         * @private\n         */\n        _init: function () {\n            this._toggleVisibility();\n        },\n\n        /**\n         * Bind a click handler to the widget's context element.\n         * @private\n         */\n        _create: function () {\n            this.element.on('click', $.proxy(this._toggleVisibility, this));\n            $(this.element.data('selector').id).find('.giftmessage-area')\n                .on('change', $.proxy(this._toggleRequired, this));\n        },\n\n        /**\n         * Toggle the visibility of the widget's context element's selector(s).\n         * @private\n         * @param {jQuery.Event} event - Click event. Target is a checkbox.\n         */\n        _toggleVisibility: function (event) {\n            var checkbox = event ? $(event.target) : this.element,\n                container = $(checkbox.data('selector').id),\n                _this;\n\n            if (checkbox.is(':checked')) {\n                container.show()\n                    .find('.giftmessage-area:not(:visible)').each(function (x, element) {\n                        if ($(element).val().length > 0) {\n                            $(element).trigger('change');\n                            container.find('a').trigger('click');\n                        }\n                    });\n            } else {\n                _this = this;\n                container.hide()\n                    .find('.input-text:not(.giftmessage-area)').each(function (x, element) {\n                        $(element).val(element.defaultValue).removeClass(_this.options.mageError)\n                            .next('div.' + _this.options.mageError).remove();\n                    }).end()\n                    .find('.giftmessage-area').val('').change().end()\n                    .find('.select').val('').change().end()\n                    .find('.checkbox:checked').prop('checked', false).trigger('click').prop('checked', false).end()\n                    .find('.price-box').addClass(this.options.noDisplay).end();\n            }\n        },\n\n        /**\n         * Make the From and To input fields required if a gift message has been written.\n         * @private\n         * @param {jQuery.Event} event - Change event. Target is a textarea.\n         */\n        _toggleRequired: function (event) {\n            var textArea = $(event.target),\n                length = textArea.val().length;\n\n            textArea.closest('li').prev('.fields')\n                .find('.input-text').toggleClass(this.options.requiredEntry, length > 0);\n        }\n    });\n\n    return $.mage.giftOptions;\n});\n","Magento_GiftMessage/js/view/gift-message.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'Magento_GiftMessage/js/model/gift-message',\n    'Magento_GiftMessage/js/model/gift-options',\n    'Magento_GiftMessage/js/action/gift-options'\n], function (Component, GiftMessage, giftOptions, giftOptionsService) {\n    'use strict';\n\n    return Component.extend({\n        formBlockVisibility: null,\n        resultBlockVisibility: null,\n        model: {},\n\n        /**\n         * Component init\n         */\n        initialize: function () {\n            var self = this,\n                model;\n\n            this._super()\n                .observe('formBlockVisibility')\n                .observe({\n                    'resultBlockVisibility': false\n                });\n\n            this.itemId = this.itemId || 'orderLevel';\n            model = new GiftMessage(this.itemId);\n            this.model = model;\n            this.isResultBlockVisible();\n            giftOptions.addOption(model);\n\n            this.model.getObservable('isClear').subscribe(function (value) {\n                if (value == true) { //eslint-disable-line eqeqeq\n                    self.formBlockVisibility(false);\n                    self.model.getObservable('alreadyAdded')(true);\n                }\n            });\n        },\n\n        /**\n         * Is reslt block visible\n         */\n        isResultBlockVisible: function () {\n            var self = this;\n\n            if (this.model.getObservable('alreadyAdded')()) {\n                this.resultBlockVisibility(true);\n            }\n            this.model.getObservable('additionalOptionsApplied').subscribe(function (value) {\n                if (value == true) { //eslint-disable-line eqeqeq\n                    self.resultBlockVisibility(true);\n                }\n            });\n        },\n\n        /**\n         * @param {String} key\n         * @return {*}\n         */\n        getObservable: function (key) {\n            return this.model.getObservable(key);\n        },\n\n        /**\n         * Hide\\Show form block\n         */\n        toggleFormBlockVisibility: function () {\n            if (!this.model.getObservable('alreadyAdded')()) {\n                this.formBlockVisibility(!this.formBlockVisibility());\n            } else {\n                this.resultBlockVisibility(!this.resultBlockVisibility());\n            }\n        },\n\n        /**\n         * Edit options\n         */\n        editOptions: function () {\n            this.resultBlockVisibility(false);\n            this.formBlockVisibility(true);\n        },\n\n        /**\n         * Delete options\n         */\n        deleteOptions: function () {\n            giftOptionsService(this.model, true);\n        },\n\n        /**\n         * Hide form block\n         */\n        hideFormBlock: function () {\n            this.formBlockVisibility(false);\n\n            if (this.model.getObservable('alreadyAdded')()) {\n                this.resultBlockVisibility(true);\n            }\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        hasActiveOptions: function () {\n            var regionData = this.getRegion('additionalOptions'),\n                options = regionData(),\n                i;\n\n            for (i = 0; i < options.length; i++) {\n                if (options[i].isActive()) {\n                    return true;\n                }\n            }\n\n            return false;\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        isActive: function () {\n            return this.model.isGiftMessageAvailable();\n        },\n\n        /**\n         * Submit options\n         */\n        submitOptions: function () {\n            giftOptionsService(this.model);\n        }\n    });\n});\n","Magento_GiftMessage/js/action/gift-options.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'Magento_GiftMessage/js/model/url-builder',\n    'mage/storage',\n    'Magento_Ui/js/model/messageList',\n    'Magento_Checkout/js/model/error-processor',\n    'mage/url',\n    'Magento_Checkout/js/model/quote',\n    'underscore'\n], function (urlBuilder, storage, messageList, errorProcessor, url, quote, _) {\n    'use strict';\n\n    return function (giftMessage, remove) {\n        var serviceUrl;\n\n        url.setBaseUrl(giftMessage.getConfigValue('baseUrl'));\n\n        if (giftMessage.getConfigValue('isCustomerLoggedIn')) {\n            serviceUrl = urlBuilder.createUrl('/carts/mine/gift-message', {});\n\n            if (giftMessage.itemId != 'orderLevel') { //eslint-disable-line eqeqeq\n                serviceUrl = urlBuilder.createUrl('/carts/mine/gift-message/:itemId', {\n                    itemId: giftMessage.itemId\n                });\n            }\n        } else {\n            serviceUrl = urlBuilder.createUrl('/guest-carts/:cartId/gift-message', {\n                cartId: quote.getQuoteId()\n            });\n\n            if (giftMessage.itemId != 'orderLevel') { //eslint-disable-line eqeqeq\n                serviceUrl = urlBuilder.createUrl(\n                    '/guest-carts/:cartId/gift-message/:itemId',\n                    {\n                        cartId: quote.getQuoteId(), itemId: giftMessage.itemId\n                    }\n                );\n            }\n        }\n        messageList.clear();\n\n        storage.post(\n            serviceUrl,\n            JSON.stringify({\n                'gift_message': giftMessage.getSubmitParams(remove)\n            })\n        ).done(function () {\n            giftMessage.reset();\n            _.each(giftMessage.getAfterSubmitCallbacks(), function (callback) {\n                if (_.isFunction(callback)) {\n                    callback();\n                }\n            });\n        }).fail(function (response) {\n            errorProcessor.process(response);\n        });\n    };\n});\n","Magento_GiftMessage/js/model/gift-message.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'uiElement',\n    'underscore',\n    'mage/url'\n], function (uiElement, _, url) {\n    'use strict';\n\n    var provider = uiElement();\n\n    return function (itemId) {\n        var model = {\n            id: 'message-' + itemId,\n            itemId: itemId,\n            observables: {},\n            additionalOptions: [],\n            submitParams: [\n                'recipient',\n                'sender',\n                'message'\n            ],\n\n            /**\n             * Initialize.\n             */\n            initialize: function () {\n                var message = false;\n\n                this.getObservable('alreadyAdded')(false);\n\n                if (this.itemId == 'orderLevel') { //eslint-disable-line eqeqeq\n                    message = window.giftOptionsConfig.giftMessage.hasOwnProperty(this.itemId) ?\n                        window.giftOptionsConfig.giftMessage[this.itemId] :\n                        null;\n                } else {\n                    message =\n                        window.giftOptionsConfig.giftMessage.hasOwnProperty('itemLevel') &&\n                        window.giftOptionsConfig.giftMessage.itemLevel.hasOwnProperty(this.itemId) ?\n                            window.giftOptionsConfig.giftMessage.itemLevel[this.itemId].message :\n                            null;\n                }\n\n                if (_.isObject(message)) {\n                    this.getObservable('recipient')(message.recipient);\n                    this.getObservable('sender')(message.sender);\n                    this.getObservable('message')(message.message);\n                    this.getObservable('alreadyAdded')(true);\n                }\n            },\n\n            /**\n             * @param {String} key\n             * @return {*}\n             */\n            getObservable: function (key) {\n                this.initObservable(this.id, key);\n\n                return provider[this.getUniqueKey(this.id, key)];\n            },\n\n            /**\n             * @param {String} node\n             * @param {String} key\n             */\n            initObservable: function (node, key) {\n                if (node && !this.observables.hasOwnProperty(node)) {\n                    this.observables[node] = [];\n                }\n\n                if (key && this.observables[node].indexOf(key) === -1) {\n                    this.observables[node].push(key);\n                    provider.observe(this.getUniqueKey(node, key));\n                }\n            },\n\n            /**\n             * @param {String} node\n             * @param {String} key\n             * @return {String}\n             */\n            getUniqueKey: function (node, key) {\n                return node + '-' + key;\n            },\n\n            /**\n             * @param {String} key\n             * @return {null}\n             */\n            getConfigValue: function (key) {\n                return window.giftOptionsConfig.hasOwnProperty(key) ?\n                    window.giftOptionsConfig[key]\n                    : null;\n            },\n\n            /**\n             * Reset.\n             */\n            reset: function () {\n                this.getObservable('isClear')(true);\n            },\n\n            /**\n             * @return {Array}\n             */\n            getAfterSubmitCallbacks: function () {\n                var callbacks = [];\n\n                callbacks.push(this.afterSubmit);\n                _.each(this.additionalOptions, function (option) {\n                    if (_.isFunction(option.afterSubmit)) {\n                        callbacks.push(option.afterSubmit);\n                    }\n                });\n\n                return callbacks;\n            },\n\n            /**\n             * After submit.\n             */\n            afterSubmit: function () {\n                window.location.href = url.build('checkout/cart/updatePost') +\n                    '?form_key=' + window.checkoutConfig.formKey +\n                    '&cart[]';\n            },\n\n            /**\n             * @param {Boolean} remove\n             * @return {Object}\n             */\n            getSubmitParams: function (remove) {\n                var params = {},\n                    self = this;\n\n                _.each(this.submitParams, function (key) {\n                    var observable = provider[self.getUniqueKey(self.id, key)];\n\n                    if (_.isFunction(observable)) {\n                        params[key] = remove ? null : observable();\n                    }\n                });\n\n                if (this.additionalOptions.length) {\n                    params['extension_attributes'] = {};\n                }\n                _.each(this.additionalOptions, function (option) {\n                    if (_.isFunction(option.getSubmitParams)) {\n                        params['extension_attributes'] = _.extend(\n                            params['extension_attributes'],\n                            option.getSubmitParams(remove)\n                        );\n                    }\n                });\n\n                return params;\n            },\n\n            /**\n             * Check if gift message can be displayed\n             *\n             * @returns {Boolean}\n             */\n            isGiftMessageAvailable: function () {\n                var isGloballyAvailable,\n                    giftMessageConfig,\n                    itemConfig;\n\n                // itemId represent gift message level: 'orderLevel' constant or cart item ID\n                if (this.itemId === 'orderLevel') {\n                    return this.getConfigValue('isOrderLevelGiftOptionsEnabled');\n                }\n\n                // gift message product configuration must override system configuration\n                isGloballyAvailable = this.getConfigValue('isItemLevelGiftOptionsEnabled');\n                giftMessageConfig = window.giftOptionsConfig.giftMessage;\n                itemConfig = giftMessageConfig.hasOwnProperty('itemLevel') &&\n                    giftMessageConfig.itemLevel.hasOwnProperty(this.itemId) ?\n                    giftMessageConfig.itemLevel[this.itemId] :\n                    {};\n\n                return itemConfig.hasOwnProperty('is_available') ? itemConfig['is_available'] : isGloballyAvailable;\n            }\n        };\n\n        model.initialize();\n\n        return model;\n    };\n});\n","Magento_GiftMessage/js/model/gift-options.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'ko'\n], function (_, ko) {\n    'use strict';\n\n    return {\n        options: ko.observableArray([]),\n\n        /**\n         * @param {Object} option\n         */\n        addOption: function (option) {\n            if (!this.options().hasOwnProperty(option.itemId)) {\n                this.options.push({\n                        id: option.itemId, value: option\n                    }\n                );\n            }\n        },\n\n        /**\n         * @param {*} itemId\n         * @return {*}\n         */\n        getOptionByItemId: function (itemId) {\n            var option = null;\n\n            _.each(this.options(), function (data) {\n                if (data.id === itemId) {\n                    option = data.value;\n\n                    return false;\n                }\n            });\n\n            return option;\n        }\n    };\n});\n","Magento_GiftMessage/js/model/url-builder.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'Magento_Checkout/js/model/url-builder'\n], function ($, urlBuilder) {\n    'use strict';\n\n    return $.extend(urlBuilder, {\n        storeCode: window.giftOptionsConfig.storeCode\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/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                if (this.getIsInvisibleRecaptcha()) {\n                    this.tokenField.value = token;\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                        if (!this.tokenField.value) {\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                if ($('#send2').length > 0) {$('#send2').prop('disabled', false);}\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/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/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/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","Magento_InstantPurchase/js/view/instant-purchase.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    'underscore',\n    'uiComponent',\n    'Magento_Ui/js/modal/confirm',\n    'Magento_Customer/js/customer-data',\n    'mage/url',\n    'mage/template',\n    'mage/translate',\n    'text!Magento_InstantPurchase/template/confirmation.html',\n    'mage/validation'\n], function (ko, $, _, Component, confirm, customerData, urlBuilder, mageTemplate, $t, confirmationTemplate) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            template: 'Magento_InstantPurchase/instant-purchase',\n            buttonText: $t('Instant Purchase'),\n            purchaseUrl: urlBuilder.build('instantpurchase/button/placeOrder'),\n            showButton: false,\n            paymentToken: null,\n            shippingAddress: null,\n            billingAddress: null,\n            shippingMethod: null,\n            productFormSelector: '#product_addtocart_form',\n            confirmationTitle: $t('Instant Purchase Confirmation'),\n            confirmationData: {\n                message: $t('Are you sure you want to place order and pay?'),\n                shippingAddressTitle: $t('Shipping Address'),\n                billingAddressTitle: $t('Billing Address'),\n                paymentMethodTitle: $t('Payment Method'),\n                shippingMethodTitle: $t('Shipping Method')\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            var instantPurchase = customerData.get('instant-purchase');\n\n            this._super();\n\n            this.setPurchaseData(instantPurchase());\n            instantPurchase.subscribe(this.setPurchaseData, this);\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super()\n                .observe('showButton paymentToken shippingAddress billingAddress shippingMethod');\n\n            return this;\n        },\n\n        /**\n         * Set data from customerData.\n         *\n         * @param {Object} data\n         */\n        setPurchaseData: function (data) {\n            this.showButton(data.available);\n            this.paymentToken(data.paymentToken);\n            this.shippingAddress(data.shippingAddress);\n            this.billingAddress(data.billingAddress);\n            this.shippingMethod(data.shippingMethod);\n        },\n\n        /**\n         * Confirmation method\n         */\n        instantPurchase: function () {\n            var form = $(this.productFormSelector),\n                confirmTemplate = mageTemplate(confirmationTemplate),\n                confirmData = _.extend({}, this.confirmationData, {\n                    paymentToken: this.paymentToken().summary,\n                    shippingAddress: this.shippingAddress().summary,\n                    billingAddress: this.billingAddress().summary,\n                    shippingMethod: this.shippingMethod().summary\n                });\n\n            if (!(form.validation() && form.validation('isValid'))) {\n                return;\n            }\n\n            confirm({\n                title: this.confirmationTitle,\n                content: confirmTemplate({\n                    data: confirmData\n                }),\n                actions: {\n                    /** @inheritdoc */\n                    confirm: function () {\n                        $.ajax({\n                            url: this.purchaseUrl,\n                            data: form.serialize(),\n                            type: 'post',\n                            dataType: 'json',\n\n                            /** Show loader before send */\n                            beforeSend: function () {\n                                $('body').trigger('processStart');\n                            }\n                        }).always(function () {\n                            $('body').trigger('processStop');\n                        });\n                    }.bind(this)\n                }\n            });\n        }\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_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_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/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/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","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"}
}});

Spamworldpro Mini