diff --git a/dist/plentymarketsCMStools-1.0.11.min.js b/dist/plentymarketsCMStools-1.0.11.min.js deleted file mode 100644 index 73d2d27..0000000 --- a/dist/plentymarketsCMStools-1.0.11.min.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Licensed under AGPL v3 - * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE) - * ===================================================================================== - * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com) - * @author Felix Dausch - * ===================================================================================== -*/ -var TemplateCache={};TemplateCache["addressSuggestions/addressDoctor.html"]='',TemplateCache["addressSuggestions/postFinder.html"]='{{#addresses}}\n
\n
\n \n
\n
\n{{/addresses}}\n',TemplateCache["error/errorMessage.html"]='
\n Code {{code}}:\n {{{message}}}\n
\n',TemplateCache["error/errorPopup.html"]='
\n \n
\n
\n
\n',TemplateCache["modal/modal.html"]='\n',TemplateCache["waitscreen/waitscreen.html"]='
',function(a,b){"object"==typeof exports&&exports&&"string"!=typeof exports.nodeName?b(exports):"function"==typeof define&&define.amd?define(["exports"],b):(a.Mustache={},b(Mustache))}(this,function(a){function b(a){return"function"==typeof a}function c(a){return p(a)?"array":typeof a}function d(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function e(a,b){return null!=a&&"object"==typeof a&&b in a}function f(a,b){return q.call(a,b)}function g(a){return!f(r,a)}function h(a){return String(a).replace(/[&<>"'\/]/g,function(a){return s[a]})}function i(b,c){function e(){if(r&&!s)for(;q.length;)delete o[q.pop()];else q=[];r=!1,s=!1}function f(a){if("string"==typeof a&&(a=a.split(u,2)),!p(a)||2!==a.length)throw new Error("Invalid tags: "+a);h=new RegExp(d(a[0])+"\\s*"),i=new RegExp("\\s*"+d(a[1])),m=new RegExp("\\s*"+d("}"+a[1]))}if(!b)return[];var h,i,m,n=[],o=[],q=[],r=!1,s=!1;f(c||a.tags);for(var y,z,A,B,C,D,E=new l(b);!E.eos();){if(y=E.pos,A=E.scanUntil(h))for(var F=0,G=A.length;G>F;++F)B=A.charAt(F),g(B)?q.push(o.length):s=!0,o.push(["text",B,y,y+1]),y+=1,"\n"===B&&e();if(!E.scan(h))break;if(r=!0,z=E.scan(x)||"name",E.scan(t),"="===z?(A=E.scanUntil(v),E.scan(v),E.scanUntil(i)):"{"===z?(A=E.scanUntil(m),E.scan(w),E.scanUntil(i),z="&"):A=E.scanUntil(i),!E.scan(i))throw new Error("Unclosed tag at "+E.pos);if(C=[z,A,y,E.pos],o.push(C),"#"===z||"^"===z)n.push(C);else if("/"===z){if(D=n.pop(),!D)throw new Error('Unopened section "'+A+'" at '+y);if(D[1]!==A)throw new Error('Unclosed section "'+D[1]+'" at '+y)}else"name"===z||"{"===z||"&"===z?s=!0:"="===z&&f(A)}if(D=n.pop())throw new Error('Unclosed section "'+D[1]+'" at '+E.pos);return k(j(o))}function j(a){for(var b,c,d=[],e=0,f=a.length;f>e;++e)b=a[e],b&&("text"===b[0]&&c&&"text"===c[0]?(c[1]+=b[1],c[3]=b[3]):(d.push(b),c=b));return d}function k(a){for(var b,c,d=[],e=d,f=[],g=0,h=a.length;h>g;++g)switch(b=a[g],b[0]){case"#":case"^":e.push(b),f.push(b),e=b[4]=[];break;case"/":c=f.pop(),c[5]=b[2],e=f.length>0?f[f.length-1][4]:d;break;default:e.push(b)}return d}function l(a){this.string=a,this.tail=a,this.pos=0}function m(a,b){this.view=a,this.cache={".":this.view},this.parent=b}function n(){this.cache={}}var o=Object.prototype.toString,p=Array.isArray||function(a){return"[object Array]"===o.call(a)},q=RegExp.prototype.test,r=/\S/,s={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},t=/\s*/,u=/\s+/,v=/\s*=/,w=/\s*\}/,x=/#|\^|\/|>|\{|&|=|!/;l.prototype.eos=function(){return""===this.tail},l.prototype.scan=function(a){var b=this.tail.match(a);if(!b||0!==b.index)return"";var c=b[0];return this.tail=this.tail.substring(c.length),this.pos+=c.length,c},l.prototype.scanUntil=function(a){var b,c=this.tail.search(a);switch(c){case-1:b=this.tail,this.tail="";break;case 0:b="";break;default:b=this.tail.substring(0,c),this.tail=this.tail.substring(c)}return this.pos+=b.length,b},m.prototype.push=function(a){return new m(a,this)},m.prototype.lookup=function(a){var c,d=this.cache;if(d.hasOwnProperty(a))c=d[a];else{for(var f,g,h=this,i=!1;h;){if(a.indexOf(".")>0)for(c=h.view,f=a.split("."),g=0;null!=c&&gi;++i)g=void 0,e=a[i],f=e[0],"#"===f?g=this.renderSection(e,b,c,d):"^"===f?g=this.renderInverted(e,b,c,d):">"===f?g=this.renderPartial(e,b,c,d):"&"===f?g=this.unescapedValue(e,b):"name"===f?g=this.escapedValue(e,b):"text"===f&&(g=this.rawValue(e)),void 0!==g&&(h+=g);return h},n.prototype.renderSection=function(a,c,d,e){function f(a){return g.render(a,c,d)}var g=this,h="",i=c.lookup(a[1]);if(i){if(p(i))for(var j=0,k=i.length;k>j;++j)h+=this.renderTokens(a[4],c.push(i[j]),d,e);else if("object"==typeof i||"string"==typeof i||"number"==typeof i)h+=this.renderTokens(a[4],c.push(i),d,e);else if(b(i)){if("string"!=typeof e)throw new Error("Cannot use higher-order sections without the original template");i=i.call(c.view,e.slice(a[3],a[5]),f),null!=i&&(h+=i)}else h+=this.renderTokens(a[4],c,d,e);return h}},n.prototype.renderInverted=function(a,b,c,d){var e=b.lookup(a[1]);return!e||p(e)&&0===e.length?this.renderTokens(a[4],b,c,d):void 0},n.prototype.renderPartial=function(a,c,d){if(d){var e=b(d)?d(a[1]):d[a[1]];return null!=e?this.renderTokens(this.parse(e),c,d,e):void 0}},n.prototype.unescapedValue=function(a,b){var c=b.lookup(a[1]);return null!=c?c:void 0},n.prototype.escapedValue=function(b,c){var d=c.lookup(b[1]);return null!=d?a.escape(d):void 0},n.prototype.rawValue=function(a){return a[1]},a.name="mustache.js",a.version="2.1.3",a.tags=["{{","}}"];var y=new n;a.clearCache=function(){return y.clearCache()},a.parse=function(a,b){return y.parse(a,b)},a.render=function(a,b,d){if("string"!=typeof a)throw new TypeError('Invalid template! Template should be a "string" but "'+c(a)+'" was given as the first argument for mustache#render(template, view, partials)');return y.render(a,b,d)},a.to_html=function(c,d,e,f){var g=a.render(c,d,e);return b(f)?void f(g):g},a.escape=h,a.Scanner=l,a.Context=m,a.Writer=n}),function(a){function b(a,b,c,d){a.on(b,function(a){return i.push(a),c.apply(null,d)}),"complete"===document.readyState&&"ready"===b&&c.apply(null,d)}function c(b){var c=a(b);c.is('input[type="checkbox"]')&&c.on("change",function(){c.is(":checked")?c.trigger("check"):c.trigger("uncheck")}),c.is('input[type="radio"]')&&c.on("change",function(){var b=c.attr("name");a('input[type="radio"][name="'+b+'"]').each(function(b,c){var d=a(c);d.is(":checked")?d.trigger("check"):d.trigger("uncheck")})})}function d(a,b){for(var c=/^(([\w]+):)?([\w]+)\.([\w]+)(\((.*)\))?$/,d=a.split(";"),e=[],f=0;f0)for(var j=h[6].match(/(['][^']+['])|([\w-]+)|(["][^"]+["])/g),k=0;k=c&&g.services.hasOwnProperty(i)){PlentyFramework.prototype.hasOwnProperty(i)||e(g.services[i],2,d),f.push(PlentyFramework.prototype[i]);continue}if(1>=c&&g.directives.hasOwnProperty(i)){PlentyFramework.directives.hasOwnProperty(i)||e(g.directives[i],1,d),f.push(PlentyFramework.directives[i]);continue}console.error('Cannot inject dependency "'+i+'": Object not found.')}else console.error("Cyclic dependency injection: "+d.join(" -> ")+" -> "+i)}3==c?PlentyFramework.factories[b.name]=b.setup.apply(null,f):2==c?PlentyFramework.prototype[b.name]=b.setup.apply(null,f):1==c&&(PlentyFramework.directives[b.name]=b.setup.apply(null,f))}var f="1.0.11",g={factories:{},services:{},directives:{}};PlentyFramework=function(){};var h=null;PlentyFramework.getInstance=function(){return h=h||new PlentyFramework},PlentyFramework.version=function(){function a(a){for(var b=f.split("."),c=a.split("."),d=0;dparseInt(c[d]))return 1}return 0}return{get:function(){return f},equals:function(b){return 0==a(b)},compare:a}}(),PlentyFramework.partials={},PlentyFramework.globals={},PlentyFramework.setGlobal=function(a,b){return PlentyFramework.globals.hasOwnProperty(a)?(console.error('Global variable "'+a+'" already exists and cannot be overridden.'),null):(PlentyFramework.globals[a]=b,PlentyFramework.globals[a])},PlentyFramework.getGlobal=function(a,b){return PlentyFramework.globals.hasOwnProperty(a)?PlentyFramework.globals[a]:b},PlentyFramework.directives={},PlentyFramework.directive=function(a,b,c){return"string"!=typeof a?void console.error("Type mismatch: Expect first parameter to be a 'string', '"+typeof a+"' given."):"function"!=typeof b?void console.error("Type mismatch: Expect second parameter to be a 'function', '"+typeof b+"' given."):(c=c||[],void(g.directives[a]={name:a,dependencies:c,setup:b}))},PlentyFramework.prototype.bindDirectives=function(e){e=e||"html",a(e).find("[data-plenty]").each(function(e,f){var g=d(a(f).attr("data-plenty"),a(f));if(!(g.length<=0)){c(f);for(var e=0;e=0;c--)if(a==i[c].type)return i[c];return null},PlentyFramework.pushEvent=function(a){i.push(a)},PlentyFramework.service=function(a,b,c){return"string"!=typeof a?void console.error("Type mismatch: Expect first parameter to be a 'string', '"+typeof a+"' given."):"function"!=typeof b?void console.error("Type mismatch: Expect second parameter to be a 'function', '"+typeof b+"' given."):(c=c||[],void(g.services[a]={name:a,dependencies:c,setup:b}))},PlentyFramework.factories={},PlentyFramework.factory=function(a,b,c){return"string"!=typeof a?void console.error("Type mismatch: Expect first parameter to be a 'string', '"+typeof a+"' given."):"function"!=typeof b?void console.error("Type mismatch: Expect second parameter to be a 'function', '"+typeof b+"' given."):(c=c||[],void(g.factories[a]={name:a,dependencies:c,setup:b}))},PlentyFramework.compileTemplate=function(a,b){return b=b||{},b.translate=function(){return function(a,b){return b(PlentyFramework.translate(a))}},Mustache.render(TemplateCache[a],b)},PlentyFramework.scriptPath="",PlentyFramework.Strings={},PlentyFramework.loadLanguageFile=function(b){a.ajax({url:PlentyFramework.scriptPath+b,dataType:"json"}).done(function(a){PlentyFramework.Strings=a})},PlentyFramework.translate=function(a,b){var c;return PlentyFramework.Strings.hasOwnProperty(a)?c=PlentyFramework.Strings[a]:(c=a,console.warn('No translation found for "'+c+'".')),b&&(c=Mustache.render(c,b)),c},PlentyFramework.compile=function(){for(var a in g.factories)PlentyFramework.factories.hasOwnProperty(a)||e(g.factories[a],3);for(var b in g.services)PlentyFramework.prototype.hasOwnProperty(b)||e(g.services[b],2);for(var c in g.directives)PlentyFramework.directives.hasOwnProperty(c)||e(g.directives[c],1);for(var d=document.getElementsByTagName("SCRIPT"),f=d.length-1;f>=0;f--){var h=d[f].src.match(/(.*)\/(.*)\.js(\?\S*)?$/);if(h){PlentyFramework.scriptPath=h[1];break}}}}(jQuery),function(a,b){b.directive("Authentication",function(c){function d(d){b.getRecentEvent().preventDefault(),c.customerLogin(a(d))}return{login:d}},["AuthenticationService"])}(jQuery,PlentyFramework),function(a,b){b.directive("Basket",function(c){function d(d){b.getRecentEvent().preventDefault();var e={},f=a(d),g=f.parents("form");e.BasketItemItemID=g.find('[name="ArticleID"]').val(),e.BasketItemPriceID=g.find('[name="SYS_P_ID"]').val(),e.BasketItemQuantity=g.find('[name="ArticleQuantity"]').val(),e.BasketItemBranchID=g.find('[name="source_category"]').val(),g.find('[name="P_ID"]')&&(e.BasketItemPriceID=g.find('[name="P_ID"]:checked').val());var h=g.find('[name^="ArticleAttribute"]'),i=[];a.each(h,function(b,c){var d=c.name.match(/^ArticleAttribute\[\d+]\[\d+]\[(\d+)]$/);d&&d[1]&&i.push({BasketItemAttributeID:d[1],BasketItemAttributeValueID:a(c).val()})}),0!=i.length&&(e.BasketItemAttributesList=i),c.addItem([e])}function e(b,c){var d=a(b),e=d.parent().find("input"),f=parseInt(e.attr("maxlength"))||5,g=parseInt(e.val())+c,h=d.parents("[data-basket-item-id]").length>0;if(h){(g+"").length<=f&&g>=0&&e.val(g);var i=d.data("timeout");i&&window.clearTimeout(i),i=window.setTimeout(function(){e.trigger("change")},1e3),d.data("timeout",i)}else(g+"").length<=f&&g>=1&&e.val(g)}function f(b,d){c.setItemQuantity(b,parseInt(a(d).val())).fail(function(){var e=c.getItem(b);a(d).val(e.BasketItemQuantity)})}return{addBasketItem:d,changeItemQuantity:e,setItemQuantity:f}},["BasketService"])}(jQuery,PlentyFramework),function(a,b){b.directive("Checkout",function(a){function b(b){a.setMethodOfPayment(b)}function c(b){a.confirmAtrigaPaymax(b)}return{setMethodOfPayment:b,confirmAtrigaPaymax:c}},["CheckoutService"])}(jQuery,PlentyFramework),function(a,b){b.directive("MobileDropdown",function(c){function d(){a(window).on("orientationchange sizeChange",function(){a("input").is(":focus")||(e(k),e(l))})}function e(b,c){for(var d,e=0;e0?window.location.assign(a(c).attr("href")):window.location.assign(c))}function e(a){c.goToID(a)}return{to:d,toCheckoutTab:e}},["MediaSizeService","NavigatorService"])}(jQuery,PlentyFramework),function(a,b){b.directive("Tab",function(c){function d(b){a(b).tab("show")}function e(a,b,c){j[c]||(j[c]=new h),j[c].getTab(b)||j[c].addTab(b),j[c].getTab(b).addLabel(a)}function f(a,b,c){j[c]||(j[c]=new h),j[c].getTab(b)||j[c].addTab(b),j[c].getTab(b).setContent(a)}function g(a,d,e){c.isInterval(e)&&(b.getRecentEvent().preventDefault(),j[d]&&j[d].getTab(a)&&j[d].showTab(a))}function h(){function b(a){return g[a]=new i(a),g[a]}function c(b){var c=0;if(f)c=parseInt(f.getContent().parent().css("zIndex")),f.hide(),f.getContent().parent().css("zIndex",c-1);else{for(var d in g)if(g[d].getContent()){var h=parseInt(g[d].getContent().parent().css("zIndex"));(0==c||c>h)&&(c=h),g[d].hide()}for(var d in g)g[d].getContent()&&g[d].getContent().parent().css("zIndex",c-1);a(window).on("sizeChange",e)}f=g[b],f.getContent().parent().css("zIndex",c),f.show()}function d(a){return g[a]}function e(){for(var a in g)g[a].getContent()&&g[a].show();f=null}var f,g={};return{addTab:b,showTab:c,getTab:d,resetTabs:e}}function i(a){function b(){return j}function c(a){return i.push(a),this}function d(a){return h=a,this}function e(){return h}function f(){for(var a=0;a0&&(a(document).scrollTop()>100?x(z,"addClass","visible"):x(z,"removeClass","visible"))})}function g(){e.showWaitscreen()}function h(a){e.hideWaitscreen(a)}function i(b){a(b).owlCarousel({navigation:!0,navigationText:!1,slideSpeed:1e3,paginationSpeed:1e3,singleItem:!0,autoPlay:6e3,stopOnHover:!0,afterMove:function(b){a(b).find('[data-plenty-rel="lazyload"]').trigger("appear")}})}function j(b,d,e){var f=a(b),g=0,h={},i=f.find('[data-plenty-rel="equal-target"]').length>0?f.find('[data-plenty-rel="equal-target"]'):f.children();e!==!0&&y.push(b);for(var j=i.length;j>=0;j--)h=a(i[j]),h.css("height",""),h.outerHeight(!0)>g&&(g=h.outerHeight(!0));(!d||c.isInterval(d))&&i.height(g)}function k(b){var c=a(b);c.click(function(){return a("html, body").animate({scrollTop:0},400),!1}),a.inArray(c,z)&&z.push(c)}function l(b,c){var d=a(b);d.lazyload({effect:c}),d.is("img")&&d.on("loaded",function(){d.css("display","inline-block")})}function m(b){console.log(b);var c=a(b),d=c.parent();d.addClass("animating"),c.siblings("ul").slideToggle(200,function(){d.is(".open")?d.removeClass("open"):d.addClass("open"),c.siblings("ul").removeAttr("style"),d.removeClass("animating")})}function n(b,c){var d=a(b),e=a(d.attr("data-plenty-rel"));if(d.is('input[type="radio"]')){var f=a('input[type="radio"][name="'+d.attr("name")+'"]'),g=!c||"checked"==c;f.change(function(){var b=a(this);e.parents('[data-plenty-rel="equal-target"]').css("height","auto"),b.is(":checked")&&b[0]===d[0]&&1==g?e.slideDown(400,function(){w()}):e.slideUp(400,function(){w()})})}else d.click(function(){d.addClass("animating"),e.slideToggle(400,function(){d.removeClass("animating"),d.toggleClass("active"),w()})})}function o(b,c){r(a(b),c,"slideDown")}function p(b,c){r(a(b),c,"slideUp")}function q(b,c){r(a(b),c,"slideToggle")}function r(a,b,c){b=b||400,a.parents('[data-plenty-rel="equal-target"]').css("height","auto"),a[c](b,function(){w()})}function s(b,c){var e=a(b),f=e.find('[data-plenty-rel="social-switch"]');e.append(''),f.is("off, on")||f.addClass("off"),f.on("click",function(){f.hasClass("off")&&("tooltip"==e.attr("data-toggle")&&e.tooltip("destroy"),f.removeClass("off").addClass("on"),e.find('[data-plenty-rel="social-placeholder"]').hide(),e.find(".social-container").append(d.getSocialService(c)))})}function t(d,e,f){var g=a(e);if(g.parents(".navbar-main").length>0){var h=g.children("span");return b.directives.MobileDropdown.slideDropdown(h),!0}if(e&&d&&(!f||c.isInterval(f))){var i=b.getRecentEvent();return i&&i.preventDefault(),g.toggleClass(d),!1}}function u(d,e,f){if(e&&d&&(!f||c.isInterval(f))){var g=b.getRecentEvent();return g&&g.preventDefault(),a(e).addClass(d),!1}}function v(d,e,f){if(e&&d&&(!f||c.isInterval(f))){var g=b.getRecentEvent();return g&&g.preventDefault(),a(e).removeClass(d),!1}}function w(){for(var a=y.length-1;a>=0;a--)j(y[a],"",!0)}function x(a,b,c){for(var d=a.length-1;d>=0;d--)a[d][b](c)}var y=[],z=[];return{initUIWindowEvents:f,showWaitscreen:g,hideWaitscreen:h,addContentPageSlider:i,equalHeight:j,initToTop:k,initLazyload:l,initSlideToggle:n,slideDown:o,slideUp:p,slideToggle:q,toggleHideShow:m,toggleSocialShare:s,toggleClass:t,addClass:u,removeClass:v}},["MediaSizeService","SocialShareService","UIFactory"])}(jQuery,PlentyFramework),function(a,b){b.directive("Validator",function(a){function b(b,c){return a.validate(b,c)}return{validate:b}},["ValidationService"])}(jQuery,PlentyFramework),function(a,b){b.factory("APIFactory",function(c,d){function e(){b.getGlobal("LoginSession")&&(l&&clearTimeout(l),l=setTimeout(function(){a(window).trigger("login-expired"),"Checkout"===b.getGlobal("PageDesign")&&d.prepare().setTitle(b.translate("Your session has expired.")).setContent(b.translate("Please log in again to continue shopping.")).setLabelDismiss(null).setLabelConfirm(b.translate("OK")).onConfirm(function(){window.location.assign("/")}).onDismiss(function(){window.location.assign("/")}).show()},b.getGlobal("LoginSessionExpiration")))}function f(b){try{var d=a.parseJSON(b.responseText);c.printErrors(d.error.error_stack)}catch(e){c.throwError(b.status,b.statusText)}}function g(b,d,g,h,i){return h||c.showWaitScreen(),a.ajax(b,{type:"GET",data:d,dataType:"json",async:!i,error:function(a){g||f(a)}}).always(function(){h||c.hideWaitScreen(),e()})}function h(b,d,g,h){var i={type:"POST",dataType:"json",error:function(a){g||f(a)}};return d&&d.isFile?(i.cache=d.cache,i.processData=d.processData,i.data=d.data,i.contentType=!1):(i.data=JSON.stringify(d),i.contentType="application/json"),h||c.showWaitScreen(),a.ajax(b,i).always(function(){h||c.hideWaitScreen(),e()})}function i(b,d,g,h){return h||c.showWaitScreen(),a.ajax(b,{type:"PUT",data:JSON.stringify(d),dataType:"json",contentType:"application/json",error:function(a){g||f(a)}}).always(function(){h||c.hideWaitScreen(),e()})}function j(b,d,g,h){return h||c.showWaitScreen(),a.ajax(b,{type:"DELETE",data:JSON.stringify(d),dataType:"json",contentType:"application/json",error:function(a){g||f(a)}}).always(function(){h||c.hideWaitScreen(),e()})}function k(){return a.Deferred().resolve()}var l=null;return a(document).ready(function(){e()}),{get:g,post:h,put:i,"delete":j,idle:k}},["UIFactory","ModalFactory"])}(jQuery,PlentyFramework),function(a){a.factory("CMSFactory",function(a){function b(b,c){function d(d){return a.get("/rest/"+d.toLowerCase()+"/container_"+b.toLowerCase()+"/",c)}return{from:d}}function c(b,c){function d(d){return a.get("/rest/"+d.toLowerCase()+"/"+b.toLowerCase()+"/",c)}return{from:d}}function d(b){return a.get("/rest/categoryview/categorycontentbody/?categoryID="+b)}return{getContainer:b,getParams:c,getCategoryContent:d}},["APIFactory"])}(PlentyFramework),function(a){a.factory("CheckoutFactory",function(b,c,d){function e(){return l}function f(a){return m&&l||g(!0),a?$.extend(!0,{},l):m}function g(a){return b.get("/rest/checkout/",null,!1,!1,a).done(function(a){a?(l=a.data,m=new e):d.throwError(0,'Could not receive checkout data [GET "/rest/checkout/" receives null value]')})}function h(){return b.put("/rest/checkout",m).done(function(a){a?(l=a.data,m=new e):d.throwError(0,'Could not receive checkout data [GET "/rest/checkout/" receives null value]')})}function i(b){return c.getContainer("checkout"+b).from("checkout").done(function(c){$('[data-plenty-checkout-template="'+b+'"]').each(function(b,d){$(d).html(c.data[0]),a.getInstance().bindDirectives(d),$(window).trigger("contentChanged")})})}function j(b){return c.getCategoryContent(b).done(function(c){$('[data-plenty-checkout-catcontent="'+b+'"]').each(function(b,d){$(d).html(c.data[0]),a.getInstance().bindDirectives(d),$(window).trigger("contentChanged")})})}function k(b){return c.getContainer("itemview"+b).from("itemview").done(function(c){$('[data-plenty-itemview-template="'+b+'"]').each(function(b,d){$(d).html(c.data[0]),a.getInstance().bindDirectives(d),$(window).trigger("contentChanged")})})}var l,m;return{getCheckout:f,setCheckout:h,loadCheckout:g,reloadContainer:i,reloadCatContent:j,reloadItemContainer:k}},["APIFactory","CMSFactory","UIFactory"])}(PlentyFramework),function(a,b){b.factory("ModalFactory",function(){function c(a){return PlentyFramework.partials.Modal.isModal(a)}function d(a){return new e(a)}function e(d){function e(a){return t.title=a,this}function f(a){return t.cssClass=a,this}function g(a){return t.content=a,this}function h(a){return t.labelConfirm=a,this}function i(a){return t.labelDismiss=a,this}function j(a){return t.onConfirm=a,this}function k(a){return t.onDismiss=a,this}function l(a){return t.container=a,this}function m(a){return t.timeout=a,this}function n(){if(t.selector)u=a(t.selector);else{u=c(t.content)?PlentyFramework.partials.Modal.getModal(t.content):a(PlentyFramework.compileTemplate("modal/modal.html",t)),a(t.container).append(u);var b=a(t.content).filter("script");b.length>0&&b.each(function(b,c){var d=document.createElement("script");d.type="text/javascript",d.innerHTML=a(c).text(),a(t.container).append(d)})}PlentyFramework.partials.Modal.init(u,t),u.find('[data-plenty-modal="confirm"]').click(function(){var a=t.onConfirm();"undefined"==typeof a&&(a=!0),a&&o(!0)}),PlentyFramework.partials.Modal.show(u),t.timeout>0&&p()}function o(a){PlentyFramework.partials.Modal.hide(u),a||t.onDismiss()}function p(){x=t.timeout,y=(new Date).getTime(),v=window.setTimeout(function(){window.clearInterval(w),o()},t.timeout),u.find('[data-plenty-modal="timer"]').text(x/1e3),w=window.setInterval(function(){if(!z){var a=x-(new Date).getTime()+y;a=Math.round(a/1e3),u.find('[data-plenty-modal="timer"]').text(a)}},1e3)}function q(){z=!0,x-=(new Date).getTime()-y,window.clearTimeout(v)}function r(){z=!1,y=(new Date).getTime(),v=window.setTimeout(function(){o(),window.clearInterval(w)},x)}function s(){window.clearTimeout(v),window.clearInterval(w)}var t=this;t.selector=d,t.title="",t.cssClass="",t.content="",t.labelDismiss=b.translate("Cancel"),t.labelConfirm=b.translate("Confirm"),t.onConfirm=function(){},t.onDismiss=function(){},t.container="body",t.timeout=-1,t.hide=o,t.startTimeout=p,t.stopTimeout=s,t.pauseTimeout=q,t.continueTimeout=r;var u,v,w,x,y,z=!1;return{setTitle:e,setClass:f,setContent:g,setContainer:l,setLabelConfirm:h,setLabelDismiss:i,onConfirm:j,onDismiss:k,setTimeout:m,show:n,hide:o}}return{prepare:d,isModal:c}})}(jQuery,PlentyFramework),function(a,b){b.factory("UIFactory",function(){function c(a,b){d([{code:a,message:b}])}function d(c){(!i||a("body").has(i).length<=0)&&(i=a(b.compileTemplate("error/errorPopup.html")),a("body").append(i),b.partials.Error.init(i)),a.each(c,function(c,d){b.partials.Error.addError(i,a(b.compileTemplate("error/errorMessage.html",d)))}),b.partials.Error.show(i),f(!0)}function e(){return h=h||0,(!g||a("body").has(g).length<=0)&&(g=a(b.compileTemplate("waitscreen/waitscreen.html")),a("body").append(g)),b.partials.WaitScreen.show(g),h++,h}function f(a){return h--,(0>=h||a)&&(h=0,b.partials.WaitScreen.hide(g)),h}var g,h=0,i=null;return{throwError:c,printErrors:d,showWaitScreen:e,hideWaitScreen:f}})}(jQuery,PlentyFramework),Object.equals=function(a,b){if(a===b)return!0;if(!(a instanceof Object&&b instanceof Object))return!1;if(a.constructor!==b.constructor)return!1;for(var c in a)if(a.hasOwnProperty(c)){if(!b.hasOwnProperty(c))return!1;if(a[c]!==b[c]){if("object"!=typeof a[c])return!1;if(!Object.equals(a[c],b[c]))return!1}}for(var c in b)if(b.hasOwnProperty(c)&&!a.hasOwnProperty(c))return!1;return!0},PlentyFramework.cssClasses={active:"active"},function(a,b){b.partials.Error={init:function(c){a(c).find(".close").click(function(){b.partials.Error.hideAll()})},addError:function(b,c){var d=a(c).attr("data-plenty-error-code");a(b).find('[data-plenty-error-code="'+d+'"]').length<=0&&a(b).find(".plentyErrorBoxInner").append(c)},show:function(b){a(b).show()},hideAll:function(){a("#CheckoutErrorPane").hide(),a("#CheckoutErrorPane").find(".plentyErrorBoxInner").html("")}}}(jQuery,PlentyFramework),function(a,b){b.partials.Modal={init:function(a,b){a.on("hidden.bs.modal",function(){b.hide(),b.selector||a.remove()}),b.timeout>0&&(a.on("hide.bs.modal",b.stopTimeout),a.find(".modal-content").hover(function(){b.pauseTimeout()},function(){a.is(".in")&&b.continueTimeout()}))},show:function(a){a.modal("show")},hide:function(a){a.modal("hide")},isModal:function(b){return a(b).filter(".modal").length+a(b).find(".modal").length>0},getModal:function(b){var c=a(b);return c.length>1&&(c=a(b).filter(".modal")||a(b).find(".modal")),c}}}(jQuery,PlentyFramework),function(a){a(document).on("initPartials",function(b,c){a(c).find('[data-toggle="tooltip"]').tooltip({container:"body"})})}(jQuery),function(a,b){b.partials.WaitScreen={show:function(a){a.addClass("in")},hide:function(a){a.removeClass("in")}}}(jQuery,PlentyFramework),function(a,b){b.service("AddressDoctorService",function(c){function d(b){var c=!0;return b=b||"[data-plenty-address-doctor]",a(b).filter("[data-plenty-address-doctor]:visible").each(function(b,d){var f=new e(d),g=a(d).attr("data-plenty-address-doctor").replace(/\s/g,"").split(",");f.isValid(g)||(c=!1)}),c}function e(c){function d(a){return j()?!0:(k=new f(m.getFormValues()),l=a,e(),1==k.getAddresses().length)}function e(){a(".suggestion-list").remove();for(var b=!1,c=0;cc;c++){var d=a.data[c],f=e(d);f?f.HouseNo.push(d.HouseNo):(d.HouseNo=[d.HouseNo],j.push(d))}})}function e(a){for(var b=j.length,c=0;b>c;c++)if(a.Street==j[c].Street&&j.ZIP==j[c].ZIP&&a.City==j[c].City)return j[c];return null}function f(){return j}function g(b){for(var c=[],d=j.length,e=0;d>e;e++){var f=j[e];a.inArray(f[b],c)<0&&c.push(f[b])}return c}function h(a){for(var b=[],c=j.length,d=0;c>d;d++){var e=j[d];(a.Street&&a.Street==e.Street||a.ZIP&&a.ZIP==e.ZIP||a.City&&a.City==e.City)&&b.push(e)}j=b}function i(a){a=parseInt(a);for(var b=j.length,c=0;b>c;c++)for(var d=j[c],e=0;e=f[0]&&a<=f[1])return!0}return!1}var j=[];return d(),{getAddresses:f,getList:g,filter:h,houseNoAllowed:i}}return{validateAddress:d}},["APIFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("AuthenticationService",function(c,d,e){function f(){var b=a('[data-plenty-checkout="lostPasswordForm"]');if(b.validateForm()){var d=b.getFormValues(),e={Email:d.Email};return c.post("/rest/checkout/lostpassword/",e).done(function(b){1==b.data.IsMailSend&&(a('[data-plenty-checkout="lostPasswordTextContainer"]').hide(),a('[data-plenty-checkout="lostPasswordSuccessMessage"]').show())})}}function g(a){if(a.validateForm()){var b=a.getFormValues(),d={Email:b.loginMail,Password:b.loginPassword};return e.showWaitScreen(),c.post("/rest/checkout/login/",d).done(function(){window.location.assign(a.attr("action"))})}}function h(a){return c.post("/rest/checkout/customerinvoiceaddress/",a).done(function(a){d.getCheckout().CustomerInvoiceAddress=a.data})}function i(){var c=a('[data-plenty-checkout-form="customerRegistration"]');if(c.validateForm()&&b.getInstance().AddressDoctorService.validateAddress()){var d=c.getFormValues();if(d.LoginType=2,d.checkout&&d.checkout.customerInvoiceAddress&&d.checkout.customerInvoiceAddress.CustomerProperty){var e=d.checkout.customerInvoiceAddress.CustomerProperty;d.CustomerPropertiesList=d.CustomerPropertiesList||[];for(var f in e)e[f]&&d.CustomerPropertiesList.push({PropertyID:f,PropertyValue:e[f]})}return h(d).done(function(){window.location.assign(c.attr("action"))})}}return{resetPassword:f,customerLogin:g,setInvoiceAddress:h,registerCustomer:i}},["APIFactory","CheckoutFactory","UIFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("BasketService",function(c,d,e,f,g){function h(d){d&&c.get("/rest/checkout/container_"+"CheckoutOrderParamsList".toLowerCase()+"/",{itemID:d[0].BasketItemItemID,quantity:d[0].BasketItemQuantity},!1,!0).done(function(c){c.data[0].indexOf("form-group")>0?g.prepare().setContent(c.data[0]).setTitle(b.translate("Select order parameters")).setLabelConfirm(b.translate("Save")).onConfirm(function(){return a('[data-plenty-checkout-form="OrderParamsForm"]').validateForm()?(j(i(d)),!0):!1}).show():j(d)})}function i(b){var c,d=a('[data-plenty-checkout-form="OrderParamsForm"]'),e={},f="";return d.find('[name^="ParamGroup"]').each(function(){c=this.name.match(/^ParamGroup\[(\d+)]\[(\d+)]$/),b=m(b,c[1],a(this).val(),a(this).val())}),d.find('[name^="ParamValue"]').each(function(){if(e=a(this),f=e.attr("type"),("checkbox"==f&&e.is(":checked")||"radio"==f&&e.is(":checked")||"radio"!=f&&"checkbox"!=f)&&"file"!=f&&"hidden"!=f){var c=e[0].name.match(/^ParamValue\[(\d+)]\[(\d+)]$/);b=m(b,c[1],c[2],e.val())}else if("file"==f)if(e[0].files&&e[0].files.length>0)b=l(e,b);else{var c=e[0].name.match(/^ParamValueFile\[(\d+)]\[(\d+)]$/),d=a('input[type="hidden"][name="ParamValue['+c[1]+"]["+c[2]+']"]').val();b=m(b,c[1],c[2],d)}}),b}function j(h){c.post("/rest/checkout/basketitemslist/",h,!0).done(function(){f.loadCheckout().done(function(){var c=a("[name^=ArticleAttribute]"),d=a("[name^=P_ID]:checked"),f={ArticleID:h[0].BasketItemItemID};c.val()>0?c.each(function(b,c){c=a(c),f[c.attr("name")]=c.val()}):d&&d.val()>0&&(f.UnitCombinationId=d.val()),s(),e.getContainer("ItemViewItemToBasketConfirmationOverlay",f).from("ItemView").done(function(a){var c=b.getGlobal("TimeoutItemToBasketOverlay",5e3),d=g.prepare().setContent(a.data[0]);c>0&&d.setTimeout(c),d.show()})})}).fail(function(a){d.printErrors(JSON.parse(a.responseText).error.error_stack)})}function k(a){c.put("/rest/checkout/basketitemslist/",a).done(function(){f.reloadCatContent(b.getGlobal("basketCatID")),f.loadCheckout().done(function(){s()})})}function l(a,b){var d,e,f=a[0].id,g={},h=[],i={type:"POST",data:{},isFile:!0,cache:!1,dataType:"json",processData:!1,contentType:!1};g[f]=a[0].files,-1==h.indexOf(f)&&h.push(f);for(var j=0,k=h.length;k>j;++j)d=new FormData,e=g[h[j]],d.append("0",e[0],e[0].name),i.data=d,c.post("/rest/checkout/orderparamfile/",i);var l=a[0].name.match(/^ParamValueFile\[(\d+)]\[(\d+)]$/);return m(b,l[1],l[2],g[f][0].name)}function m(b,c,d,e){return c>0&&void 0==b[c]&&(b[c]=a.extend(!0,{},b[0]),b[c].BasketItemOrderParamsList=[]),void 0!=b[c]&&(b[c].BasketItemQuantity=1,void 0==b[c].BasketItemOrderParamsList&&(b[c].BasketItemOrderParamsList=[]),e&&b[c].BasketItemOrderParamsList.push({BasketItemOrderParamID:d,BasketItemOrderParamValue:e})),b}function n(b){var c=a('[data-plenty-basket-item="'+b+'"]');c.modal("show"),c.find('[data-plenty-modal="confirm"]').on("click",function(){var d=p(b),e=[];c.find('select, .PlentyFormContainer.AttrImage > input[type="hidden"]').each(function(b,c){var d=c.name.match(/^ArticleAttribute\[\d+]\[\d+]\[(\d+)]$/);d&&d[1]&&e.push({BasketItemAttributeID:d[1],BasketItemAttributeValueID:a(c).val()})}),0!=e.length&&(d.BasketItemAttributesList=e),k([d])})}function o(d){var e=p(d);e.BasketItemOrderParamsList=[],c.get("/rest/checkout/container_"+"CheckoutOrderParamsList".toLowerCase()+"/",{itemID:e.BasketItemItemID,quantity:e.BasketItemQuantity,basketItemID:d}).done(function(c){g.prepare().setContent(c.data[0]).setTitle(b.translate("Edit order parameters")).setLabelConfirm(b.translate("Save")).onConfirm(function(){return a('[data-plenty-checkout-form="OrderParamsForm"]').validateForm()?(k(i([e])),!0):!1}).show()})}function p(a){for(var b=f.getCheckout().BasketItemsList,c=0;c=0?c.get("/rest/checkout/container_checkoutbasketitemslist/").done(function(c){var d=a("[data-basket-item-id]").parents("ul"),e=d.parents(".panel-body");d.fadeOut(function(){a(this).siblings(":not('[data-plenty-checkout-template]')").remove(),a(this).remove(),e.prepend(a(c.data[0])).hide().fadeIn(function(){b.getInstance().bindDirectives(e)})})}):f.reloadContainer("BasketItemsList"),f.reloadContainer("Totals")),s(),i.resolve()})})}var i=a.Deferred(),j=p(d).BasketItemNameMap[1];return e?h():g.prepare().setTitle(b.translate("Please confirm")).setContent("

"+b.translate('Do you really want to remove "{{item}}" from your basket?',{item:j})+"

").onDismiss(function(){i.reject()}).onConfirm(function(){h()}).setLabelConfirm(b.translate("Delete")).show(),i}function r(d,e){if(0>=e)return q(d);for(var g,h,i=a.Deferred(),j=f.getCheckout().BasketItemsList,k=0;k0&&f.reloadContainer("Totals")}return{addItem:h,removeItem:q,getItem:p,setItemQuantity:r,editItemAttributes:n,editOrderParams:o,addCoupon:t,removeCoupon:u}},["APIFactory","UIFactory","CMSFactory","CheckoutFactory","ModalFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("CheckoutService",function(c,d,e,f,g){function h(){f.loadCheckout(!0)}function i(){var b=a('[data-plenty-checkout-form="details"]'),d=b.getFormValues();return f.getCheckout().CheckoutCustomerSign||(f.getCheckout().CheckoutCustomerSign=""),f.getCheckout().CheckoutOrderInfoText||(f.getCheckout().CheckoutOrderInfoText=""),f.getCheckout().CheckoutCustomerSign!==d.CustomerSign&&a(b).find('[name="CustomerSign"]').length>0||f.getCheckout().CheckoutOrderInfoText!==d.OrderInfoText&&a(b).find('[name="OrderInfoText"]').length>0?(f.getCheckout().CheckoutCustomerSign=d.CustomerSign,f.getCheckout().CheckoutOrderInfoText=d.OrderInfoText,f.setCheckout()):c.idle()}function j(d){var e=a('[data-plenty-checkout-form="shippingAddress"]');if(!d&&!e.validateForm())return!1;if(!d&&!b.getInstance().AddressDoctorService.validateAddress(e))return!1;var g=e.getFormValues(),h=a('[name="shippingAddressID"]:checked').val();if(0>h){var i=g;return m(i,f.getCheckout().CustomerShippingAddress)?c.idle():("PACKSTATION"==i.Street?(i.IsPackstation=1,i.PackstationNo=i.HouseNo):"POSTFILIALE"==i.Street&&(i.IsPostfiliale=1,i.PostfilialNo=i.HouseNo),c.post("/rest/checkout/customershippingaddress/",i).done(function(a){f.getCheckout().CheckoutCustomerShippingAddressID=a.data.ID,f.getCheckout().CheckoutShippingCountryID=a.data.CountryID,k()}))}return h==f.getCheckout().CheckoutCustomerShippingAddressID?c.idle():(f.getCheckout().CheckoutCustomerShippingAddressID=h,void k())}function k(){return delete f.getCheckout().CheckoutMethodOfPaymentID,delete f.getCheckout().CheckoutShippingProfileID,f.setCheckout().done(function(){f.reloadContainer("MethodsOfPaymentList"),f.reloadContainer("ShippingProfilesList"),2==f.getCheckout().CustomerInvoiceAddress.LoginType&&f.reloadContainer("CustomerShippingAddress"),a("#shippingAdressSelect").modal("hide"),a(".modal-backdrop")&&a(".modal-backdrop").remove()})}function l(){var b=a('[data-plenty-checkout-form="guestRegistration"]'),d=b.getFormValues();if(d.LoginType=1,d.checkout&&d.checkout.customerInvoiceAddress&&d.checkout.customerInvoiceAddress.CustomerProperty){var e=d.checkout.customerInvoiceAddress.CustomerProperty;d.CustomerPropertiesList=d.CustomerPropertiesList||[];for(var g in e)e[g]&&d.CustomerPropertiesList.push({PropertyID:g,PropertyValue:e[g]})}return m(d,f.getCheckout().CustomerInvoiceAddress)?j():c.post("/rest/checkout/customerinvoiceaddress/",d).done(function(a){j().done(f.loadCheckout)})}function m(a,b){for(var c in a)if(a[c]+""!=b[c]+""&&"EmailRepeat"!==c)return!1;return!0}function n(){var b=a('[data-plenty-checkout-form="shippingProfileSelect"]').getFormValues();return f.getCheckout().CheckoutShippingProfileID=b.ShippingProfileID,delete f.getCheckout().CheckoutCustomerShippingAddressID,delete f.getCheckout().CheckoutMethodOfPaymentID,f.setCheckout().done(function(){f.reloadContainer("MethodsOfPaymentList")})}function o(){var b=f.getCheckout().CheckoutMethodOfPaymentID,e=a('input[type="radio"][name="MethodOfPaymentID"][value="'+b+'"]').parent().getFormValues();return c.post("/rest/checkout/preparepayment/",e,!0).done(function(b){if(""!=b.data.CheckoutMethodOfPaymentRedirectURL)document.location.assign(b.data.CheckoutMethodOfPaymentRedirectURL);else if(b.data.CheckoutMethodOfPaymentAdditionalContent){var c=a(b.data.CheckoutMethodOfPaymentAdditionalContent).find('[data-plenty-checkout-form="bankDetails"]').length>0;g.prepare().setContent(b.data.CheckoutMethodOfPaymentAdditionalContent).onConfirm(function(){return c?s():u()}).show()}}).fail(function(b){try{for(var c=a.parseJSON(b.responseText),e=[],g=0;g0&&d.printErrors(e)}catch(h){d.throwError(b.status,b.statusText)}})}function p(c){return c||(c=a('input[name="MethodOfPaymentID"]:checked').val()),f.getCheckout().CheckoutMethodOfPaymentID=c,b.getGlobal("Checkout.AtrigaRequireUserConfirmation")||(f.getCheckout().CheckoutAtrigapaymaxChecked=!0),delete f.getCheckout().CheckoutCustomerShippingAddressID,delete f.getCheckout().CheckoutShippingProfileID,f.setCheckout().done(function(){f.reloadContainer("ShippingProfilesList")})}function q(a){return f.getCheckout().CheckoutAtrigapaymaxChecked=!!a,c.put("/rest/checkout",{CheckoutAtrigapaymaxChecked:!!a})}function r(){e.getContainer("CheckoutPaymentInformationBankDetails").from("Checkout").done(function(b){g.prepare().setContent(b.data[0]).onDismiss(function(){a('input[name="MethodOfPaymentID"]').each(function(b,c){a(c).val()==f.getCheckout().CheckoutMethodOfPaymentID?a(c).attr("checked","checked"):a(c).removeAttr("checked")})}).onConfirm(function(){return s()}).show()})}function s(){var b=a('[data-plenty-checkout-form="bankDetails"]');if(b.validateForm()){var d=b.getFormValues().checkout.customerBankDetails,e={CustomerBankName:d.bankName,CustomerBLZ:d.blz,CustomerAccountNumber:d.accountNo,CustomerAccountOwner:d.accountOwner,CustomerIBAN:d.iban,CustomerBIC:d.bic};return c.post("/rest/checkout/paymentinformationbankdetails/",e).done(function(){f.loadCheckout().done(function(){p(3),f.reloadContainer("MethodsOfPaymentList")})}),!0}return!1}function t(){e.getContainer("CheckoutPaymentInformationCreditCard").from("Checkout").done(function(b){g.prepare().setContent(b.data[0]).onDismiss(function(){a('input[name="MethodOfPaymentID"]').each(function(b,c){a(c).val()==f.getCheckout().CheckoutMethodOfPaymentID?a(c).attr("checked","checked"):a(c).removeAttr("checked")})}).onConfirm(function(){return u()}).show()})}function u(){var b=a('[data-plenty-checkout-form="creditCard"]');if(b.validateForm()){var d=b.getFormValues().checkout.paymentInformationCC,e={Owner:d.owner,Cvv2:d.cvv2,Number:d.number,Year:d.year,Month:d.month,Provider:d.provider};return c.post("/rest/checkout/paymentinformationcreditcard/",e).done(function(){f.loadCheckout()}),!0}return!1}function v(b){if(2==f.getCheckout().CustomerInvoiceAddress.LoginType)var c=a('[data-plenty-checkout-form="shippingAddress"]').getFormValues();else var c=a('[data-plenty-checkout-form="guestRegistration"]').getFormValues();var d={street:c.Street,houseNo:c.HouseNo,ZIP:c.ZIP,city:c.City,postnummer:c.Postnummer,suggestionType:"postfinder"};e.getContainer("CheckoutAddressSuggestionResultsList",d).from("Checkout").done(function(a){g.prepare().setContent(a.data[0]).show()})}function w(){var b=a('[data-plenty-checkout-form="placeOrder"]');if(b.validateForm()){var d=b.getFormValues(),e={TermsAndConditionsCheck:d.termsAndConditionsCheck||0,WithdrawalCheck:d.withdrawalCheck||0,PrivacyPolicyCheck:d.privacyPolicyCheck||0,AgeRestrictionCheck:d.ageRestrictionCheck||0,NewsletterCheck:d.newsletterCheck||0,KlarnaTermsAndConditionsCheck:d.klarnaTermsAndConditionsCheck||0,PayoneDirectDebitMandateCheck:d.payoneDirectDebitMandateCheck||0,PayoneInvoiceCheck:d.payoneInvoiceCheck||0};return c.post("/rest/checkout/placeorder/",e).done(function(a){""!=a.data.MethodOfPaymentRedirectURL?window.location.assign(a.data.MethodOfPaymentRedirectURL):""!=a.data.MethodOfPaymentAdditionalContent?g.prepare().setContent(a.data.MethodOfPaymentAdditionalContent).setLabelDismiss("").onDismiss(function(){window.location.assign(b.attr("action"))}).onConfirm(function(){window.location.assign(b.attr("action"))}).show():window.location.assign(b.attr("action"))})}}return{init:h,setCustomerSignAndInfo:i,registerGuest:l,setShippingProfile:n,saveShippingAddress:j,loadAddressSuggestion:v,preparePayment:o,setMethodOfPayment:p,confirmAtrigaPaymax:q,editBankDetails:r,editCreditCard:t,placeOrder:w}},["APIFactory","UIFactory","CMSFactory","CheckoutFactory","ModalFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("FeedbackService",function(a){function b(){function b(a,b){return e.dateStart=a,e.dateEnd=b,this}function c(b,c,f){var g={ReferenceId:c,FromDate:e.dateStart,ToDate:e.dateEnd,FeedbackType:f||d().COMMENTS_AND_RATINGS};return a.get("/rest/feedback/"+b+"/",g)}var e={dateStart:null,dateEnd:null};return{between:b,"for":c}}function c(){function b(a){return f.Rating=a,this}function c(a){return f.Text=a,this}function d(a,b,c){return f.Author=a,b&&(f.Email=b),c&&(f.CustomerId=c),this}function e(b,c){return a.post("/rest/feedback/"+b+"/",f)}var f={Rating:1,Text:"",Author:"",Email:"",CustomerId:0};return{withRating:b,withComment:c,withAuthor:d,to:e}}function d(){return{COMMENTS_ONLY:"comments_only",RATINGS_ONLY:"ratings_only",COMMENTS_AND_RATINGS:"comments_with_ratings"}}function e(){return{ITEM:"item",CATEGORY:"category",BLOG:"blog"}}return{getFeedbacks:b,addFeedback:c,ArticleTypes:e(),FeedbackTypes:d()}},["APIFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("MediaSizeService",function(){function b(){return e&&c(),e}function c(){var b;if(b=window.matchMedia?window.matchMedia("(min-width:1200px)").matches?"lg":window.matchMedia("(min-width:992px)").matches?"md":window.matchMedia("(min-width:768px)").matches?"sm":"xs":a(window).width()>=1200?"lg":a(window).width()>=992?"md":a(window).width()>=768?"sm":"xs",b!=e||"xs"===b){var c=e;e=b,a(window).trigger("sizeChange",[e,c])}}function d(a){for(var b=a.replace(/\s/g,"").split(","),c=0;c li'),r=a('[data-plenty-checkout="container"] > div'),u=a('[data-plenty-checkout="next"]'),t=a('[data-plenty-checkout="prev"]'),q.length==r.length&&r.length>0){d.getCheckout();r.hide(),q.each(function(b,c){a(c).addClass("disabled"),a(c).click(function(){a(this).is(".disabled")||j(b)})}),u.attr("disabled","disabled"),u.click(function(){m()}),t.attr("disabled","disabled"),t.click(function(){n()}),window.addEventListener("hashchange",function(){window.location.hash.length>0?o(window.location.hash):j(0)},!1),a.urlParam=function(a){var b=new RegExp("[?&]"+a+"=([^&#]*)").exec(window.location.href);return null==b?null:b[1]||0};var c=a.urlParam("gototab");0==window.location.hash.length&&c&&a('[data-plenty-checkout-id="'+c+'"]').length>0?window.location.hash=c:j(!o(window.location.hash)&&s>=0?s:0),p(),a(window).on("sizeChange",p),a(window).resize(function(){"xs"==b.getInstance().MediaSizeService.interval()&&p()})}}function f(){return s>=0?{id:a(r[s]).attr("data-plenty-checkout-id"),index:s}:null}function g(a){return v.beforeChange.push(a),b.getInstance().NavigatorService}function h(a){return v.afterChange.push(a),b.getInstance().NavigatorService}function i(b,c){var d=!0;if(s>=0||"afterChange"===b){var e=f(),g={index:c,id:a(r[c]).attr("data-plenty-checkout-id")};a.each(v[b],function(a,b){return b(e,g)===!1?(d=!1,!1):void 0})}return d}function j(e,f){var g=s!==e;(!g||f||i("beforeChange",e))&&(s=e,!Object.equals(w[s],d.getCheckout(!0))&&g&&a(r[s]).attr("data-plenty-checkout-content")?(w[s]=d.getCheckout(!0),c.getCategoryContent(a(r[s]).attr("data-plenty-checkout-content")).done(function(c){a(r[s]).html(c.data[0]),k(g),b.getInstance().bindDirectives(r[s]),a(window).trigger("contentChanged")})):k(g))}function k(b){a(r).hide();var c;a(q).each(function(b,d){c=a(d),c.removeClass("disabled active"),c.find('[role="tab"]').attr("aria-selected","false"),s>b?c.addClass("visited"):b==s?(c.addClass("active visited"),c.find('[role="tab"]').attr("aria-selected","true")):b>s&&!c.is(".visited")&&c.addClass("disabled")}),p(),0>=s?t.attr("disabled","disabled"):t.removeAttr("disabled"),s+1==q.length?u.attr("disabled","disabled"):u.removeAttr("disabled"),a(r[s]).show(),s>0?window.location.hash=a(r[s]).attr("data-plenty-checkout-id"):window.location.hash.length>0&&(window.location.hash=""),b&&i("afterChange",s)}function l(a){j(a.index,!0)}function m(){s0&&j(s-1)}function o(b){return"next"==b?(m(),!0):"prev"==b?(n(),!0):(b=b.replace("#",""),a(r).each(function(c,d){return a(d).attr("data-plenty-checkout-id")==b?(j(c),!0):void 0}),!1)}function p(){var b=q.length;if(!(0>=b)){a(q).removeAttr("style"),a(q).children("span").removeAttr("style"),a(u).removeAttr("style"),a(t).removeAttr("style");var c=a(t).outerWidth()c?a(d).children("span").css({paddingLeft:g+"px",paddingRight:h+"px"}):a(d).children("span").css({paddingLeft:j+"px",paddingRight:k+"px"})})}}var q=[],r=[],s=-1,t={},u={},v={beforeChange:[],afterChange:[]},w=[];return{init:e,getCurrentContainer:f,goTo:j,beforeChange:g,afterChange:h,continueChange:l,next:m,previous:n,goToID:o,fillNavigation:p}},["CMSFactory","CheckoutFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("PostfinderService",function(c,d,e){function f(){var b=a('input[name="Street"]').val();return"PACKSTATION"==b.toUpperCase()||"POSTFILIALE"==b.toUpperCase()}function g(){j={PostfinderItemStreet:a('input[name="Street"]','[data-plenty-checkout-form="shippingAddress"]'),PostfinderItemZIP:a('input[name="ZIP"]','[data-plenty-checkout-form="shippingAddress"]'),PostfinderItemCity:a('input[name="City"]','[data-plenty-checkout-form="shippingAddress"]'),PostfinderItemHouseNo:a('input[name="HouseNo"]','[data-plenty-checkout-form="shippingAddress"]')},j.PostfinderItemStreet.val(""),j.PostfinderItemZIP.val().length>2||j.PostfinderItemCity.val().length>2?c.get("/rest/checkout/shippingaddresspostfinderlist/",{suggestionType:"postfinder",zip:j.PostfinderItemZIP.val(),city:j.PostfinderItemCity.val()}).done(function(c){l=c.data,k=l.length,0==k&&h();for(var e={addresses:[]},f=0;k>f;f++){var g="km",m=l[f].PostfinderItemDistance,n=m/1e3;n=(Math.round(100*n)/100).toFixed(2).replace(".",","),1e3>m&&(n=m,g="m"),e.addresses.push({index:f,dimension:g,type:l[f].PostfinderItemIsPackstation?"Packstation":"Postfiliale",number:l[f].PostfinderItemIsPackstation?l[f].PostfinderItemPackstationNo:l[f].PostfinderItemPostfilialNo,street:l[f].PostfinderItemStreet,houseNo:l[f].PostfinderItemHouseNo,zip:l[f].PostfinderItemZIP,city:l[f].PostfinderItemCity,district:l[f].PostfinderItemDistrict,distance:n,remark:l[f].PostfinderItemRemark})}var o=b.compileTemplate("addressSuggestions/postFinder.html",e);d.prepare().setTitle(b.translate("Packstations and post offices in your area")).setContent(o).setClass("checkout").onConfirm(function(){return j.PostfinderItemCity.removeClass("has-error").addClass("has-success"),a('label[for="'+j.PostfinderItemCity.attr("id")+'"]').removeClass("has-error").addClass("has-success"),j.PostfinderItemZIP.removeClass("has-error").addClass("has-success"),a('label[for="'+j.PostfinderItemZIP.attr("id")+'"]').removeClass("has-error").addClass("has-success"),j.PostfinderItemStreet.removeClass("has-error").addClass("has-success"),a('label[for="'+j.PostfinderItemStreet.attr("id")+'"]').removeClass("has-error").addClass("has-success"),j.PostfinderItemHouseNo.removeClass("has-error").addClass("has-success"),a('label[for="'+j.PostfinderItemHouseNo.attr("id")+'"]').removeClass("has-error").addClass("has-success"),i=a('input[type="radio"][name="postfinder"]:checked').val(),l[i].PostfinderItemIsPackstation?(a(j.PostfinderItemStreet).val("PACKSTATION"),a(j.PostfinderItemHouseNo).val(l[i].PostfinderItemPackstationNo)):(a(j.PostfinderItemStreet).val("POSTFILIALE"),a(j.PostfinderItemHouseNo).val(l[i].PostfinderItemPostfilialNo)),a(j.PostfinderItemStreet).trigger("change"),a(j.PostfinderItemCity).val(l[i].PostfinderItemCity),a(j.PostfinderItemZIP).val(l[i].PostfinderItemZIP),!0}).show()}):h()}function h(){e.throwError(0,b.translate("Please enter a ZIP code and/or a city.")),j.PostfinderItemCity.removeClass("has-success").addClass("has-error"),a('label[for="'+j.PostfinderItemCity.attr("id")+'"]').removeClass("has-success").addClass("has-error"),j.PostfinderItemZIP.removeClass("has-success").addClass("has-error"),a('label[for="'+j.PostfinderItemZIP.attr("id")+'"]').removeClass("has-success").addClass("has-error"),j.PostfinderItemCity.focus(function(){a(this).removeClass("has-error");var b=a(this).attr("id");a(this).closest(".form-group").find('[for="'+b+'"]').removeClass("has-error")}),j.PostfinderItemZIP.focus(function(){a(this).removeClass("has-error");var b=a(this).attr("id");a(this).closest(".form-group").find('[for="'+b+'"]').removeClass("has-error")})}var i="",j={},k={},l={};return{openPostfinderModal:g,isPackstation:f}},["APIFactory","ModalFactory","UIFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("SocialShareService",function(){function b(a){var b={"facebook-like":'',"facebook-recommend":'',twitter:'',"google-plus":'
'};return b[a]}function c(){var b=document.location.href,c=a("link[rel=canonical]").attr("href");return c&&c.length>0&&(c.indexOf("http")<0&&(c=document.location.protocol+"//"+document.location.host+c),b=c),b}function d(b){var c=a('meta[name="'+b+'"]').attr("content");return c||""}function e(){var b=d("DC.title"),c=d("DC.creator");return b.length>0&&c.length>0?b+=" - "+c:b=a("title").text(),encodeURIComponent(b)}return"undefined"==typeof socialLangLocale&&(socialLangLocale="en_US"),"undefined"==typeof socialLang&&(socialLang="en"),{getSocialService:b}})}(jQuery,PlentyFramework),function(a,b){b.service("ValidationService",function(){function b(b){return b=a(b),b.is("input")||b.is("select")||b.is("textarea")?b:b.find("input").length>0?b.find("input"):b.find("select").length>0?b.find("select"):b.find("textarea").length>0?b.find("textarea"):null}function c(b){return b.is("input")||b.is("select")||b.is("textarea")?a.trim(b.val()).length>0:(console.error("Validation Error: Cannot validate Text for <"+b.prop("tagName")+">"),!1)}function d(b){var d=/[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;return c(b)?d.test(a.trim(b.val())):!1}function e(b){return c(b)?a.isNumeric(a.trim(b.val())):!1}function f(b,c,d){return b=a.trim(b.val()),c=a.trim(a(c).length>0?a(c).val():c),d?b==c:b.toLowerCase()==c.toLowerCase()}function g(a){return!a.is(":visible")||!a.is(":enabled")}function h(h,i){var j,k,l,m,n,o,p,q,r,s,t,u=a(h);i=i||"has-error";var v=[],w=!1;u.find("[data-plenty-validate], :required").each(function(h,x){r=a(x).attr("data-plenty-validate"),k=b(x),s=r?r:"text",s=s.split(",");for(var h=0,y=k.length;y>h;h++){if(j=a(k[h]),t=j.attr("type"),g(j))return;if(l=s[h].trim()||s[0].trim(),m=!1,j.is("input")&&"radio"!=t&&"checkbox"!=t||j.is("textarea"))switch(l){case"text":m=!c(j);break;case"mail":m=!d(j);break;case"number":m=!e(j);break;case"value":m=!f(j,a(x).attr("data-plenty-validation-value"),"password"===j.context.type);break;case"none":break;default:console.error('Form validation error: unknown validate property: "'+r+'"')}else if(!j.is("input")||"radio"!=t&&"checkbox"!=t){if(!j.is("select"))return void console.error("Form validation error: "+a(x).prop("tagName")+" does not contain an form element");m=""==j.val()||"-1"==j.val()}else{if(n=j.attr("name"),o=u.find('input[name="'+n+'"]:checked').length,"radio"==t)p=1,q=1;else{var z=new Function("return "+r)()||{min:1,max:1};p=z.min,q=z.max}m=p>o||o>q}m&&(w=!0,v.push(j),k.length>1?(j.addClass(i),u.find('label[for="'+j.attr("id")+'"]').addClass(i)):a(x).addClass(i)); -}}),u.on("validationFailed",function(){var b=50,c=u.find("."+i).first(),d=c.offset().top,e=a("html, body");u.parents(".modal").length>0?(e=u.parents(".modal").find(".modal-body"),d=e.scrollTop()-(e.offset().top-c.offset().top)):u.is(".modal")&&(e=u.find(".modal-body"),d=e.scrollTop()-(e.offset().top-c.offset().top)),(d-bwindow.pageYOffset+window.innerHeight)&&e.animate({scrollTop:d-b})}),w&&(u.find("."+i).each(function(c,d){j=a(b(d)),j.on("focus click",function(){var b=a(d);b.removeClass(i),u.find('label[for="'+a(this).attr("id")+'"]').removeClass(i)})}),u.trigger("validationFailed",[v]));var x=u.attr("data-plenty-callback");if(!w&&x&&"submit"!=x&&"function"==typeof window[x]){var y={};return u.find("input, textarea, select").each(function(){"checkbox"==a(this).attr("type")?y[a(this).attr("name")]=a(this).is(":checked"):y[a(this).attr("name")]=a(this).val()}),window[x](y),!1}return!w}return{validate:h}}),a.fn.validateForm=function(){return b.getInstance().ValidationService.validate(this)},a.fn.getFormValues=function(){function b(b,c){var e=b.match(/^([^\[]+)(.*)/);if(e[2]){var f,g=/\[([^\]]+)]/g,h=[];for(h[0]=e[1];null!==(f=g.exec(e[2]));)h.push(f[1]);for(var i=h.length-1;i>=0;i--){var j={};j[h[i]]=c,c=j}d=a.extend(!0,d,c)}else d[e[1]]=c}var c=this,d={};return c.find("input, select, textarea").each(function(d,e){if(a(e).attr("name"))if("checkbox"==a(e).attr("type")){var f=[];a(c).find('[name="'+a(e).attr("name")+'"]:checked').each(function(b,c){f.push(a(c).val())}),b(a(e).attr("name"),f)}else"radio"==a(e).attr("type")?a(e).is(":checked")&&b(a(e).attr("name"),a(e).val()):b(a(e).attr("name"),a(e).val())}),d}}(jQuery,PlentyFramework),PlentyFramework.compile();var plenty=PlentyFramework.getInstance();jQuery(document).ready(function(){plenty.bindDirectives()}); -//# sourceMappingURL=plentymarketsCMStools-1.0.11.min.js.map \ No newline at end of file diff --git a/dist/plentymarketsCMStools-1.0.11.min.js.map b/dist/plentymarketsCMStools-1.0.11.min.js.map deleted file mode 100644 index 874ef0e..0000000 --- a/dist/plentymarketsCMStools-1.0.11.min.js.map +++ /dev/null @@ -1,936 +0,0 @@ -{ - "version": 3, - "file": "plentymarketsCMStools-1.0.11.min.js", - "sources": [ - "plentymarketsCMStools-1.0.11.js" - ], - "names": [ - "TemplateCache", - "global", - "factory", - "exports", - "nodeName", - "define", - "amd", - "Mustache", - "this", - "mustache", - "isFunction", - "object", - "typeStr", - "obj", - "isArray", - "escapeRegExp", - "string", - "replace", - "hasProperty", - "propName", - "testRegExp", - "re", - "regExpTest", - "call", - "isWhitespace", - "nonSpaceRe", - "escapeHtml", - "String", - "s", - "entityMap", - "parseTemplate", - "template", - "tags", - "stripSpace", - "hasTag", - "nonSpace", - "spaces", - "length", - "tokens", - "pop", - "compileTags", - "tagsToCompile", - "split", - "spaceRe", - "Error", - "openingTagRe", - "RegExp", - "closingTagRe", - "closingCurlyRe", - "sections", - "start", - "type", - "value", - "chr", - "token", - "openSection", - "scanner", - "Scanner", - "eos", - "pos", - "scanUntil", - "i", - "valueLength", - "charAt", - "push", - "scan", - "tagRe", - "whiteRe", - "equalsRe", - "curlyRe", - "nestTokens", - "squashTokens", - "lastToken", - "squashedTokens", - "numTokens", - "section", - "nestedTokens", - "collector", - "tail", - "Context", - "view", - "parentContext", - "cache", - ".", - "parent", - "Writer", - "objectToString", - "Object", - "prototype", - "toString", - "Array", - "test", - "&", - "<", - ">", - "\"", - "'", - "/", - "match", - "index", - "substring", - "search", - "lookup", - "name", - "hasOwnProperty", - "names", - "context", - "lookupHit", - "indexOf", - "clearCache", - "parse", - "render", - "partials", - "renderTokens", - "originalTemplate", - "symbol", - "buffer", - "undefined", - "renderSection", - "renderInverted", - "renderPartial", - "unescapedValue", - "escapedValue", - "rawValue", - "subRender", - "self", - "j", - "slice", - "escape", - "version", - "defaultWriter", - "TypeError", - "to_html", - "send", - "result", - "$", - "bindEventCallback", - "$elem", - "eventType", - "callback", - "params", - "on", - "event", - "eventStack", - "apply", - "document", - "readyState", - "addCustomEvents", - "element", - "is", - "trigger", - "radioGroup", - "attr", - "each", - "radio", - "$radio", - "parseDirectives", - "input", - "thisValue", - "directivePattern", - "expressions", - "directives", - "expression", - "trim", - "console", - "error", - "directive", - "class", - "method", - "param", - "isNaN", - "parseFloat", - "toLowerCase", - "compileComponent", - "component", - "componentLevel", - "dependencyStack", - "compiledDependencies", - "dependencies", - "dependency", - "inArray", - "components", - "factories", - "PlentyFramework", - "services", - "join", - "setup", - "instance", - "getInstance", - "compare", - "localVersion", - "compareVersion", - "parseInt", - "get", - "equals", - "v", - "globals", - "setGlobal", - "identifier", - "getGlobal", - "fallbackValue", - "directiveName", - "directiveFunctions", - "bindDirectives", - "rootElement", - "find", - "getRecentEvent", - "lastEventIdx", - "pushEvent", - "service", - "serviceName", - "serviceFunctions", - "factoryName", - "factoryFunctions", - "compileTemplate", - "data", - "translate", - "text", - "scriptPath", - "Strings", - "loadLanguageFile", - "fileName", - "ajax", - "url", - "dataType", - "done", - "response", - "localeString", - "warn", - "compile", - "scripts", - "getElementsByTagName", - "path", - "src", - "jQuery", - "pm", - "AuthenticationService", - "login", - "elem", - "preventDefault", - "customerLogin", - "BasketService", - "addBasketItem", - "basketItemsList", - "parentForm", - "parents", - "BasketItemItemID", - "val", - "BasketItemPriceID", - "BasketItemQuantity", - "BasketItemBranchID", - "attributeInputsList", - "attributesList", - "idx", - "BasketItemAttributeID", - "BasketItemAttributeValueID", - "BasketItemAttributesList", - "addItem", - "changeItemQuantity", - "increment", - "$quantityInput", - "maxLength", - "isBasketView", - "timeout", - "window", - "clearTimeout", - "setTimeout", - "setItemQuantity", - "basketItemID", - "fail", - "basketItem", - "getItem", - "CheckoutService", - "setMethodOfPayment", - "paymentID", - "confirmAtrigaPaymax", - "atrigaPaymaxConfirmed", - "MediaSize", - "initDropdowns", - "resetDropdowns", - "dropdownElements", - "closableDropdownElements", - "dropdownList", - "$current", - "target", - "removeClass", - "unbind", - "resetEvent", - "openDropdown", - "alwaysClickable", - "$parent", - "isInterval", - "Modernizr", - "touch", - "showDropdownHideOthers", - "avoidRedirectinStopPropagation", - "not", - "addClass", - "off", - "e", - "stopPropagation", - "slideDropdown", - "$elemParent", - "siblings", - "slideToggle", - "removeAttr", - "MediaSizeService", - "NavigatorService", - "to", - "href", - "interval", - "location", - "assign", - "toCheckoutTab", - "tabID", - "goToID", - "showTab", - "tabSelector", - "tab", - "initRemoteLabel", - "groupID", - "tabGroups", - "TabGroup", - "getTab", - "addTab", - "addLabel", - "initRemoteTab", - "setContent", - "showRemoteTab", - "tabs", - "Tab", - "zIndex", - "activeTab", - "getContent", - "css", - "hide", - "currentZ", - "resetTabs", - "show", - "id", - "getID", - "label", - "$labels", - "content", - "$content", - "SocialShareService", - "UIFactory", - "initUIWindowEvents", - "fireEqualHeight", - "toTopButtonList", - "scrollTop", - "doToArrayElements", - "showWaitscreen", - "hideWaitscreen", - "forceClose", - "addContentPageSlider", - "owlCarousel", - "navigation", - "navigationText", - "slideSpeed", - "paginationSpeed", - "singleItem", - "autoPlay", - "stopOnHover", - "afterMove", - "current", - "equalHeight", - "mediaSizes", - "elementExists", - "maxHeight", - "$equalTarget", - "$equalTargetList", - "children", - "equalHeightElementList", - "outerHeight", - "height", - "initToTop", - "click", - "animate", - "initLazyload", - "effect", - "lazyload", - "toggleHideShow", - "log", - "initSlideToggle", - "checked", - "$targetElement", - "$radioGroupList", - "visibleOnChecked", - "change", - "$self", - "slideDown", - "slideUp", - "toggleClass", - "duration", - "slideAction", - "$target", - "callbackString", - "toggleSocialShare", - "socialShareService", - "$toggle", - "append", - "hasClass", - "tooltip", - "getSocialService", - "cssClass", - "array", - "func", - "ValidationService", - "validate", - "form", - "errorClass", - "UI", - "Modal", - "renewLoginSession", - "sessionExpirationTimeout", - "prepare", - "setTitle", - "setLabelDismiss", - "setLabelConfirm", - "onConfirm", - "onDismiss", - "handleError", - "jqXHR", - "responseText", - "parseJSON", - "printErrors", - "error_stack", - "throwError", - "status", - "statusText", - "_get", - "ignoreErrors", - "runInBackground", - "sync", - "showWaitScreen", - "async", - "always", - "hideWaitScreen", - "_post", - "isFile", - "processData", - "contentType", - "JSON", - "stringify", - "_put", - "_delete", - "_idle", - "Deferred", - "resolve", - "ready", - "post", - "put", - "delete", - "idle", - "API", - "getContainer", - "containerName", - "from", - "layoutGroup", - "getParams", - "getCategoryContent", - "categoryID", - "CMS", - "Checkout", - "checkoutData", - "getCheckout", - "copy", - "checkout", - "loadCheckout", - "extend", - "setCheckout", - "reloadContainer", - "container", - "html", - "reloadCatContent", - "catId", - "reloadItemContainer", - "isModal", - "selector", - "title", - "modal", - "setClass", - "labelConfirm", - "labelDismiss", - "setContainer", - "bsModal", - "getModal", - "filter", - "script", - "createElement", - "innerHTML", - "init", - "close", - "startTimeout", - "confirmed", - "timeRemaining", - "timeStart", - "Date", - "getTime", - "clearInterval", - "setInterval", - "paused", - "secondsRemaining", - "Math", - "round", - "pauseTimeout", - "continueTimeout", - "stopTimeout", - "code", - "msg", - "message", - "errorMessages", - "errorPopup", - "has", - "key", - "addError", - "waitScreenCount", - "waitScreen", - "WaitScreen", - "a", - "b", - "constructor", - "cssClasses", - "active", - "popup", - "hideAll", - "errorCode", - "remove", - "hover", - "root", - "validateAddress", - "addressForms", - "addressIsValid", - "addressDoctor", - "AddressDoctor", - "requiredFields", - "isValid", - "fields", - "isPackstation", - "suggestions", - "AddressList", - "$form", - "getFormValues", - "refreshView", - "getAddresses", - "suggestionListVisible", - "validateInput", - "houseNoAllowed", - "$inputs", - "HouseNo", - "valueList", - "getList", - "$suggestionContainer", - "buildSuggestionList", - "focus", - "positionSuggestionList", - "suggestionKey", - "width", - "outerWidth", - "left", - "position", - "top", - "values", - "filterAddress", - "Street", - "toUpperCase", - "ZIP", - "City", - "addressInput", - "suggestionType", - "street", - "city", - "houseNo", - "country", - "CountryID", - "responseLength", - "currentResponse", - "address", - "getAddress", - "addresses", - "suggestion", - "addressCount", - "results", - "filteredAddresses", - "range", - "resetPassword", - "validateForm", - "Email", - "IsMailSend", - "loginMail", - "Password", - "loginPassword", - "setInvoiceAddress", - "invoiceAddress", - "CustomerInvoiceAddress", - "registerCustomer", - "AddressDoctorService", - "LoginType", - "customerInvoiceAddress", - "CustomerProperty", - "tmpProperties", - "CustomerPropertiesList", - "property", - "PropertyID", - "PropertyValue", - "article", - "itemID", - "quantity", - "resp", - "addArticle", - "saveOrderParams", - "articleWithParams", - "orderParamsForm", - "attrType", - "addOrderParamValue", - "files", - "orderParamFileUpload", - "paramValue", - "$artAttr", - "$unitCombinationId", - "requestData", - "ArticleID", - "refreshBasketPreview", - "updateArticle", - "$input", - "formData", - "fileData", - "orderParamUploadFiles", - "orderParamFileIdStack", - "FormData", - "basketList", - "paramId", - "BasketItemOrderParamsList", - "BasketItemOrderParamID", - "BasketItemOrderParamValue", - "editItemAttributes", - "BasketItemID", - "getBasketItem", - "attributeSelect", - "editOrderParams", - "basketItems", - "BasketItemsList", - "removeBasketItem", - "forceDelete", - "doDelete", - "$oldBasketList", - "$basketListContainer", - "fadeOut", - "prepend", - "fadeIn", - "deferred", - "itemName", - "BasketItemNameMap", - "item", - "reject", - "basketItemIndex", - "itemQuantityTotal", - "Totals", - "TotalsItemSum", - "addCoupon", - "CouponActiveCouponCode", - "updateContainer", - "removeCoupon", - "Coupon", - "removeItem", - "setCustomerSignAndInfo", - "CheckoutCustomerSign", - "CheckoutOrderInfoText", - "CustomerSign", - "OrderInfoText", - "saveShippingAddress", - "shippingAddressID", - "shippingAddress", - "addressesAreEqual", - "CustomerShippingAddress", - "IsPackstation", - "PackstationNo", - "IsPostfiliale", - "PostfilialNo", - "CheckoutCustomerShippingAddressID", - "ID", - "CheckoutShippingCountryID", - "updatePaymentAndShippingDependencies", - "CheckoutMethodOfPaymentID", - "CheckoutShippingProfileID", - "registerGuest", - "address1", - "address2", - "setShippingProfile", - "ShippingProfileID", - "preparePayment", - "paymentData", - "CheckoutMethodOfPaymentRedirectURL", - "CheckoutMethodOfPaymentAdditionalContent", - "isBankDetails", - "saveBankDetails", - "saveCreditCard", - "errorStack", - "CheckoutAtrigapaymaxChecked", - "atrigaPaymaxChecked", - "editBankDetails", - "customerBankDetails", - "bankDetails", - "CustomerBankName", - "bankName", - "CustomerBLZ", - "blz", - "CustomerAccountNumber", - "accountNo", - "CustomerAccountOwner", - "accountOwner", - "CustomerIBAN", - "iban", - "CustomerBIC", - "bic", - "editCreditCard", - "paymentInformationCC", - "creditCard", - "Owner", - "owner", - "Cvv2", - "cvv2", - "Number", - "number", - "Year", - "year", - "Month", - "month", - "Provider", - "provider", - "loadAddressSuggestion", - "postnummer", - "Postnummer", - "placeOrder", - "TermsAndConditionsCheck", - "termsAndConditionsCheck", - "WithdrawalCheck", - "withdrawalCheck", - "PrivacyPolicyCheck", - "privacyPolicyCheck", - "AgeRestrictionCheck", - "ageRestrictionCheck", - "NewsletterCheck", - "newsletterCheck", - "KlarnaTermsAndConditionsCheck", - "klarnaTermsAndConditionsCheck", - "PayoneDirectDebitMandateCheck", - "payoneDirectDebitMandateCheck", - "PayoneInvoiceCheck", - "payoneInvoiceCheck", - "MethodOfPaymentRedirectURL", - "MethodOfPaymentAdditionalContent", - "getFeedbacks", - "setFeedbackInterval", - "end", - "feedbackInterval", - "dateStart", - "dateEnd", - "listFeedbacks", - "articleType", - "referenceId", - "feedbackType", - "ReferenceId", - "FromDate", - "ToDate", - "FeedbackType", - "feedbackTypes", - "COMMENTS_AND_RATINGS", - "between", - "for", - "addFeedback", - "withRating", - "rating", - "Rating", - "withComment", - "comment", - "Text", - "withAuthor", - "author", - "mail", - "customerID", - "Author", - "CustomerId", - "sendFeedback", - "COMMENTS_ONLY", - "RATINGS_ONLY", - "articleTypes", - "ITEM", - "CATEGORY", - "BLOG", - "ArticleTypes", - "FeedbackTypes", - "getInterval", - "bsInterval", - "calculateMediaSize", - "size", - "matchMedia", - "matches", - "oldValue", - "intervalList", - "resize", - "buttonNext", - "buttonPrev", - "goTo", - "next", - "previous", - "addEventListener", - "hash", - "urlParam", - "exec", - "fillNavigation", - "getCurrentContainer", - "beforeChange", - "interceptor", - "interceptors", - "afterChange", - "resolveInterceptors", - "continueTabChange", - "currentContainer", - "targetContainer", - "ignoreInterceptors", - "contentChanged", - "checkoutStates", - "proceedTabChange", - "continueChange", - "containerID", - "navigationCount", - "buttonWidth", - "padding", - "tabWidth", - "paddingLeft", - "paddingRight", - "paddingEachItem", - "paddingLastLeft", - "paddingLastRight", - "paddingLastItem", - "openPostfinderModal", - "shippingFields", - "PostfinderItemStreet", - "PostfinderItemZIP", - "PostfinderItemCity", - "PostfinderItemHouseNo", - "zip", - "numberOfResults", - "showErrorMessage", - "dimension", - "distInMeters", - "PostfinderItemDistance", - "distInKilometers", - "toFixed", - "PostfinderItemIsPackstation", - "PostfinderItemPackstationNo", - "PostfinderItemPostfilialNo", - "district", - "PostfinderItemDistrict", - "distance", - "remark", - "PostfinderItemRemark", - "packstationID", - "inputId", - "closest", - "getService", - "facebook-like", - "socialLangLocale", - "encodeURIComponent", - "getURI", - "facebook-recommend", - "twitter", - "getTweetText", - "google-plus", - "socialLang", - "uri", - "canonical", - "protocol", - "host", - "getMeta", - "metaContent", - "creator", - "getFormControl", - "validateText", - "formControl", - "prop", - "validateMail", - "mailRegExp", - "validateNumber", - "isNumeric", - "compareValues", - "reference", - "caseSensitive", - "isNotVisibleOrEnabled", - "$formControl", - "formControls", - "validationKey", - "currentHasError", - "group", - "checkedMin", - "checkedMax", - "attrValidate", - "validationKeys", - "formControlAttrType", - "missingFields", - "hasError", - "minMax", - "Function", - "min", - "max", - "distanceTop", - "$error", - "first", - "errorOffset", - "offset", - "$scrollTarget", - "pageYOffset", - "innerHeight", - "$errorElement", - "fn", - "inject", - "child", - "exp", - "groupValues", - "checkbox", - "plenty" - ], - "mappings": "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", - "sourcesContent": [ - "var TemplateCache = {};\n\nTemplateCache[\"addressSuggestions/addressDoctor.html\"] = \"\";\n\nTemplateCache[\"addressSuggestions/postFinder.html\"] = \"{{#addresses}}\\n\" +\n \"
\\n\" +\n \"
\\n\" +\n \" \\n\" +\n \"
\\n\" +\n \"
\\n\" +\n \"{{/addresses}}\\n\" +\n \"\";\n\nTemplateCache[\"error/errorMessage.html\"] = \"
\\n\" +\n \" Code {{code}}:\\n\" +\n \" {{{message}}}\\n\" +\n \"
\\n\" +\n \"\";\n\nTemplateCache[\"error/errorPopup.html\"] = \"
\\n\" +\n \" \\n\" +\n \"
\\n\" +\n \"
\\n\" +\n \"
\\n\" +\n \"\";\n\nTemplateCache[\"modal/modal.html\"] = \"
\\n\" +\n \"
\\n\" +\n \"
\\n\" +\n \"\\n\" +\n \" {{#title}}\\n\" +\n \"
\\n\" +\n \" \\n\" +\n \"

{{{title}}}

\\n\" +\n \"
\\n\" +\n \" {{/title}}\\n\" +\n \"\\n\" +\n \"
{{{content}}}
\\n\" +\n \"\\n\" +\n \"
\\n\" +\n \"\\n\" +\n \" {{#labelDismiss}}\\n\" +\n \" \\n\" +\n \" {{/labelDismiss}}\\n\" +\n \"\\n\" +\n \" \\n\" +\n \"
\\n\" +\n \"
\\n\" +\n \"
\\n\" +\n \"
\\n\" +\n \"\";\n\nTemplateCache[\"waitscreen/waitscreen.html\"] = \"
\";\n\n(function defineMustache(global,factory){if(typeof exports===\"object\"&&exports&&typeof exports.nodeName!==\"string\"){factory(exports)}else if(typeof define===\"function\"&&define.amd){define([\"exports\"],factory)}else{global.Mustache={};factory(Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)===\"[object Array]\"};function isFunction(object){return typeof object===\"function\"}function typeStr(obj){return isArray(obj)?\"array\":typeof obj}function escapeRegExp(string){return string.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g,\"\\\\$&\")}function hasProperty(obj,propName){return obj!=null&&typeof obj===\"object\"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={\"&\":\"&\",\"<\":\"<\",\">\":\">\",'\"':\""\",\"'\":\"'\",\"/\":\"/\"};function escapeHtml(string){return String(string).replace(/[&<>\"'\\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\\s*/;var spaceRe=/\\s+/;var equalsRe=/\\s*=/;var curlyRe=/\\s*\\}/;var tagRe=/#|\\^|\\/|>|\\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile===\"string\")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error(\"Invalid tags: \"+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+\"\\\\s*\");closingTagRe=new RegExp(\"\\\\s*\"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp(\"\\\\s*\"+escapeRegExp(\"}\"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===\"\"};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return\"\";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail=\"\";break;case 0:match=\"\";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={\".\":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(\".\")>0){value=context.view;names=name.split(\".\");index=0;while(value!=null&&index\")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol===\"&\")value=this.unescapedValue(token,context);else if(symbol===\"name\")value=this.escapedValue(token,context);else if(symbol===\"text\")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer=\"\";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j\n * =====================================================================================\n */\n\n/**\n * @module PlentyFramework\n */\n(function( $ )\n{\n // will be overridden by grunt\n var version = \"1.0.11\";\n\n /**\n * Collection of uncompiled registered factories & services.\n * See {{#crossLink \"PlentyFramework/compile:method\"}}.compile(){{/crossLink}}\n * @attribute components\n * @static\n * @type {{factories: {}, services: {}}}\n */\n var components = {\n factories : {},\n services : {},\n directives: {}\n };\n\n /**\n * Framework providing client functions for plentymarkets Webshops.\n * @class PlentyFramework\n * @constructor\n */\n PlentyFramework = function()\n {\n };\n\n var instance = null;\n PlentyFramework.getInstance = function()\n {\n instance = instance || new PlentyFramework();\n return instance;\n };\n\n PlentyFramework.version = (function() {\n\n return {\n get: function() {\n return version;\n },\n equals: function( v ) {\n return compare(v) == 0;\n },\n compare: compare\n };\n\n function compare( compare )\n {\n var localVersion = version.split(\".\");\n var compareVersion = compare.split(\".\");\n\n for( var i = 0; i < compareVersion.length; i++ )\n {\n if( localVersion[i] === compareVersion[i] || compareVersion[i] === \"*\" )\n {\n continue;\n }\n\n if( parseInt(localVersion[i]) < parseInt(compareVersion[i]) )\n {\n return -1;\n }\n\n if( parseInt(localVersion[i]) > parseInt(compareVersion[i]) )\n {\n return 1;\n }\n }\n return 0;\n }\n\n })();\n\n /**\n * Customizable controls for partials will be injected here.\n * (e.g. Modal)\n * @attribute\n * @static\n * @type {object}\n */\n PlentyFramework.partials = {};\n\n /**\n * Collection of registered global variables\n * @attribute\n * @static\n * @type {object}\n */\n PlentyFramework.globals = {};\n\n /**\n * Set a global variable.\n * @function setGlobal\n * @static\n * @param {string} identifier A unique identifier to reference this variable\n * @param {*} value The value to set\n * @return {*} The value\n */\n PlentyFramework.setGlobal = function( identifier, value )\n {\n if ( PlentyFramework.globals.hasOwnProperty( identifier ) )\n {\n console.error( 'Global variable \"' + identifier + '\" already exists and cannot be overridden.' );\n return null;\n }\n\n PlentyFramework.globals[identifier] = value;\n\n return PlentyFramework.globals[identifier];\n };\n\n /**\n * Get the value of a global variable or undefined if not exists\n * @function getGlobal\n * @static\n * @param identifier The identifier of the requested variable\n * @return {*} The value of the variable\n */\n PlentyFramework.getGlobal = function( identifier, fallbackValue )\n {\n if( !PlentyFramework.globals.hasOwnProperty( identifier ) )\n {\n return fallbackValue;\n }\n return PlentyFramework.globals[identifier];\n };\n\n /**\n * Collection of registered directives\n * @type {Array}\n * @static\n */\n PlentyFramework.directives = {};\n\n /**\n * Register directive. Directives can be bound to dynamically added nodes by calling pm.bindPlentyFunctions();\n * @function directive\n * @static\n * @param {string} selector jQuery selector of the DOM-elements to bind the directive to\n * @param {function} callback Function to add directives behaviour\n * @param {Array} dependencies List of required services. Services will be passed to callback function\n * @param {boolean} allowDuplicates Defines if a directive can be bound to the same element multiple times\n * @return {object} The created directive\n */\n PlentyFramework.directive = function( directiveName, directiveFunctions, dependencies )\n {\n // Catch type mismatching for 'directiveName'\n if ( typeof directiveName !== 'string' )\n {\n console.error( \"Type mismatch: Expect first parameter to be a 'string', '\" + typeof directiveName + \"' given.\" );\n return;\n }\n\n // Catch type mismatching for 'serviceFunctions'\n if ( typeof directiveFunctions !== 'function' )\n {\n console.error( \"Type mismatch: Expect second parameter to be a 'function', '\" + typeof directiveFunctions + \"' given.\" );\n return;\n }\n\n dependencies = dependencies || [];\n\n components.directives[directiveName] = {\n name : directiveName,\n dependencies: dependencies,\n setup : directiveFunctions\n };\n };\n\n /**\n * Bind registered directives.\n * @function bindDirectives\n * @param {string} [directiveSelector] restrict binding to elements matching this selector\n */\n PlentyFramework.prototype.bindDirectives = function( rootElement )\n {\n\n rootElement = rootElement || 'html';\n\n $( rootElement ).find( '[data-plenty]' ).each( function( i, element )\n {\n\n var directives = parseDirectives( $( element ).attr( 'data-plenty' ), $( element ) );\n\n if ( directives.length <= 0 )\n {\n // continue\n return;\n }\n\n addCustomEvents( element );\n\n for ( var i = 0; i < directives.length; i++ )\n {\n var directive = directives[i];\n if ( !!PlentyFramework.directives[directive.class] && PlentyFramework.directives.hasOwnProperty( directive.class ) )\n {\n\n var callback = PlentyFramework.directives[directive.class][directive.method];\n if ( !!callback && typeof callback == \"function\" )\n {\n\n if ( directive.event == \"ready\" )\n {\n callback.apply( null, directive.params );\n }\n else\n {\n bindEventCallback( $( element ), directive.event, callback, directive.params );\n /*\n $( element ).on( directive.event, function( e )\n {\n directive = injectEvent( directive, e );\n return callback.apply( null, directive.params );\n } );\n */\n }\n\n }\n else\n {\n console.error( \"Method not found: \" + directive.method + \" in \" + directive.class );\n }\n\n }\n else\n {\n console.error( \"Directive not found: \" + directive.class );\n }\n }\n } );\n\n $( document ).trigger( 'initPartials', rootElement );\n };\n\n var eventStack = [];\n\n PlentyFramework.getRecentEvent = function( eventType )\n {\n var lastEventIdx = eventStack.length - 1;\n if ( !eventType )\n {\n return eventStack[lastEventIdx];\n }\n else\n {\n for ( var i = lastEventIdx; i >= 0; i-- )\n {\n if ( eventType == eventStack[i].type )\n {\n return eventStack[i];\n }\n }\n }\n\n return null;\n\n };\n\n PlentyFramework.pushEvent = function( event )\n {\n eventStack.push( event );\n };\n\n /**\n * Bind event to element by eventType.\n * If cms says \"click:Foo.bar(this, event)\" eventType is \"click\".\n *\n * @param $elem - jQuery object on which event was triggered\n * @param eventType - type of event\n * @param callback - callback function of directive [example: \"bar(this, event)\"]\n * @param params - list of parameters for callback function.\n */\n function bindEventCallback( $elem, eventType, callback, params )\n {\n $elem.on( eventType, function( event )\n {\n eventStack.push( event );\n return callback.apply( null, params );\n } );\n\n if( document.readyState === \"complete\" && eventType === \"ready\" )\n {\n // execute 'ready' directives directly if document is already loaded\n callback.apply( null, params );\n }\n }\n\n function addCustomEvents( element )\n {\n\n var $elem = $( element );\n\n if ( $elem.is( 'input[type=\"checkbox\"]' ) )\n {\n $elem.on( 'change', function()\n {\n\n if ( $elem.is( ':checked' ) )\n {\n $elem.trigger( 'check' );\n }\n else\n {\n $elem.trigger( 'uncheck' );\n }\n } );\n }\n\n if ( $elem.is( 'input[type=\"radio\"]' ) )\n {\n $elem.on( 'change', function()\n {\n\n var radioGroup = $elem.attr( 'name' );\n\n $( 'input[type=\"radio\"][name=\"' + radioGroup + '\"]' ).each( function( i, radio )\n {\n var $radio = $( radio );\n if ( $radio.is( ':checked' ) )\n {\n $radio.trigger( 'check' );\n }\n else\n {\n $radio.trigger( 'uncheck' );\n }\n\n } );\n\n } );\n }\n }\n\n function parseDirectives( input, thisValue )\n {\n var directivePattern = /^(([\\w]+):)?([\\w]+)\\.([\\w]+)(\\((.*)\\))?$/;\n var expressions = input.split( ';' );\n var directives = [];\n\n for ( var i = 0; i < expressions.length; i++ )\n {\n var expression = expressions[i].trim();\n\n if ( !expression )\n {\n continue;\n }\n\n if ( !directivePattern.test( expression ) )\n {\n // console.warn( \"Invalid directive: \" + expression );\n continue;\n }\n\n var match = expression.match( directivePattern );\n\n if ( !match[3] || match[3].length <= 0 )\n {\n console.error( \"Cannot parse '\" + expression + \"': Class name not set.\" );\n continue;\n }\n\n if ( !match[4] || match[4].length <= 0 )\n {\n console.error( \"Cannot parse '\" + expression + \"': Method not set.\" );\n continue;\n }\n\n var directive = {\n event : match[2] || 'ready',\n class : match[3],\n method: match[4],\n params: []\n };\n\n if ( !!match[6] && match[6].length > 0 )\n {\n var params = match[6].match( /(['][^']+['])|([\\w-]+)|([\"][^\"]+[\"])/g );\n for ( var j = 0; j < params.length; j++ )\n {\n var param = params[j].trim();\n if ( !isNaN( parseFloat( param ) ) )\n {\n directive.params.push( parseFloat( param ) );\n }\n else if ( param.toLowerCase() == 'true' )\n {\n directive.params.push( true );\n }\n else if ( param.toLowerCase() == 'false' )\n {\n directive.params.push( false );\n }\n else if ( param.toLowerCase() == 'this' )\n {\n directive.params.push( thisValue );\n }\n else\n {\n directive.params.push( param.replace( /^['\"]|['\"]$/g, '' ) );\n }\n }\n }\n\n directives.push( directive );\n\n }\n return directives;\n }\n\n /**\n * Register a new service\n * @function service\n * @static\n * @param {string} serviceName Unique identifier of the service to get/ create\n * @param {function} serviceFunctions Callback containing all public functions of this service.\n * @param {Array} [dependencies] Identifiers of required services to inject in serviceFunctions\n * @return {object} The object described in serviceFunctions(). Can be received via\n * PlentyFramework.[serviceName]\n */\n PlentyFramework.service = function( serviceName, serviceFunctions, dependencies )\n {\n\n // Catch type mismatching for 'serviceName'\n if ( typeof serviceName !== 'string' )\n {\n console.error( \"Type mismatch: Expect first parameter to be a 'string', '\" + typeof serviceName + \"' given.\" );\n return;\n }\n\n // Catch type mismatching for 'serviceFunctions'\n if ( typeof serviceFunctions !== 'function' )\n {\n console.error( \"Type mismatch: Expect second parameter to be a 'function', '\" + typeof serviceFunctions + \"' given.\" );\n return;\n }\n\n dependencies = dependencies || [];\n\n components.services[serviceName] = {\n name : serviceName,\n dependencies: dependencies,\n setup : serviceFunctions\n };\n\n };\n\n /**\n * Collection of compiled factories\n * @attribute factories\n * @static\n * @type {object}\n */\n PlentyFramework.factories = {};\n\n /**\n * Register a new factory\n * @function factory\n * @static\n * @param {string} factoryName A unique name of the new factory\n * @param {function} factoryFunctions The function describing the factory\n * @param {Array} dependencies List of required factories to inject\n */\n PlentyFramework.factory = function( factoryName, factoryFunctions, dependencies )\n {\n\n // Catch type mismatching for 'serviceName'\n if ( typeof factoryName !== 'string' )\n {\n console.error( \"Type mismatch: Expect first parameter to be a 'string', '\" + typeof factoryName + \"' given.\" );\n return;\n }\n\n // Catch type mismatching for 'serviceFunctions'\n if ( typeof factoryFunctions !== 'function' )\n {\n console.error( \"Type mismatch: Expect second parameter to be a 'function', '\" + typeof factoryFunctions + \"' given.\" );\n return;\n }\n\n dependencies = dependencies || [];\n components.factories[factoryName] = {\n name : factoryName,\n dependencies: dependencies,\n setup : factoryFunctions\n }\n\n };\n\n /**\n * Renders html template. Will provide given data to templates scope.\n * Uses Mustache syntax for data-binding.\n * @function compileTemplate\n * @static\n * @param {String} template relative path to partials template to load. Base path = '/src/partials/'\n * @param {Object} data data to privide to templates scope.\n * @returns {String} The rendered html string\n */\n PlentyFramework.compileTemplate = function( template, data )\n {\n data = data || {};\n data.translate = function()\n {\n return function( text, render )\n {\n return render( PlentyFramework.translate( text ) );\n };\n };\n return Mustache.render( TemplateCache[template], data );\n };\n\n /**\n * The path on the server where the script is located in.\n * @attribute\n * @static\n * @type {String}\n */\n PlentyFramework.scriptPath = '';\n\n /**\n * Collection of locale strings will be injected here after reading language file.\n * @attribute\n * @static\n * @type {Object}\n */\n PlentyFramework.Strings = {};\n\n /**\n * Load language file containing translations of locale strings.\n * @function loadLanguageFile\n * @static\n * @param fileName relative path to language file.\n */\n PlentyFramework.loadLanguageFile = function( fileName )\n {\n $.ajax({\n url: PlentyFramework.scriptPath + fileName,\n dataType: 'json'\n }).done( function( response ) {\n PlentyFramework.Strings = response;\n });\n };\n\n /**\n * Try to get locale translation of given string.\n * Render translated string using Mustache syntax\n * if additional parameters are given.\n * @function translate\n * @static\n * @param {String} string The string to translate\n * @param {Object} [params] additional data for rendering\n * @returns {String} The translation of the given string if found. Otherwise returns the original string.\n */\n PlentyFramework.translate = function( string, params )\n {\n var localeString;\n if ( PlentyFramework.Strings.hasOwnProperty( string ) )\n {\n localeString = PlentyFramework.Strings[string];\n }\n else\n {\n localeString = string;\n console.warn( 'No translation found for \"' + localeString + '\".' );\n }\n\n if ( !!params )\n {\n localeString = Mustache.render( localeString, params );\n }\n\n return localeString;\n\n };\n\n /**\n * Compile registered factories & services\n * @function compile\n * @static\n */\n PlentyFramework.compile = function()\n {\n\n for ( var factory in components.factories )\n {\n if ( !PlentyFramework.factories.hasOwnProperty( factory ) )\n {\n //components.factories[factory].compile();\n compileComponent( components.factories[factory], 3 );\n }\n }\n\n for ( var service in components.services )\n {\n if ( !PlentyFramework.prototype.hasOwnProperty( service ) )\n {\n //components.factories[factory].compile();\n compileComponent( components.services[service], 2 );\n }\n }\n\n for ( var directive in components.directives )\n {\n if ( !PlentyFramework.directives.hasOwnProperty( directive ) )\n {\n //components.factories[factory].compile();\n compileComponent( components.directives[directive], 1 );\n }\n }\n\n var scripts = document.getElementsByTagName( 'SCRIPT' );\n for( var i = scripts.length - 1; i >= 0; i-- ) {\n var path = scripts[i].src.match( /(.*)\\/(.*)\\.js(\\?\\S*)?$/ );\n if( !!path ) {\n PlentyFramework.scriptPath = path[1];\n break;\n }\n }\n\n };\n\n // Level: 1 = directive, 2 = service, 3 = factory\n function compileComponent( component, componentLevel, dependencyStack )\n {\n dependencyStack = dependencyStack || [];\n\n // resolve dependencies\n var compiledDependencies = [];\n for ( var i = 0; i < component.dependencies.length; i++ )\n {\n var dependency = component.dependencies[i];\n if ( $.inArray( dependency, dependencyStack ) < 0 )\n {\n // add dependency to stack to avoid cyclic injection\n dependencyStack.push( dependency );\n\n if ( components.factories.hasOwnProperty( dependency ) )\n {\n // required dependency is a factory\n if ( !PlentyFramework.factories.hasOwnProperty( dependency ) )\n {\n // factory is not compiled yet\n compileComponent( components.factories[dependency], 3, dependencyStack );\n }\n compiledDependencies.push( PlentyFramework.factories[dependency] );\n continue;\n }\n\n if ( componentLevel <= 2 && components.services.hasOwnProperty( dependency ) )\n {\n // required dependency is a service\n if ( !PlentyFramework.prototype.hasOwnProperty( dependency ) )\n {\n // service is not compiled yet\n compileComponent( components.services[dependency], 2, dependencyStack );\n }\n compiledDependencies.push( PlentyFramework.prototype[dependency] );\n continue;\n }\n\n if ( componentLevel <= 1 && components.directives.hasOwnProperty( dependency ) )\n {\n // required dependency is a directive\n if ( !PlentyFramework.directives.hasOwnProperty( dependency ) )\n {\n // directive is not compiled yet\n compileComponent( components.directives[dependency], 1, dependencyStack );\n }\n compiledDependencies.push( PlentyFramework.directives[dependency] );\n continue;\n }\n\n console.error( 'Cannot inject dependency \"' + dependency + '\": Object not found.' );\n }\n else\n {\n console.error( 'Cyclic dependency injection: ' + dependencyStack.join( ' -> ' ) + ' -> ' + dependency );\n }\n }\n\n // compile component\n if ( componentLevel == 3 )\n {\n PlentyFramework.factories[component.name] = component.setup.apply( null, compiledDependencies );\n }\n else if ( componentLevel == 2 )\n {\n PlentyFramework.prototype[component.name] = component.setup.apply( null, compiledDependencies );\n }\n else if ( componentLevel == 1 )\n {\n PlentyFramework.directives[component.name] = component.setup.apply( null, compiledDependencies );\n }\n }\n\n}( jQuery ));\n\n\n\n\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n(function( $, pm )\n{\n pm.directive( 'Authentication', function( AuthenticationService )\n {\n return {\n login: login\n };\n\n function login( elem )\n {\n pm.getRecentEvent().preventDefault();\n AuthenticationService.customerLogin( $( elem ) );\n }\n }, [\"AuthenticationService\"] );\n\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Basket', function( BasketService )\n {\n\n return {\n addBasketItem : addBasketItem,\n changeItemQuantity: changeItemQuantity,\n setItemQuantity : setItemQuantity\n };\n\n function addBasketItem( elem )\n {\n pm.getRecentEvent().preventDefault();\n //init\n var basketItemsList = {};\n var $elem = $( elem );\n var parentForm = $elem.parents( 'form' );\n\n basketItemsList.BasketItemItemID = parentForm.find( '[name=\"ArticleID\"]' ).val();\n basketItemsList.BasketItemPriceID = parentForm.find( '[name=\"SYS_P_ID\"]' ).val();\n basketItemsList.BasketItemQuantity = parentForm.find( '[name=\"ArticleQuantity\"]' ).val();\n basketItemsList.BasketItemBranchID = parentForm.find( '[name=\"source_category\"]' ).val();\n\n if ( parentForm.find( '[name=\"P_ID\"]' ) )\n {\n basketItemsList.BasketItemPriceID = parentForm.find( '[name=\"P_ID\"]:checked' ).val();\n }\n\n //attributes\n var attributeInputsList = parentForm.find( '[name^=\"ArticleAttribute\"]' );\n var attributesList = [];\n\n $.each( attributeInputsList, function( idx, elem )\n {\n var match = elem.name.match( /^ArticleAttribute\\[\\d+]\\[\\d+]\\[(\\d+)]$/ );\n if ( match && match[1] )\n {\n attributesList.push( {\n BasketItemAttributeID : match[1],\n BasketItemAttributeValueID: $( elem ).val()\n } );\n }\n } );\n\n if ( attributesList.length != 0 )\n {\n basketItemsList.BasketItemAttributesList = attributesList;\n }\n\n //add basketItem and refresh previewLists\n BasketService.addItem( [basketItemsList] );\n\n }\n\n function changeItemQuantity( elem, increment )\n {\n var $elem = $( elem );\n var $quantityInput = $elem.parent().find( 'input' );\n var maxLength = parseInt( $quantityInput.attr( 'maxlength' ) ) || 5;\n var value = parseInt( $quantityInput.val() ) + increment;\n\n var isBasketView = $elem.parents( '[data-basket-item-id]' ).length > 0;\n\n if ( isBasketView )\n {\n if ( (value + '').length <= maxLength && value >= 0 )\n {\n $quantityInput.val( value );\n }\n\n var timeout = $elem.data( 'timeout' );\n\n if ( !!timeout )\n {\n window.clearTimeout( timeout );\n }\n\n timeout = window.setTimeout( function()\n {\n $quantityInput.trigger( 'change' );\n }, 1000 );\n\n $elem.data( 'timeout', timeout );\n }\n else\n {\n if ( (value + '').length <= maxLength && value >= 1 )\n {\n $quantityInput.val( value );\n }\n }\n }\n\n function setItemQuantity( basketItemID, input )\n {\n BasketService.setItemQuantity(\n basketItemID,\n parseInt( $( input ).val() )\n ).fail( function()\n {\n // reset input's value on cancel\n var basketItem = BasketService.getItem( basketItemID );\n $( input ).val( basketItem.BasketItemQuantity );\n } );\n }\n\n }, ['BasketService'] );\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Checkout', function( CheckoutService )\n {\n\n return {\n setMethodOfPayment: setMethodOfPayment,\n confirmAtrigaPaymax: confirmAtrigaPaymax\n };\n\n function setMethodOfPayment( paymentID )\n {\n CheckoutService.setMethodOfPayment( paymentID );\n }\n\n function confirmAtrigaPaymax( atrigaPaymaxConfirmed )\n {\n CheckoutService.confirmAtrigaPaymax( atrigaPaymaxConfirmed );\n }\n }, ['CheckoutService'] );\n})( jQuery, PlentyFramework );\n/**\n * Mobile dropdowns\n * Toggles dropdowns using css class 'open' instead of pseudo class :hover\n * Usage:\n *
  • \n * ...\n *
  • \n *\n * possible values for CONDITION\n * \"touch\" : use 'open'-class if device is touch-device AND media size is 'md' or 'lg'\n * \"toggle-xs-sm-or-touch\" : use 'open'-class if device is \"touch\" (as above) OR media size is 'xs' or 'sm'\n *\n */\n(function( $, pm )\n{\n pm.directive( 'MobileDropdown', function( MediaSize )\n {\n // store all dropdown elements\n var dropdownElements = [];\n\n // store dropdown elements which should be closed by clicking outside the element itself\n var closableDropdownElements = [];\n\n return {\n initDropdowns: initDropdowns,\n openDropdown : openDropdown,\n slideDropdown: slideDropdown\n };\n\n function initDropdowns()\n {\n $( window ).on( 'orientationchange sizeChange', function()\n {\n if ( !$( \"input\" ).is( \":focus\" ) )\n {\n resetDropdowns( dropdownElements );\n resetDropdowns( closableDropdownElements );\n }\n } );\n }\n\n function resetDropdowns( dropdownList, event )\n {\n var $current;\n for ( var i = 0; i < dropdownList.length; i++ )\n {\n $current = $( dropdownList[i] );\n if ( !!event )\n {\n if ( $current.find( $( event.target ) ).length === 0\n && !$( \"input\" ).is( \":focus\" ) )\n {\n $current.removeClass( 'open' );\n $( 'html' ).unbind( \"click touchstart\", resetEvent );\n }\n }\n else\n {\n if ( !$( \"input\" ).is( \":focus\" ) )\n {\n $current.removeClass( 'open' );\n $( 'html' ).unbind( \"click touchstart\", resetEvent );\n }\n }\n }\n\n }\n\n function openDropdown( elem, alwaysClickable )\n {\n var $elem = $( elem );\n var $parent = $elem.parent();\n\n // case 1: xs || sm || ( touch && ( md || lg ) ) -> open/close via click on small devices, open/close via\n // css-hover on desktop, open/close via click on touch-desktop (e.g. top navigation)\n\n if ( !!alwaysClickable && ( MediaSize.isInterval( 'xs, sm' ) || ( Modernizr.touch && MediaSize.isInterval( 'md, lg' ) ) ) )\n {\n if ( !$parent.is( '.open' ) )\n {\n showDropdownHideOthers( $elem, $parent );\n\n // if href\n if ( !$elem.attr( 'href' ) )\n {\n avoidRedirectinStopPropagation( $parent.not( $elem ) );\n }\n }\n else\n {\n if ( !$elem.attr( 'href' ) )\n {\n // hide dropdown\n $parent.removeClass( 'open' );\n }\n }\n }\n\n // case 2: touch && ( md || lg ) -> open via 1st click on touch-desktop, return false (e.g. main navigation)\n\n if ( !alwaysClickable && ( Modernizr.touch && MediaSize.isInterval( 'md, lg' ) ) )\n {\n if ( !$parent.is( '.open' ) )\n {\n showDropdownHideOthers( $elem, $parent );\n\n avoidRedirectinStopPropagation( $parent );\n }\n else\n {\n // redirect to href if dropdown is already open\n // do nothing\n }\n }\n\n // handle \"close menu on click outside\"\n $( 'html' ).on( \"click touchstart\", resetEvent );\n }\n\n function showDropdownHideOthers( elem, parent )\n {\n var $parent = $( parent );\n\n // hide other dropdowns\n resetDropdowns( closableDropdownElements, elem );\n\n // remember opened dropdown\n if ( $.inArray( $parent[0], closableDropdownElements ) < 0 )\n {\n closableDropdownElements.push( $parent[0] );\n }\n\n // show dropdown\n $parent.addClass( 'open' );\n }\n\n function avoidRedirectinStopPropagation( elem )\n {\n var $elem = $( elem );\n\n // avoid redirecting\n pm.getRecentEvent().preventDefault();\n\n // avoid closing popup by clicking itself\n $elem.off( 'click' );\n $elem.on( 'click', function( e )\n {\n e.stopPropagation();\n } );\n }\n\n function slideDropdown( elem )\n {\n var $elem = $( elem );\n var $elemParent = $elem.parent();\n\n // size interval query is required since function is used on document ready to initial open active\n // navigation (on small devices)\n if ( MediaSize.isInterval( 'xs, sm' ) )\n {\n $elemParent.addClass( 'animating' );\n $elem.siblings( 'ul' ).slideToggle( 400, function()\n {\n if ( $elemParent.is( '.open' ) && !$( \"input\" ).is( \":focus\" ) )\n {\n $elemParent.removeClass( 'open' );\n $elem.siblings( 'ul' ).removeAttr( 'style' );\n $elemParent.removeClass( 'animating' );\n }\n else\n {\n $elemParent.addClass( 'open' );\n if ( $.inArray( $elemParent[0], dropdownElements ) < 0 )\n {\n dropdownElements.push( $elemParent[0] );\n }\n }\n } );\n }\n\n // handle \"close menu on click outside\"\n $( 'html' ).on( \"click touchstart\", resetEvent );\n }\n\n function resetEvent( event )\n {\n resetDropdowns( closableDropdownElements, event );\n }\n\n }, ['MediaSizeService'] );\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Redirect', function( MediaSizeService, NavigatorService )\n {\n\n return {\n to : to,\n toCheckoutTab: toCheckoutTab\n };\n\n function to( href )\n {\n if ( MediaSizeService.interval() != 'xs' )\n {\n if ( typeof href === 'string' && href.indexOf('/') == -1 && $( href ).length > 0 )\n {\n window.location.assign( $( href ).attr( 'href' ) );\n }\n else\n {\n window.location.assign( href );\n }\n }\n }\n\n function toCheckoutTab( tabID )\n {\n NavigatorService.goToID( tabID );\n }\n\n }, ['MediaSizeService', 'NavigatorService'] );\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Tab', function( MediaSize )\n {\n\n var tabGroups = {};\n\n return {\n showTab : showTab,\n initRemoteLabel: initRemoteLabel,\n initRemoteTab : initRemoteTab,\n showRemoteTab : showRemoteTab\n };\n\n function showTab( tabSelector )\n {\n $( tabSelector ).tab( 'show' );\n }\n\n function initRemoteLabel( $elem, tabID, groupID )\n {\n if ( !tabGroups[groupID] )\n {\n tabGroups[groupID] = new TabGroup();\n }\n\n if ( !tabGroups[groupID].getTab( tabID ) )\n {\n tabGroups[groupID].addTab( tabID );\n }\n\n tabGroups[groupID].getTab( tabID ).addLabel( $elem );\n }\n\n function initRemoteTab( $elem, tabID, groupID )\n {\n if ( !tabGroups[groupID] )\n {\n tabGroups[groupID] = new TabGroup();\n }\n\n if ( !tabGroups[groupID].getTab( tabID ) )\n {\n tabGroups[groupID].addTab( tabID );\n }\n\n tabGroups[groupID].getTab( tabID ).setContent( $elem );\n }\n\n function showRemoteTab( tabID, groupID, interval )\n {\n if ( MediaSize.isInterval( interval ) )\n {\n pm.getRecentEvent().preventDefault();\n\n if ( !!tabGroups[groupID] && !!tabGroups[groupID].getTab( tabID ) )\n {\n tabGroups[groupID].showTab( tabID );\n }\n\n }\n }\n\n function TabGroup()\n {\n var tabs = {};\n var activeTab;\n\n return {\n addTab : addTab,\n showTab : showTab,\n getTab : getTab,\n resetTabs: resetTabs\n };\n\n function addTab( tabID )\n {\n tabs[tabID] = new Tab( tabID );\n return tabs[tabID];\n }\n\n function showTab( tabID )\n {\n var zIndex = 0;\n if ( !!activeTab )\n {\n // activeTab is set\n zIndex = parseInt( activeTab.getContent().parent().css( 'zIndex' ) );\n activeTab.hide();\n activeTab.getContent().parent().css( 'zIndex', zIndex - 1 );\n }\n else\n {\n // activeTab not set before\n for ( var tab in tabs )\n {\n if ( !!tabs[tab].getContent() )\n {\n var currentZ = parseInt( tabs[tab].getContent().parent().css( 'zIndex' ) );\n if ( zIndex == 0 || currentZ < zIndex )\n {\n zIndex = currentZ;\n }\n tabs[tab].hide();\n }\n }\n\n for ( var tab in tabs )\n {\n if ( !!tabs[tab].getContent() )\n {\n tabs[tab].getContent().parent().css( 'zIndex', zIndex - 1 );\n }\n }\n\n $( window ).on( 'sizeChange', resetTabs );\n }\n\n activeTab = tabs[tabID];\n activeTab.getContent().parent().css( 'zIndex', zIndex );\n activeTab.show();\n }\n\n function getTab( tabID )\n {\n return tabs[tabID];\n }\n\n function resetTabs()\n {\n for ( var tab in tabs )\n {\n if ( !!tabs[tab].getContent() )\n {\n tabs[tab].show();\n }\n }\n\n activeTab = null;\n }\n }\n\n function Tab( id )\n {\n var $content;\n var $labels = [];\n var tabID = id;\n\n return {\n addLabel : addLabel,\n setContent: setContent,\n getContent: getContent,\n getID : getID,\n show : show,\n hide : hide\n };\n\n function getID()\n {\n return tabID;\n }\n\n function addLabel( label )\n {\n $labels.push( label );\n return this;\n }\n\n function setContent( content )\n {\n $content = content;\n return this;\n }\n\n function getContent()\n {\n return $content;\n }\n\n function show()\n {\n for ( var i = 0; i < $labels.length; i++ )\n {\n $labels[i].addClass( 'active' );\n }\n\n if ( !!$content )\n {\n $content.show().addClass( 'in' );\n }\n\n }\n\n function hide()\n {\n for ( var i = 0; i < $labels.length; i++ )\n {\n $labels[i].removeClass( 'active' );\n }\n\n if ( !!$content )\n {\n $content.hide().removeClass( 'in' );\n }\n }\n }\n\n }, ['MediaSizeService'] );\n})( jQuery, PlentyFramework );\n/**\n * Add fancy ui modifications - the visual stuff - here.\n * Respond functionality like 'event':UI.myFunctionality(currentElement)\n *\n * Example:\n * \n *\n */\n(function( $, pm )\n{\n pm.directive( 'UI', function( MediaSizeService, SocialShareService, UIFactory )\n {\n // elements to calculate height.\n var equalHeightElementList = [];\n var toTopButtonList = [];\n\n return {\n initUIWindowEvents : initUIWindowEvents,\n showWaitscreen : showWaitscreen,\n hideWaitscreen : hideWaitscreen,\n addContentPageSlider: addContentPageSlider,\n equalHeight : equalHeight,\n initToTop : initToTop,\n initLazyload : initLazyload,\n initSlideToggle : initSlideToggle,\n slideDown : slideDown,\n slideUp : slideUp,\n slideToggle : slideToggle,\n toggleHideShow : toggleHideShow,\n toggleSocialShare : toggleSocialShare,\n toggleClass : toggleClass,\n addClass : addClass,\n removeClass : removeClass\n };\n\n function initUIWindowEvents()\n {\n // resize elements on window size change.\n $( window ).on( 'sizeChange contentChanged', function()\n {\n fireEqualHeight();\n } );\n\n $( window ).on( \"scroll resize\", function()\n {\n if ( toTopButtonList.length > 0 )\n {\n if ( $( document ).scrollTop() > 100 )\n {\n doToArrayElements( toTopButtonList, \"addClass\", \"visible\" );\n }\n else\n {\n doToArrayElements( toTopButtonList, \"removeClass\", \"visible\" );\n }\n }\n } );\n }\n\n /**\n * Display waitscreen on page e.g. for requests.\n * Use with care and don't forget to hide waitscreen, if your calls are done or broke!!\n */\n function showWaitscreen()\n {\n UIFactory.showWaitscreen();\n }\n\n /**\n * Just hide the waitscreen.\n * @param forceClose\n */\n function hideWaitscreen( forceClose )\n {\n UIFactory.hideWaitscreen( forceClose );\n }\n\n /**\n * Adds content page slider (owlCarousel)\n *\n * usage:\n *
    \n *
    \n * ...\n *
    \n *
    \n * ...\n *
    \n * ...\n *
    \n *\n * Legacy directive selector: data-plenty=\"contentpageSlider\"\n *\n * @param elem\n */\n function addContentPageSlider( elem )\n {\n $( elem ).owlCarousel( {\n navigation : true,\n navigationText : false,\n slideSpeed : 1000,\n paginationSpeed: 1000,\n singleItem : true,\n autoPlay : 6000,\n stopOnHover : true,\n afterMove : function( current )\n {\n $( current ).find( '[data-plenty-rel=\"lazyload\"]' ).trigger( 'appear' );\n }\n } );\n }\n\n /**\n * Equal Box height\n * Calculates equal box height for chosen elements.\n *\n * Legacy directive selector: data-plenty-equal\n *\n * @param elem\n * @param elementExists - default false\n */\n function equalHeight( elem, mediaSizes, elementExists )\n {\n var $elem = $( elem );\n var maxHeight = 0;\n var $equalTarget = {};\n var $equalTargetList = $elem.find( '[data-plenty-rel=\"equal-target\"]' ).length > 0 ? $elem.find( '[data-plenty-rel=\"equal-target\"]' ) : $elem.children();\n\n // if element wasn't pushed before.\n if ( elementExists !== true )\n {\n equalHeightElementList.push( elem );\n }\n\n for ( var i = $equalTargetList.length; i >= 0; i-- )\n {\n $equalTarget = $( $equalTargetList[i] );\n $equalTarget.css( 'height', '' );\n\n if ( $equalTarget.outerHeight( true ) > maxHeight )\n {\n maxHeight = $equalTarget.outerHeight( true );\n }\n }\n\n if ( !mediaSizes || MediaSizeService.isInterval( mediaSizes ) )\n {\n $equalTargetList.height( maxHeight );\n }\n }\n\n /**\n * Scroll page to top.\n * Just add without events.\n *\n * Legacy directive selector: data-plenty=\"toTop\"\n *\n * @param elem\n */\n function initToTop( elem )\n {\n var $elem = $( elem );\n\n $elem.click( function()\n {\n $( 'html, body' ).animate( {\n scrollTop: 0\n }, 400 );\n return false;\n } );\n\n if ( !!$.inArray( $elem, toTopButtonList ) )\n {\n toTopButtonList.push( $elem );\n }\n }\n\n /**\n * lazy load on ready.\n *\n * Legacy directive selector: img[data-plenty-lazyload]\n *\n * @param elem\n */\n function initLazyload( elem, effect )\n {\n var $elem = $( elem );\n\n $elem.lazyload( {\n effect: effect\n } );\n if ( $elem.is( 'img' ) )\n {\n $elem.on( 'loaded', function()\n {\n $elem.css( 'display', 'inline-block' );\n } );\n }\n }\n\n /**\n * Toggle show and hide animation.\n *\n * Legacy directive selector: data-plenty=\"openCloseToggle\"\n *\n * @param elem\n */\n function toggleHideShow( elem )\n {\n\n console.log( elem );\n\n var $elem = $( elem );\n var $elemParent = $elem.parent();\n\n $elemParent.addClass( 'animating' );\n $elem.siblings( 'ul' ).slideToggle( 200, function()\n {\n if ( $elemParent.is( '.open' ) )\n {\n $elemParent.removeClass( 'open' );\n }\n else\n {\n $elemParent.addClass( 'open' );\n }\n $elem.siblings( 'ul' ).removeAttr( 'style' );\n $elemParent.removeClass( 'animating' );\n } );\n }\n\n /**\n * Toggle target content on click.\n * Bind to checked-/ unchecked-property of radio buttons\n *\n * Legacy directive selector: data-plenty-slidetoggle\n *\n * @param elem\n */\n function initSlideToggle( elem, checked )\n {\n var $elem = $( elem );\n var $targetElement = $( $elem.attr( 'data-plenty-rel' ) );\n\n if ( $elem.is( 'input[type=\"radio\"]' ) )\n {\n // is radio button\n var $radioGroupList = $( 'input[type=\"radio\"][name=\"' + ( $elem.attr( 'name' ) ) + '\"]' );\n var visibleOnChecked = !checked || checked == 'checked';\n\n $radioGroupList.change( function()\n {\n var $self = $( this );\n $targetElement.parents( '[data-plenty-rel=\"equal-target\"]' ).css( 'height', 'auto' );\n\n if ( $self.is( ':checked' ) && $self[0] === $elem[0] && visibleOnChecked == true )\n {\n // checked\n $targetElement.slideDown( 400, function()\n {\n fireEqualHeight();\n } );\n }\n else\n {\n // unchecked (since other radio button has been checked)\n $targetElement.slideUp( 400, function()\n {\n fireEqualHeight();\n } );\n }\n } );\n }\n else\n {\n // is not radio button\n $elem.click( function()\n {\n //$targetElement.parents( '[data-plenty-rel=\"equal-target\"]' ).css( 'height', 'auto' );\n\n $elem.addClass( 'animating' );\n $targetElement.slideToggle( 400, function()\n {\n $elem.removeClass( 'animating' );\n $elem.toggleClass( 'active' );\n fireEqualHeight();\n } );\n } );\n }\n }\n\n function slideDown( target, duration )\n {\n slideAction( $( target ), duration, 'slideDown' );\n }\n\n function slideUp( target, duration )\n {\n slideAction( $( target ), duration, 'slideUp' );\n }\n\n function slideToggle( target, duration )\n {\n slideAction( $( target ), duration, 'slideToggle' );\n }\n\n function slideAction( $target, duration, callbackString )\n {\n duration = duration || 400;\n $target.parents( '[data-plenty-rel=\"equal-target\"]' ).css( 'height', 'auto' );\n $target[callbackString]( duration, function()\n {\n fireEqualHeight();\n } );\n }\n\n /**\n * TODO check comment\n * Social Share Activation\n * Activate and load share-buttons manually by clicking a separate button\n * Usage / data-attributes:\n *
    \n * Will be used to activate the service set in\n * data-plenty-social=\"\"\n * Will be replaced with loaded share button\n *
    \n *\n * possible values for data-plenty-social:\n * \"facebook-like\" : Load Facebooks \"Like\"-Button\n * \"facebook-recommend\" : Load Facebooks \"Recommend\"-Button\n * \"twitter\" : Load Twitter Button\n * \"google-plus\" : Load google \"+1\"-Button\n *\n * Additional Tooltips\n * You can extend the parent element with a (bootstrap) tooltip by adding data-toggle=\"tooltip\" and\n * title=\"TOOLTIP CONTENT\" Tooltip will be destroyed after activating a social service\n * (!) Requires bootstrap.js\n *\n * Legacy directive selector: data-plenty-social\n *\n * @param elem\n */\n function toggleSocialShare( elem, socialShareService )\n {\n var $elem = $( elem );\n var $toggle = $elem.find( '[data-plenty-rel=\"social-switch\"]' );\n\n // append container to put / delete service.html\n $elem.append( '
    ' );\n\n // add \"off\" class to switch, if neither \"off\" or \"on\" is set\n // replaced hasClass() with is() benchmark: http://jsperf.com/hasclasstest\n if ( !$toggle.is( 'off, on' ) )\n {\n $toggle.addClass( 'off' );\n }\n\n // toggle switch\n $toggle.on( 'click', function()\n {\n if ( $toggle.hasClass( 'off' ) )\n {\n // TODO remove bootstrap dependency\n if ( $elem.attr( \"data-toggle\" ) == \"tooltip\" )\n {\n $elem.tooltip( 'destroy' )\n }\n $toggle.removeClass( 'off' ).addClass( 'on' );\n // hide dummy button\n $elem.find( '[data-plenty-rel=\"social-placeholder\"]' ).hide();\n // load HTML defined in 'api'\n $elem.find( '.social-container' ).append( SocialShareService.getSocialService( socialShareService ) );\n }\n // do not disable social medias after activation\n } );\n }\n\n /**\n * Toggle Class\n * toggle style-classes on click\n * Usage / data-attribute:\n *
    \n * target : jQuery selector to toggle the class at.\n * class : class(es) to toggle at target element\n * media : only toggle class on given media sizes (optional)\n *\n * (!) using data-plenty-toggle on -elements will prevent redirecting to href=\"\"\n *\n * Legacy directive selector: data-plenty-toggle\n *\n * @param cssClass\n * @param target\n * @param interval\n */\n function toggleClass( cssClass, target, interval )\n {\n var $target = $( target );\n /* FIXME\n * Callisto 3.1 Design adaption:\n * NavigationCategoriesList\n * Line 8\n * BEFORE:\n *
  • \n * AFTER:\n *
  • \n *\n * Line 10\n * BEFORE:\n * \n * AFTER:\n * \n *\n * */\n if ( $target.parents( \".navbar-main\" ).length > 0 )\n {\n var $elem = $target.children( \"span\" );\n pm.directives[\"MobileDropdown\"].slideDropdown( $elem );\n return true;\n }\n\n if ( !!target && !!cssClass && ( !interval || MediaSizeService.isInterval( interval ) ) )\n {\n var e = pm.getRecentEvent();\n if ( !!e )\n {\n e.preventDefault();\n }\n\n $target.toggleClass( cssClass );\n return false;\n }\n }\n\n function addClass( cssClass, target, interval )\n {\n if ( !!target && !!cssClass && ( !interval || MediaSizeService.isInterval( interval ) ) )\n {\n var e = pm.getRecentEvent();\n if ( !!e )\n {\n e.preventDefault();\n }\n\n $( target ).addClass( cssClass );\n return false;\n }\n }\n\n function removeClass( cssClass, target, interval )\n {\n if ( !!target && !!cssClass && ( !interval || MediaSizeService.isInterval( interval ) ) )\n {\n var e = pm.getRecentEvent();\n if ( !!e )\n {\n e.preventDefault();\n }\n\n $( target ).removeClass( cssClass );\n return false;\n }\n }\n\n /*\n ##### PRIVATE FUNCTIONS ######\n */\n\n function fireEqualHeight()\n {\n for ( var i = equalHeightElementList.length - 1; i >= 0; i-- )\n {\n equalHeight( equalHeightElementList[i], '', true );\n }\n }\n\n function doToArrayElements( array, func, params )\n {\n for ( var i = array.length - 1; i >= 0; i-- )\n {\n array[i][func]( params );\n }\n }\n\n }, ['MediaSizeService', 'SocialShareService', 'UIFactory'] );\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Validator', function( ValidationService )\n {\n\n return {\n validate: validate\n };\n\n function validate( form, errorClass )\n {\n return ValidationService.validate( form, errorClass );\n }\n\n }, ['ValidationService'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( $, pm )\n{\n\n /**\n * Handles requests to ReST API. Provides a {{#crossLink \"APIFactory/handleError:method\"}}default\n * error-handling{{/crossLink}}. Request parameters will be parsed to json internally
    \n * Requires:\n *
      \n *
    • {{#crossLink \"UIFactory\"}}UIFactory{{/crossLink}}
    • \n *
    \n * @class APIFactory\n * @static\n */\n pm.factory( 'APIFactory', function( UI, Modal )\n {\n\n var sessionExpirationTimeout = null;\n $( document ).ready( function()\n {\n renewLoginSession();\n } );\n\n return {\n get : _get,\n post : _post,\n put : _put,\n delete: _delete,\n idle : _idle\n };\n\n function renewLoginSession()\n {\n if ( !pm.getGlobal( 'LoginSession' ) )\n {\n return;\n }\n\n if ( !!sessionExpirationTimeout )\n {\n clearTimeout( sessionExpirationTimeout );\n }\n\n sessionExpirationTimeout = setTimeout( function()\n {\n $( window ).trigger( 'login-expired' );\n\n if ( pm.getGlobal( 'PageDesign' ) === \"Checkout\" )\n {\n Modal.prepare()\n .setTitle( pm.translate( 'Your session has expired.' ) )\n .setContent( pm.translate( 'Please log in again to continue shopping.' ) )\n .setLabelDismiss( null )\n .setLabelConfirm( pm.translate( 'OK' ) )\n .onConfirm( function()\n {\n window.location.assign( '/' );\n } )\n .onDismiss( function()\n {\n window.location.assign( '/' );\n } )\n .show();\n }\n\n }, pm.getGlobal( 'LoginSessionExpiration' ) );\n }\n\n /**\n * Is called by default if a request failed.
    \n * Can be prevented by setting the requests last parameter to false.\n *\n * @function handleError\n * @private\n *\n * @param {object} jqXHR
    jQuery\n * deferred Object\n */\n function handleError( jqXHR )\n {\n try\n {\n var responseText = $.parseJSON( jqXHR.responseText );\n UI.printErrors( responseText.error.error_stack );\n }\n catch ( e )\n {\n UI.throwError( jqXHR.status, jqXHR.statusText );\n }\n }\n\n /**\n * Sends a GET request to ReST-API\n *\n * @function get\n *\n * @param {string} url The URL to send the request to\n * @param {object} params The data to append to requests body. Will be converted to JSON\n * internally\n * @param {boolean} [ignoreErrors=false] disable/ enable defaults error handling\n * @param {boolean} [runInBackground=false] show wait screen while request is in progress.\n * @return {object} jQuery\n * deferred Object\n */\n function _get( url, params, ignoreErrors, runInBackground, sync )\n {\n\n if ( !runInBackground )\n {\n UI.showWaitScreen();\n }\n\n return $.ajax(\n url,\n {\n type : 'GET',\n data : params,\n dataType: 'json',\n async : !sync,\n error : function( jqXHR )\n {\n if ( !ignoreErrors )\n {\n handleError( jqXHR )\n }\n }\n }\n ).always( function()\n {\n if ( !runInBackground )\n {\n UI.hideWaitScreen();\n }\n renewLoginSession();\n } );\n\n }\n\n /**\n * Sends a POST request to ReST-API\n *\n * @function post\n *\n * @param {string} url The URL to send the request to\n * @param {object} data The data to append to requests body. Will be converted to JSON\n * internally\n * @param {boolean} [ignoreErrors=false] disable/ enable defaults error handling\n * @param {boolean} [runInBackground=false] show wait screen while request is in progress.\n * @return {object} jQuery\n * deferred Object\n */\n function _post( url, data, ignoreErrors, runInBackground )\n {\n\n var params = {\n type : 'POST',\n dataType: 'json',\n error : function( jqXHR )\n {\n if ( !ignoreErrors )\n {\n handleError( jqXHR )\n }\n }\n };\n\n if ( !!data && data.isFile )\n {\n params.cache = data.cache;\n params.processData = data.processData;\n params.data = data.data;\n params.contentType = false;\n }\n else\n {\n params.data = JSON.stringify( data );\n params.contentType = 'application/json';\n }\n\n if ( !runInBackground )\n {\n UI.showWaitScreen();\n }\n\n return $.ajax(\n url, params\n ).always( function()\n {\n if ( !runInBackground )\n {\n UI.hideWaitScreen();\n }\n renewLoginSession();\n } );\n }\n\n /**\n * Sends a PUT request to ReST-API\n *\n * @function put\n *\n * @param {string} url The URL to send the request to\n * @param {object} data The data to append to requests body. Will be converted to JSON\n * internally\n * @param {boolean} [ignoreErrors=false] disable/ enable defaults error handling\n * @param {boolean} [runInBackground=false] show wait screen while request is in progress.\n * @return {object} jQuery\n * deferred Object\n */\n function _put( url, data, ignoreErrors, runInBackground )\n {\n\n if ( !runInBackground )\n {\n UI.showWaitScreen();\n }\n\n return $.ajax(\n url,\n {\n type : 'PUT',\n data : JSON.stringify( data ),\n dataType : 'json',\n contentType: 'application/json',\n error : function( jqXHR )\n {\n if ( !ignoreErrors )\n {\n handleError( jqXHR )\n }\n }\n }\n ).always( function()\n {\n if ( !runInBackground )\n {\n UI.hideWaitScreen();\n }\n renewLoginSession();\n } );\n\n }\n\n /**\n * Sends a DELETE request to ReST-API\n *\n * @function delete\n *\n * @param {string} url The URL to send the request to\n * @param {object} data The data to append to requests body. Will be converted to JSON\n * internally\n * @param {boolean} [ignoreErrors=false] disable/ enable defaults error handling\n * @param {boolean} [runInBackground=false] show wait screen while request is in progress.\n * @returns {object} jQuery\n * deferred Object\n */\n function _delete( url, data, ignoreErrors, runInBackground )\n {\n\n if ( !runInBackground )\n {\n UI.showWaitScreen();\n }\n\n return $.ajax(\n url,\n {\n type : 'DELETE',\n data : JSON.stringify( data ),\n dataType : 'json',\n contentType: 'application/json',\n error : function( jqXHR )\n {\n if ( !ignoreErrors )\n {\n handleError( jqXHR )\n }\n }\n }\n ).always( function()\n {\n if ( !runInBackground )\n {\n UI.hideWaitScreen();\n }\n renewLoginSession();\n } );\n\n }\n\n /**\n * Get a idle request doing nothing for chaining methods\n * @returns {object} jQuery\n * deferred Object\n */\n function _idle()\n {\n return $.Deferred().resolve();\n }\n\n }, ['UIFactory', 'ModalFactory'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( pm )\n{\n\n /**\n * Provide methods for receiving layout containers, layout parameters\n * or category content from API
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    \n * @class CMSFactory\n * @static\n */\n pm.factory( 'CMSFactory', function( API )\n {\n\n return {\n getContainer : getContainer,\n getParams : getParams,\n getCategoryContent: getCategoryContent\n };\n\n /**\n * Prepare the request to receive HTML-Content from CMS\n * @function getContainer\n * @param {string} containerName The Layoutcontainer to receive.\n * @param {object} params Additional GET-parameters.\n * @returns {object} The prepared request. Call .from( layoutGroup ) to specify the location in\n * the CMS\n * (e.g. 'Checkout')\n * @example\n * CMSFactory.getContainer( 'CheckoutTotals' ).from( 'Checkout' )\n * .done(function( response ) {\n * // container content\n * var html = response.data[0]\n * });\n */\n function getContainer( containerName, params )\n {\n\n function from( layoutGroup )\n {\n return API.get( '/rest/' + layoutGroup.toLowerCase() + '/container_' + containerName.toLowerCase() + '/', params );\n }\n\n return {\n from: from\n }\n\n }\n\n /**\n * Prepare the request to receive Layout parameters for a template\n * @function getParams\n * @param {string} containerName The Layoutcontainer to receive the parameteres of.\n * @param {object} params Additional GET-parameters.\n * @returns {object} The prepared request. Call .from( layoutGroup ) to specify the\n * location in the CMS\n * (e.g. 'ItemView')\n * @example\n * CMSFactory.getParams( 'BasketItemsList' ).from( 'ItemView' )\n * .done(function( response ) {\n * // BasketItems\n * var items = response.data;\n * });\n */\n function getParams( containerName, params )\n {\n\n function from( layoutGroup )\n {\n return API.get( '/rest/' + layoutGroup.toLowerCase() + '/' + containerName.toLowerCase() + '/', params );\n }\n\n return {\n from: from\n }\n }\n\n /**\n * Get the content of a category specified by its ID\n * @function getCategoryContent\n * @param {number} categoryID The ID of the category to get the content from\n * @returns {object} jQuery deferred\n * Object\n */\n function getCategoryContent( categoryID )\n {\n return API.get( '/rest/categoryview/categorycontentbody/?categoryID=' + categoryID );\n }\n\n }, ['APIFactory'] );\n}( PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( pm )\n{\n\n /**\n * Holds checkout data for global access and provides methods\n * for reloading content dynamically-
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CMSFactory\"}}CMSFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"UIFactory\"}}UIFactory{{/crossLink}}
    • \n *
    \n * @class CheckoutFactory\n * @static\n */\n pm.factory( 'CheckoutFactory', function( API, CMS, UI )\n {\n\n // data received from ReST API\n var checkoutData;\n\n // instance wrapped checkout object for global access\n var checkout;\n\n return {\n getCheckout : getCheckout,\n setCheckout : setCheckout,\n loadCheckout : loadCheckout,\n reloadContainer : reloadContainer,\n reloadCatContent : reloadCatContent,\n reloadItemContainer: reloadItemContainer\n };\n\n function Checkout()\n {\n return checkoutData;\n }\n\n /**\n * Returns instance of wrapped checkout object\n * @function getCheckout\n * @returns {Checkout} Instance of checkout object\n */\n function getCheckout( copy )\n {\n if ( !checkout || !checkoutData )\n {\n loadCheckout( true );\n }\n\n if ( !!copy )\n {\n return $.extend( true, {}, checkoutData );\n }\n return checkout;\n }\n\n /**\n * Receive global checkout data from ReST-API\n * @function loadCheckout\n * @return {object} jQuery deferred\n * Object\n */\n function loadCheckout( sync )\n {\n\n return API.get( '/rest/checkout/', null, false, false, sync )\n .done( function( response )\n {\n if ( !!response )\n {\n checkoutData = response.data;\n checkout = new Checkout();\n }\n else\n {\n UI.throwError( 0, 'Could not receive checkout data [GET \"/rest/checkout/\" receives null value]' );\n }\n } );\n }\n\n /**\n * Update checkout data on server\n * @function setCheckout\n * @return {object} jQuery deferred\n * Object\n */\n function setCheckout()\n {\n\n return API.put( '/rest/checkout', checkout )\n .done( function( response )\n {\n if ( !!response )\n {\n checkoutData = response.data;\n checkout = new Checkout();\n }\n else\n {\n UI.throwError( 0, 'Could not receive checkout data [GET \"/rest/checkout/\" receives null value]' );\n }\n } );\n\n }\n\n /**\n * Get layout container from server and replace received HTML\n * in containers marked with data-plenty-checkout-template=\"...\"\n * @function reloadContainer\n * @param {string} container Name of the template to load from server\n * @return {object} jQuery deferred\n * Object\n */\n function reloadContainer( container )\n {\n\n return CMS.getContainer( \"checkout\" + container ).from( 'checkout' )\n .done( function( response )\n {\n $( '[data-plenty-checkout-template=\"' + container + '\"]' )\n .each( function( i, elem )\n {\n $( elem ).html( response.data[0] );\n pm.getInstance().bindDirectives( elem );\n $( window ).trigger( 'contentChanged' );\n } );\n } );\n }\n\n /**\n * Get category content from server and replace received HTML\n * in containers marked with data-plenty-checkout-catcontent=\"...\"\n * @function reloadCatContent\n * @param {number} catId ID of the category to load content (description 1) from server\n * @return {object} jQuery deferred\n * Object\n * @deprecated\n */\n function reloadCatContent( catId )\n {\n\n return CMS.getCategoryContent( catId )\n .done( function( response )\n {\n $( '[data-plenty-checkout-catcontent=\"' + catId + '\"]' )\n .each( function( i, elem )\n {\n $( elem ).html( response.data[0] );\n pm.getInstance().bindDirectives( elem );\n $( window ).trigger( 'contentChanged' );\n\n } );\n } );\n\n }\n\n /**\n * Get layout container from server and replace received HTML\n * in containers marked with data-plenty-itemview-template=\"...\"\n * @function reloadItemContainer\n * @param {string} container Name of the (item view) template to load from server\n * @return {object} jQuery deferred\n * Object\n */\n function reloadItemContainer( container )\n {\n\n return CMS.getContainer( 'itemview' + container ).from( 'itemview' )\n .done( function( response )\n {\n $( '[data-plenty-itemview-template=\"' + container + '\"]' )\n .each( function( i, elem )\n {\n $( elem ).html( response.data[0] );\n pm.getInstance().bindDirectives( elem );\n $( window ).trigger( 'contentChanged' );\n\n } );\n } );\n\n }\n\n }, ['APIFactory', 'CMSFactory', 'UIFactory'] );\n}( PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( $, pm )\n{\n\n /**\n * Provides methods for creating and displaying modal popups.\n * @class ModalFactory\n * @static\n */\n pm.factory( 'ModalFactory', function()\n {\n\n return {\n prepare: prepare,\n isModal: isModal\n };\n\n /**\n * Detect if given html contains a valid modal\n * @function isModal\n * @param {string} html\n * @returns {boolean}\n */\n function isModal( html )\n {\n return PlentyFramework.partials.Modal.isModal( html );\n }\n\n /**\n * Create a new Instance of {{#crossLink \"ModalFactory.Modal\"}}Modal{{/crossLink}}\n * @function prepare\n * @returns {Modal}\n */\n function prepare( selector )\n {\n return new Modal( selector );\n }\n\n /**\n * Holds configuration of a modal and provides methods for displaying and hiding the modal\n * @class Modal\n * @for ModalFactory\n * @returns {Modal}\n * @constructor\n */\n function Modal( selector )\n {\n\n var modal = this;\n modal.selector = selector;\n\n /**\n * The title of the modal\n * @attribute title\n * @type {string}\n * @private\n * @default \"\"\n */\n modal.title = '';\n\n modal.cssClass = '';\n\n /**\n * The content of the modal\n * @attribute content\n * @type {string}\n * @private\n * @default \"\"\n */\n modal.content = '';\n\n /**\n * The content of the dismiss-button\n * @attribute labelDismiss\n * @type {string}\n * @private\n * @default \"Abbrechen\"\n */\n modal.labelDismiss = pm.translate( \"Cancel\" );\n\n /**\n * the label of the confirmation button\n * @attribute labelConfirm\n * @type {string}\n * @private\n * @default \"Bestätigen\"\n */\n modal.labelConfirm = pm.translate( \"Confirm\" );\n\n /**\n * Callback when modal is confirmed by clicking confirmation button.\n * Modal will not be dismissed if callback returns false.\n * @attribute onConfirm\n * @type {function}\n * @private\n * @default function() {}\n */\n modal.onConfirm = function()\n {\n };\n\n /**\n * Callback when modal is dismissed by closing the modal\n * @attribute onDismiss\n * @type {function}\n * @private\n * @default function() {}\n */\n modal.onDismiss = function()\n {\n };\n\n /**\n * jQuery selector of the container element to display the modal in.\n * @attribute container\n * @type {string}\n * @private\n * @default \"body\"\n */\n modal.container = 'body';\n\n /**\n * Timeout to close the modal automatically. Set <0 to disable.\n * @attribute timeout\n * @type {number}\n * @private\n * @default -1\n */\n modal.timeout = -1;\n\n modal.hide = hide;\n modal.startTimeout = startTimeout;\n modal.stopTimeout = stopTimeout;\n modal.pauseTimeout = pauseTimeout;\n modal.continueTimeout = continueTimeout;\n\n var bsModal;\n var timeout, interval;\n var timeRemaining, timeStart;\n var paused = false;\n\n return {\n setTitle : setTitle,\n setClass : setClass,\n setContent : setContent,\n setContainer : setContainer,\n setLabelConfirm: setLabelConfirm,\n setLabelDismiss: setLabelDismiss,\n onConfirm : onConfirm,\n onDismiss : onDismiss,\n setTimeout : setTimeout,\n show : show,\n hide : hide\n };\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/title:attribute}}title{{/crossLink}} of the modal\n * @function setTitle\n * @param {string} title The title\n * @returns {Modal} Modal object for chaining methods\n */\n function setTitle( title )\n {\n modal.title = title;\n return this;\n }\n\n function setClass( cssClass )\n {\n modal.cssClass = cssClass;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/content:attribute}}content{{/crossLink}} of the modal\n * @function setContent\n * @param {string} content The content\n * @returns {Modal} Modal object for chaining methods\n */\n function setContent( content )\n {\n modal.content = content;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/labelConfirm:attribute}}label of the confirmation\n * button{{/crossLink}} of the modal\n * @function setLabelConfirm\n * @param {string} label The label\n * @returns {Modal} Modal object for chaining methods\n */\n function setLabelConfirm( label )\n {\n modal.labelConfirm = label;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/labelDismiss:attribute}}label if the dismiss\n * button{{/crossLink}} of the modal\n * @function setLabelDismiss\n * @param {string} label The label\n * @returns {Modal} Modal object for chaining methods\n */\n function setLabelDismiss( label )\n {\n modal.labelDismiss = label;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/onConfirm:attribute}}confirmation callback{{/crossLink}} of the\n * modal\n * @function onConfirm\n * @param {function} callback The callback if modal is confirmed\n * @returns {Modal} Modal object for chaining methods\n */\n function onConfirm( callback )\n {\n modal.onConfirm = callback;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/onDismiss:attribute}}dismiss callback{{/crossLink}} of the modal\n * @function onDismiss\n * @param {function} callback The callback if modal is dismissed\n * @returns {Modal} Modal object for chaining methods\n */\n function onDismiss( callback )\n {\n modal.onDismiss = callback;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/container:attribute}}container{{/crossLink}} of the modal\n * @function setContainer\n * @param {string} container The jQuery selector of the container to display the modal in\n * @returns {Modal} Modal object for chaining methods\n */\n function setContainer( container )\n {\n modal.container = container;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/timeout:attribute}}timeout{{/crossLink}} of the modal\n * @function setTimeout\n * @param {number} timeout The timeout to close the modal automatically. Set <0 to disable\n * @returns {Modal} Modal object for chaining methods\n */\n function setTimeout( timeout )\n {\n modal.timeout = timeout;\n return this;\n }\n\n /**\n * Inject modal data in default template if not template is given\n * and display the modal inside the configured container.
    \n * Start timer to hide the modal automatically if timeout is set.\n * @function show\n */\n function show()\n {\n if( !!modal.selector )\n {\n bsModal = $( modal.selector );\n }\n else\n {\n if ( isModal( modal.content ) )\n {\n bsModal = PlentyFramework.partials.Modal.getModal( modal.content );\n }\n else\n {\n bsModal = $( PlentyFramework.compileTemplate( 'modal/modal.html', modal ) );\n }\n\n $( modal.container ).append( bsModal );\n\n // append additional scripts executable\n var scripts = $( modal.content ).filter( 'script' );\n if ( scripts.length > 0 )\n {\n scripts.each( function( i, script )\n {\n var element = document.createElement( 'script' );\n element.type = 'text/javascript';\n element.innerHTML = $( script ).text();\n $( modal.container ).append( element );\n } );\n }\n }\n\n // bind callback functions\n PlentyFramework.partials.Modal.init( bsModal, modal );\n bsModal.find( '[data-plenty-modal=\"confirm\"]' ).click( function()\n {\n var close = modal.onConfirm();\n\n if ( typeof close == \"undefined\" )\n {\n close = true;\n }\n\n if ( close )\n {\n hide( true );\n }\n } );\n\n PlentyFramework.partials.Modal.show( bsModal );\n\n if ( modal.timeout > 0 )\n {\n startTimeout();\n }\n\n }\n\n /**\n * Hide the modal.\n * @function hide\n * @param {boolean} confirmed Flag indicating of modal is closed by confirmation button or dismissed\n */\n function hide( confirmed )\n {\n PlentyFramework.partials.Modal.hide( bsModal );\n\n if ( !confirmed )\n {\n modal.onDismiss();\n }\n }\n\n /**\n * Start the configured timeout initially\n * @function startTimeout\n * @private\n */\n function startTimeout()\n {\n timeRemaining = modal.timeout;\n timeStart = (new Date()).getTime();\n\n timeout = window.setTimeout( function()\n {\n window.clearInterval( interval );\n hide();\n }, modal.timeout );\n\n bsModal.find( '[data-plenty-modal=\"timer\"]' ).text( timeRemaining / 1000 );\n interval = window.setInterval( function()\n {\n if ( !paused )\n {\n var secondsRemaining = timeRemaining - (new Date()).getTime() + timeStart;\n secondsRemaining = Math.round( secondsRemaining / 1000 );\n bsModal.find( '[data-plenty-modal=\"timer\"]' ).text( secondsRemaining );\n }\n }, 1000 )\n }\n\n /**\n * Pause the timeout (e.g. on hover)\n * @function pauseTimeout\n * @private\n */\n function pauseTimeout()\n {\n paused = true;\n timeRemaining -= (new Date()).getTime() - timeStart;\n window.clearTimeout( timeout );\n }\n\n /**\n * Continue paused timeout\n * @function continueTimeout\n * @private\n */\n function continueTimeout()\n {\n paused = false;\n timeStart = (new Date()).getTime();\n timeout = window.setTimeout( function()\n {\n hide();\n window.clearInterval( interval );\n }, timeRemaining );\n }\n\n /**\n * Stop timeout. Stopped timeouts cannot be continued.\n * @function stopTimeout\n * @private\n */\n function stopTimeout()\n {\n window.clearTimeout( timeout );\n window.clearInterval( interval );\n }\n\n }\n\n } );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( $, pm )\n{\n\n /**\n * Displaying error messages and handling wait screen\n * @class UIFactory\n * @static\n */\n pm.factory( 'UIFactory', function()\n {\n /**\n * Increased/ decreased when showing/ hiding wait screen to avoid stacking\n * multiple instances of overlays.\n * @attribute waitScreenCount\n * @private\n * @type {number}\n * @default 0\n */\n var waitScreenCount = 0;\n var waitScreen;\n var errorPopup = null;\n\n return {\n throwError : throwError,\n printErrors : printErrors,\n showWaitScreen: showWaitScreen,\n hideWaitScreen: hideWaitScreen\n };\n\n /**\n * Display a single error message.\n * @function throwError\n * @param {number} code A code identifying this error\n * @param {string} msg The error message to display\n */\n function throwError( code, msg )\n {\n printErrors( [{code: code, message: msg}] );\n }\n\n /**\n * Wrap error messages in error popup, if popup doesn't already contain this error\n * If popup is already visible, append new errors to popup's inner HTML\n * otherwise create new popup\n * @function printErrors\n * @param {Array} errorMessages A list of errors to display\n */\n function printErrors( errorMessages )\n {\n\n // create error-popup if not exist\n if ( !errorPopup || $( 'body' ).has( errorPopup ).length <= 0 )\n {\n errorPopup = $( pm.compileTemplate( 'error/errorPopup.html' ) );\n $( 'body' ).append( errorPopup );\n pm.partials.Error.init( errorPopup );\n }\n\n $.each( errorMessages, function( key, error )\n {\n // add additional error, if not exist.\n pm.partials.Error.addError( errorPopup, $( pm.compileTemplate( 'error/errorMessage.html', error ) ) );\n } );\n\n pm.partials.Error.show( errorPopup );\n\n hideWaitScreen( true );\n }\n\n /**\n * Show wait screen if not visible and increase\n * {{#crossLink \"UIFactory/waitScreenCount:attribute\"}}waitScreenCount{{/crossLink}}\n * @function showWaitScreen\n */\n function showWaitScreen()\n {\n waitScreenCount = waitScreenCount || 0;\n\n // create wait-overlay if not exist\n if ( !waitScreen || $( 'body' ).has( waitScreen ).length <= 0 )\n {\n waitScreen = $( pm.compileTemplate( 'waitscreen/waitscreen.html' ) );\n $( 'body' ).append( waitScreen );\n }\n\n pm.partials.WaitScreen.show( waitScreen );\n\n // increase instance counter to avoid showing multiple overlays\n waitScreenCount++;\n return waitScreenCount;\n }\n\n /**\n * Decrease {{#crossLink \"UIFactory/waitScreenCount:attribute\"}}waitScreenCount{{/crossLink}}\n * and hide wait screen if waitScreenCount is 0\n * @function hideWaitScreen\n * @param {boolean} forceClose set true to hide wait screen independent from the value of waitScreenCount.\n */\n function hideWaitScreen( forceClose )\n {\n\n // decrease overlay count\n waitScreenCount--;\n\n // hide if all instances of overlays has been closed\n // or if closing is forced by user\n if ( waitScreenCount <= 0 || !!forceClose )\n {\n waitScreenCount = 0;\n pm.partials.WaitScreen.hide( waitScreen );\n }\n return waitScreenCount;\n }\n\n } );\n}( jQuery, PlentyFramework ));\n/**\n * Factories provide static functions and can be injected into\n * {{#crossLinkModule \"Services\"}}services{{/crossLinkModule}}.
    \n * Factories also can inject other factories. Compared to services,\n * factories are not visible in instances of {{#crossLinkModule \"PlentyFramework\"}}PlentyFramework{{/crossLinkModule}}.\n *\n * @module Factories\n * @main Factories\n */\nObject.equals = function( a, b )\n{\n if ( a === b )\n {\n return true;\n }\n if ( !(a instanceof Object) || !(b instanceof Object) )\n {\n return false;\n }\n if ( a.constructor !== b.constructor )\n {\n return false;\n }\n\n for ( var key in a )\n {\n if ( !a.hasOwnProperty( key ) )\n {\n continue;\n }\n if ( !b.hasOwnProperty( key ) )\n {\n return false;\n }\n if ( a[key] === b[key] )\n {\n continue;\n }\n if ( typeof( a[key] ) !== \"object\" )\n {\n return false;\n }\n if ( !Object.equals( a[key], b[key] ) )\n {\n return false;\n }\n }\n\n for ( var key in b )\n {\n if ( b.hasOwnProperty( key ) && !a.hasOwnProperty( key ) )\n {\n return false;\n }\n }\n\n return true;\n\n};\nPlentyFramework.cssClasses = {\n\n active: \"active\"\n\n};\n(function( $, pm )\n{\n\n pm.partials.Error = {\n\n /**\n * Will be called, after the error popup was created and injected in DOM.\n * @param {HTMLElement} popup The injected element of the popup\n */\n init: function( popup )\n {\n $( popup ).find( '.close' ).click( function()\n {\n pm.partials.Error.hideAll();\n } );\n },\n\n /**\n * Will be called for each thrown error. Has to be injected in DOM manually.\n * @param {HTMLElement} popup The error popup element\n * @param {HTMLElement} error The error message element\n */\n addError: function( popup, error )\n {\n var errorCode = $( error ).attr( 'data-plenty-error-code' );\n\n if ( $( popup ).find( '[data-plenty-error-code=\"' + errorCode + '\"]' ).length <= 0 )\n {\n $( popup ).find( '.plentyErrorBoxInner' ).append( error );\n }\n },\n\n /**\n * Will be called, after initialization and injection of all errors\n * @param {HTMLElement} popup The error popup element\n */\n show: function( popup )\n {\n $( popup ).show();\n },\n\n hideAll: function() {\n $( '#CheckoutErrorPane' ).hide();\n $( '#CheckoutErrorPane' ).find( '.plentyErrorBoxInner' ).html( '' );\n }\n\n }\n\n})( jQuery, PlentyFramework );\n(function( $, pm )\n{\n\n pm.partials.Modal = {\n\n /**\n * Will be called after a new modal was created and injected into DOM\n * @param {HTMLElement} element The injected modal element\n * @param {Modal} modal The instance of the current modal\n */\n init: function( element, modal )\n {\n element.on( 'hidden.bs.modal', function()\n {\n modal.hide();\n if( !modal.selector )\n {\n //Do not remove static modals\n element.remove();\n }\n } );\n\n if ( modal.timeout > 0 )\n {\n element.on( 'hide.bs.modal', modal.stopTimeout );\n element.find( '.modal-content' ).hover( function()\n {\n modal.pauseTimeout();\n }, function()\n {\n if ( element.is( '.in' ) )\n {\n modal.continueTimeout();\n }\n } );\n }\n },\n\n /**\n * Will be called if a Modal requests to show.\n * @param {HTMLElement} element The injected modal element\n */\n show: function( element )\n {\n element.modal( 'show' );\n },\n\n /**\n * Will be called if a Modal requests to hide.\n * @param {HTMLElement} element The injected modal element\n */\n hide: function( element )\n {\n element.modal( 'hide' );\n },\n\n /**\n * Detect if a given HTML string contains a modal\n * @param {HTMLElement} html the element to search a modal in.\n * @returns {boolean} true if a modal was found\n */\n isModal: function( html )\n {\n return $( html ).filter( '.modal' ).length + $( html ).find( '.modal' ).length > 0;\n },\n\n /**\n * Filter a modal from a given HTML string\n * @param {HTMLElement} html the element to get a modal from.\n * @returns {HTMLElement} the filtered modal element\n */\n getModal: function( html )\n {\n var modal = $( html );\n if ( modal.length > 1 )\n {\n modal = $( html ).filter( '.modal' ) || $( html ).find( '.modal' );\n }\n\n return modal;\n }\n\n };\n\n}( jQuery, PlentyFramework ));\n(function( $ )\n{\n\n $( document ).on( 'initPartials', function( e, root )\n {\n\n $( root ).find( '[data-toggle=\"tooltip\"]' ).tooltip( {\n container: 'body'\n } );\n\n } );\n\n})( jQuery );\n(function( $, pm )\n{\n\n pm.partials.WaitScreen = {\n\n /**\n * Will be called if the wait screen should be shown\n * @param {HTMLElement} element The wait screen element\n */\n show: function( element )\n {\n element.addClass( 'in' );\n },\n\n /**\n * Will be called if the wait screen should be hidden\n * @param {HTMLElement} element The wait screen element\n */\n hide: function( element )\n {\n element.removeClass( 'in' );\n }\n\n };\n\n})( jQuery, PlentyFramework );\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n(function( $, pm )\n{\n pm.service( 'AddressDoctorService', function( API )\n {\n return {\n validateAddress: validateAddress\n };\n\n function validateAddress( addressForms )\n {\n var addressIsValid = true;\n addressForms = addressForms || '[data-plenty-address-doctor]';\n $( addressForms ).filter( '[data-plenty-address-doctor]:visible' ).each( function( i, form )\n {\n var addressDoctor = new AddressDoctor( form );\n var requiredFields = $( form ).attr( 'data-plenty-address-doctor' ).replace( /\\s/g, '' ).split( ',' );\n if ( !addressDoctor.isValid( requiredFields ) )\n {\n addressIsValid = false;\n }\n\n } );\n\n return addressIsValid;\n }\n\n function AddressDoctor( form )\n {\n var $form = $( form );\n var $inputs = {\n Street : $form.find( 'input[name=\"Street\"]' ),\n ZIP : $form.find( 'input[name=\"ZIP\"]' ),\n City : $form.find( 'input[name=\"City\"]' ),\n HouseNo: $form.find( 'input[name=\"HouseNo\"]' )\n };\n var $suggestionContainer = {};\n\n var suggestions;\n var requiredFields;\n\n return {\n isValid: isValid\n };\n\n function isValid( fields )\n {\n\n if ( isPackstation() )\n {\n return true;\n }\n\n suggestions = new AddressList( $form.getFormValues() );\n requiredFields = fields;\n\n refreshView();\n\n return suggestions.getAddresses().length == 1;\n }\n\n function refreshView()\n {\n $( '.suggestion-list' ).remove();\n\n var suggestionListVisible = false;\n for ( var i = 0; i < requiredFields.length; i++ )\n {\n if ( !validateInput( requiredFields[i], suggestionListVisible ) )\n {\n $form.trigger( 'validationFailed' );\n suggestionListVisible = true;\n }\n }\n\n if ( suggestions.houseNoAllowed( $inputs.HouseNo.val() ) || suggestions.getAddresses().length == 1 )\n {\n $inputs.HouseNo.removeClass( 'has-error' );\n $form.find( 'label[for=\"' + $inputs.HouseNo.attr( 'id' ) + '\"]' ).removeClass( 'has-error' );\n\n $inputs.HouseNo.addClass( 'has-success' );\n $form.find( 'label[for=\"' + $inputs.HouseNo.attr( 'id' ) + '\"]' ).addClass( 'has-success' );\n }\n else\n {\n $inputs.HouseNo.removeClass( 'has-success' );\n $form.find( 'label[for=\"' + $inputs.HouseNo.attr( 'id' ) + '\"]' ).removeClass( 'has-success' );\n\n $inputs.HouseNo.addClass( 'has-error' );\n $form.find( 'label[for=\"' + $inputs.HouseNo.attr( 'id' ) + '\"]' ).addClass( 'has-error' );\n }\n }\n\n function validateInput( key, suggestionListVisible )\n {\n var valueList = suggestions.getList( key );\n\n if ( !!$suggestionContainer[key] )\n {\n $suggestionContainer[key].remove();\n }\n\n if ( !$inputs[key] )\n {\n return true;\n }\n\n if ( valueList.length == 1 )\n {\n $inputs[key].val( valueList[0] );\n\n $inputs[key].removeClass( 'has-error' );\n $form.find( 'label[for=\"' + $inputs[key].attr( 'id' ) + '\"]' ).removeClass( 'has-error' );\n\n $inputs[key].addClass( 'has-success' );\n $form.find( 'label[for=\"' + $inputs[key].attr( 'id' ) + '\"]' ).addClass( 'has-success' );\n return true;\n }\n else\n {\n $inputs[key].removeClass( 'has-success' );\n $form.find( 'label[for=\"' + $inputs[key].attr( 'id' ) + '\"]' ).removeClass( 'has-success' );\n\n $inputs[key].addClass( 'has-error' );\n $form.find( 'label[for=\"' + $inputs[key].attr( 'id' ) + '\"]' ).addClass( 'has-error' );\n\n if ( !suggestionListVisible )\n {\n buildSuggestionList( $inputs[key], valueList );\n }\n $inputs[key].off( 'focus' );\n $inputs[key].focus();\n return false;\n\n }\n }\n\n function positionSuggestionList( $parent, suggestionKey )\n {\n $suggestionContainer[suggestionKey].css( {\n 'width': $parent.outerWidth( true ),\n 'left' : $parent.position().left,\n 'top' : $parent.position().top + $parent.outerHeight( true )\n } );\n }\n\n function buildSuggestionList( $parent, values )\n {\n var suggestionKey = $parent.attr( 'name' );\n\n // render html content\n $suggestionContainer[suggestionKey] = $( pm.compileTemplate( 'addressSuggestions/addressDoctor.html', {values: values} ) );\n\n positionSuggestionList( $parent, suggestionKey );\n\n $( window ).on( 'sizeChange', function()\n {\n positionSuggestionList( $parent, suggestionKey );\n } );\n\n // bind click event to list elements\n $suggestionContainer[suggestionKey].find( '[data-address-value]' ).each( function( i, elem )\n {\n\n var $elem = $( elem );\n var value = $elem.attr( 'data-address-value' );\n\n $elem.click( function()\n {\n // insert clicked value in input\n $parent.val( value );\n\n // filter addresses and show remaining suggestions\n var filterAddress = {};\n filterAddress[$parent.attr( 'name' )] = value;\n suggestions.filter( filterAddress );\n\n // refresh suggestion lists\n refreshView();\n\n } );\n\n } );\n\n // inject html\n $parent.parent().append( $suggestionContainer[suggestionKey] );\n }\n\n function isPackstation()\n {\n return ( $inputs.Street.val().toUpperCase() == \"PACKSTATION\" || $inputs.Street.val().toUpperCase() == \"POSTFILIALE\" );\n }\n\n }\n\n function AddressList( addressInput )\n {\n var addresses = [];\n\n init();\n\n return {\n getAddresses : getAddresses,\n getList : getList,\n filter : filter,\n houseNoAllowed: houseNoAllowed\n };\n\n function init()\n {\n API.get( '/rest/checkout/addresssuggestionresultslist/', {\n suggestionType: \"addressdoctor\",\n street : addressInput.Street,\n ZIP : addressInput.ZIP,\n city : addressInput.City,\n houseNo : addressInput.HouseNo,\n country : addressInput.CountryID\n }, false, false, true ).done( function( response )\n {\n\n var responseLength = response.data.length;\n\n for ( var i = 0; i < responseLength; i++ )\n {\n var currentResponse = response.data[i];\n\n var address = getAddress( currentResponse )\n if ( !address )\n {\n currentResponse.HouseNo = [currentResponse.HouseNo];\n addresses.push( currentResponse );\n }\n else\n {\n address.HouseNo.push( currentResponse.HouseNo );\n }\n\n }\n\n } );\n }\n\n function getAddress( suggestion )\n {\n var addressCount = addresses.length;\n\n for ( var j = 0; j < addressCount; j++ )\n {\n if ( suggestion.Street == addresses[j].Street && addresses.ZIP == addresses[j].ZIP && suggestion.City == addresses[j].City )\n {\n return addresses[j];\n }\n }\n\n return null;\n\n }\n\n function getAddresses()\n {\n return addresses;\n }\n\n function getList( key )\n {\n var results = [];\n var addressCount = addresses.length;\n\n for ( var i = 0; i < addressCount; i++ )\n {\n var address = addresses[i];\n if ( $.inArray( address[key], results ) < 0 )\n {\n results.push( address[key] );\n }\n }\n\n return results;\n }\n\n function filter( filterAddress )\n {\n var filteredAddresses = [];\n var addressCount = addresses.length;\n\n for ( var i = 0; i < addressCount; i++ )\n {\n var address = addresses[i];\n if ( (!!filterAddress.Street && filterAddress.Street == address.Street)\n || (!!filterAddress.ZIP && filterAddress.ZIP == address.ZIP)\n || (!!filterAddress.City && filterAddress.City == address.City) )\n {\n filteredAddresses.push( address );\n }\n }\n\n addresses = filteredAddresses;\n }\n\n function houseNoAllowed( houseNo )\n {\n houseNo = parseInt( houseNo );\n\n var addressCount = addresses.length;\n\n for ( var i = 0; i < addressCount; i++ )\n {\n var address = addresses[i];\n\n for ( var j = 0; j < address.HouseNo.length; j++ )\n {\n var range = address.HouseNo[j].split( '-' );\n if ( ( range.length == 1 && houseNo == range[0] )\n || range.length == 2 && houseNo >= range[0] && houseNo <= range[1] )\n {\n return true;\n }\n }\n }\n\n return false;\n }\n }\n\n }, ['APIFactory'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Providing methods for logging in and out and registering new customers.
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CheckoutFactory\"}}CheckoutFactory{{/crossLink}}
    • \n *
    \n * @class AuthenticationService\n * @static\n */\n pm.service( 'AuthenticationService', function( API, Checkout, UI )\n {\n\n return {\n resetPassword : resetPassword,\n customerLogin : customerLogin,\n setInvoiceAddress: setInvoiceAddress,\n registerCustomer : registerCustomer\n };\n\n /**\n * Reading E-Mail from form marked with data-plenty-checkout=\"lostPasswordForm\"\n * and sends request to provide a new password to the entered E-Mail-Address.\n *\n * @function resetPasswort\n * @return {object} jQuery deferred\n * Object\n */\n function resetPassword()\n {\n\n var form = $( '[data-plenty-checkout=\"lostPasswordForm\"]' );\n\n if ( form.validateForm() )\n {\n\n var values = form.getFormValues();\n\n var params = {\n Email: values.Email\n };\n\n return API.post( \"/rest/checkout/lostpassword/\", params )\n .done( function( response )\n {\n if ( response.data.IsMailSend == true )\n {\n $( '[data-plenty-checkout=\"lostPasswordTextContainer\"]' ).hide();\n $( '[data-plenty-checkout=\"lostPasswordSuccessMessage\"]' ).show();\n }\n } );\n\n }\n }\n\n /**\n * Try to login in with credentials read from given <form> - element.\n * On success redirect to forms 'action' attribute.\n *\n * @function customerLogin\n * @param {object} form The jQuery-wrapped form-element to read the credentials from\n * @return {object} jQuery deferred\n * Object\n */\n function customerLogin( form )\n {\n if ( form.validateForm() )\n {\n var values = form.getFormValues();\n\n var params = {\n Email : values.loginMail,\n Password: values.loginPassword\n };\n\n UI.showWaitScreen();\n return API.post( \"/rest/checkout/login/\", params )\n .done( function()\n {\n // successful login -> go to form's target referenced by action-attribute\n window.location.assign( form.attr( 'action' ) );\n\n } );\n }\n }\n\n /**\n * Setting the invoice address of a newly registered customer or a guest.\n *\n * @function setInvoiceAddress\n * @param {object} invoiceAddress containing address-data sent to server\n * @return {object} jQuery deferred\n * Object\n */\n function setInvoiceAddress( invoiceAddress )\n {\n\n return API.post( \"/rest/checkout/customerinvoiceaddress/\", invoiceAddress )\n .done( function( response )\n {\n Checkout.getCheckout().CustomerInvoiceAddress = response.data;\n } );\n }\n\n /**\n * Prepare address-data to register new customer. Read the address-data from a <form> marked with\n * data-plenty-checkout-form=\"customerRegistration\"
    \n * On success, redirect to forms target referenced by action-attribute\n *\n * @function registerCustomer\n * @return {object} jQuery deferred\n * Object\n */\n function registerCustomer()\n {\n var form = $( '[data-plenty-checkout-form=\"customerRegistration\"]' );\n\n if ( form.validateForm() && pm.getInstance().AddressDoctorService.validateAddress() )\n {\n var values = form.getFormValues();\n values.LoginType = 2;\n\n if ( values.checkout\n && values.checkout.customerInvoiceAddress\n && values.checkout.customerInvoiceAddress.CustomerProperty )\n {\n var tmpProperties = values.checkout.customerInvoiceAddress.CustomerProperty;\n values.CustomerPropertiesList = values.CustomerPropertiesList || [];\n\n for ( var property in tmpProperties )\n {\n if ( tmpProperties[property] )\n {\n values.CustomerPropertiesList.push( {\n PropertyID : property,\n PropertyValue: tmpProperties[property]\n } );\n }\n }\n }\n\n return setInvoiceAddress( values )\n .done( function()\n {\n window.location.assign( form.attr( 'action' ) );\n } );\n }\n }\n }, ['APIFactory', 'CheckoutFactory', 'UIFactory'] );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Providing methods for adding, editing or removing basket items and coupon codes
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"UIFactory\"}}UIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CMSFactory\"}}CMSFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CheckoutFactory\"}}CheckoutFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"ModalFactory\"}}ModalFactory{{/crossLink}}
    • \n *
    \n * @class BasketService\n * @static\n */\n pm.service( 'BasketService', function( API, UI, CMS, Checkout, Modal )\n {\n\n return {\n addItem : addBasketItem,\n removeItem : removeBasketItem,\n getItem : getBasketItem,\n setItemQuantity : setItemQuantity,\n editItemAttributes: editItemAttributes,\n editOrderParams : editOrderParams,\n addCoupon : addCoupon,\n removeCoupon : removeCoupon\n };\n\n /**\n * Add item to basket. Will fail and show a popup if item has order params\n * @function addBasketItem\n * @param {Array} article Array containing the item to add\n * @param {boolean} [isUpdate=false] Indicating if item's OrderParams are updated\n * @return {object} jQuery deferred\n * Object\n */\n function addBasketItem( article )\n {\n\n if ( !!article )\n {\n\n API.get( '/rest/checkout/container_' + 'CheckoutOrderParamsList'.toLowerCase() + '/',\n {\n itemID : article[0].BasketItemItemID,\n quantity: article[0].BasketItemQuantity\n }, false, true ).done( function( resp )\n {\n // checking for order params!\n if ( resp.data[0].indexOf( \"form-group\" ) > 0 )\n {\n Modal.prepare()\n .setContent( resp.data[0] )\n .setTitle( pm.translate( \"Select order parameters\" ) )\n .setLabelConfirm( pm.translate( \"Save\" ) )\n .onConfirm( function()\n {\n // validate form\n if ( $( '[data-plenty-checkout-form=\"OrderParamsForm\"]' ).validateForm() )\n {\n // save order params\n addArticle( saveOrderParams( article ) );\n\n // close modal after saving order params\n return true;\n }\n else\n {\n return false;\n }\n } )\n .show();\n }\n else\n {\n addArticle( article );\n }\n } );\n }\n }\n\n /**\n * Read OrderParams from <form> marked with data-plenty-checkout-form=\"OrderParamsForm\" and inject\n * read values in 'addBasketList'. Update item by calling addBasketItem() again\n * @function saveOrderParams\n * @private\n * @param {Array} articleWithParams Containing the current item to add. Read OrderParams will be injected\n */\n function saveOrderParams( articleWithParams )\n {\n //TODO use $(\"[data-plenty-checkout-form='OrderParamsForm']\").serializeArray() to get order params\n var orderParamsForm = $( '[data-plenty-checkout-form=\"OrderParamsForm\"]' );\n var $self = {};\n var attrType = \"\";\n var match;\n\n //Groups\n orderParamsForm.find( '[name^=\"ParamGroup\"]' ).each( function()\n {\n match = this.name.match( /^ParamGroup\\[(\\d+)]\\[(\\d+)]$/ );\n articleWithParams = addOrderParamValue( articleWithParams, match[1], $( this ).val(), $( this ).val() );\n } );\n\n //Values\n orderParamsForm.find( '[name^=\"ParamValue\"]' ).each( function()\n {\n $self = $( this );\n attrType = $self.attr( 'type' );\n\n if ( ((attrType == 'checkbox' && $self.is( ':checked' )) ||\n (attrType == 'radio' && $self.is( ':checked' )) ||\n (attrType != 'radio' && attrType != 'checkbox')) && attrType != 'file' && attrType != 'hidden' )\n {\n\n var match = $self[0].name.match( /^ParamValue\\[(\\d+)]\\[(\\d+)]$/ );\n articleWithParams = addOrderParamValue( articleWithParams, match[1], match[2], $self.val() );\n\n }\n else if ( attrType == 'file' )\n {\n if ( $self[0].files && $self[0].files.length > 0 )\n {\n articleWithParams = orderParamFileUpload( $self, articleWithParams );\n }\n else\n {\n var match = $self[0].name.match( /^ParamValueFile\\[(\\d+)]\\[(\\d+)]$/ );\n var paramValue = $( 'input[type=\"hidden\"][name=\"ParamValue[' + match[1] + '][' + match[2] + ']\"]' ).val();\n articleWithParams = addOrderParamValue( articleWithParams, match[1], match[2], paramValue );\n }\n }\n } );\n\n return articleWithParams;\n }\n\n function addArticle( article )\n {\n API.post( '/rest/checkout/basketitemslist/', article, true )\n .done( function()\n {\n // Item has no OrderParams -> Refresh Checkout & BasketPreview\n Checkout.loadCheckout()\n .done( function()\n {\n var $artAttr = $( \"[name^=ArticleAttribute]\" );\n var $unitCombinationId = $( \"[name^=P_ID]:checked\" );\n var requestData = {ArticleID: article[0].BasketItemItemID};\n\n if ( $artAttr.val() > 0 )\n {\n $artAttr.each( function( i, value )\n {\n value = $( value );\n requestData[value.attr( \"name\" )] = value.val();\n } );\n }\n else if ( $unitCombinationId && $unitCombinationId.val() > 0 )\n {\n requestData[\"UnitCombinationId\"] = $unitCombinationId.val();\n }\n\n refreshBasketPreview();\n\n // Show confirmation popup\n CMS.getContainer( 'ItemViewItemToBasketConfirmationOverlay', requestData ).from( 'ItemView' )\n .done( function( response )\n {\n var timeout = pm.getGlobal( 'TimeoutItemToBasketOverlay', 5000 );\n var modal = Modal.prepare().setContent( response.data[0] );\n\n if ( timeout > 0 )\n {\n modal.setTimeout( timeout );\n }\n\n modal.show();\n } );\n } );\n } ).fail( function( jqXHR )\n {\n // some other error occured\n UI.printErrors( JSON.parse( jqXHR.responseText ).error.error_stack );\n } );\n }\n\n function updateArticle( article )\n {\n API.put( '/rest/checkout/basketitemslist/', article )\n .done( function()\n {\n // Item has no OrderParams -> Refresh Checkout & BasketPreview\n Checkout.reloadCatContent( pm.getGlobal( 'basketCatID' ) );\n Checkout.loadCheckout()\n .done( function()\n {\n refreshBasketPreview();\n } );\n } )\n }\n\n function orderParamFileUpload( $input, articleWithParams )\n {\n var key = $input[0].id;\n var orderParamUploadFiles = {};\n var orderParamFileIdStack = [];\n var formData;\n var fileData;\n var params = {\n type : 'POST',\n data : {},\n isFile : true,\n cache : false,\n dataType : 'json',\n processData: false,\n contentType: false\n };\n\n orderParamUploadFiles[key] = $input[0].files;\n\n // if input not pushed before.\n if ( orderParamFileIdStack.indexOf( key ) == -1 )\n {\n orderParamFileIdStack.push( key );\n }\n\n for ( var i = 0, length = orderParamFileIdStack.length; i < length; ++i )\n {\n formData = new FormData();\n fileData = orderParamUploadFiles[orderParamFileIdStack[i]];\n formData.append( \"0\", fileData[0], fileData[0].name );\n\n params.data = formData;\n\n API.post( \"/rest/checkout/orderparamfile/\", params );\n }\n\n var match = $input[0].name.match( /^ParamValueFile\\[(\\d+)]\\[(\\d+)]$/ );\n\n return addOrderParamValue( articleWithParams, match[1], match[2], orderParamUploadFiles[key][0]['name'] );\n }\n\n /**\n * Inject an OrderParam.\n * @function addOrderParamValue\n * @private\n * @param {Array} basketList The target to inject the value in.\n * @param {number} position Position where to inject the value\n * @param {number} paramId The ID of the OrderParam to inject\n * @param {string|number} paramValue the value of the OrderParam to inject\n * @returns {Array} Containing the item and the injected OrderParam\n */\n function addOrderParamValue( basketList, position, paramId, paramValue )\n {\n if ( position > 0 && basketList[position] == undefined )\n {\n basketList[position] = $.extend( true, {}, basketList[0] );\n basketList[position].BasketItemOrderParamsList = [];\n }\n\n if ( basketList[position] != undefined )\n {\n basketList[position].BasketItemQuantity = 1;\n if ( basketList[position].BasketItemOrderParamsList == undefined )\n {\n basketList[position].BasketItemOrderParamsList = [];\n }\n if ( paramValue )\n {\n basketList[position].BasketItemOrderParamsList.push( {\n BasketItemOrderParamID : paramId,\n BasketItemOrderParamValue: paramValue\n } );\n }\n }\n\n return basketList;\n }\n\n function editItemAttributes( BasketItemID )\n {\n var modal = $( '[data-plenty-basket-item=\"' + BasketItemID + '\"]' );\n modal.modal( 'show' );\n modal.find( '[data-plenty-modal=\"confirm\"]' ).on( 'click', function()\n {\n var basketItem = getBasketItem( BasketItemID );\n var attributesList = [];\n\n // check for select or list of images\n modal.find( 'select, .PlentyFormContainer.AttrImage > input[type=\"hidden\"]' ).each( function( i, attributeSelect )\n {\n var match = attributeSelect.name.match( /^ArticleAttribute\\[\\d+]\\[\\d+]\\[(\\d+)]$/ );\n if ( match && match[1] )\n {\n attributesList.push( {\n BasketItemAttributeID : match[1],\n BasketItemAttributeValueID: $( attributeSelect ).val()\n } );\n }\n\n } );\n\n if ( attributesList.length != 0 )\n {\n basketItem.BasketItemAttributesList = attributesList;\n }\n //update basketItem and refresh previewLists\n updateArticle( [basketItem] );\n\n } );\n }\n\n function editOrderParams( BasketItemID )\n {\n\n var basketItem = getBasketItem( BasketItemID );\n // FIX: unset old order params\n\n basketItem.BasketItemOrderParamsList = [];\n\n API.get( '/rest/checkout/container_' + 'CheckoutOrderParamsList'.toLowerCase() + '/', {\n itemID : basketItem.BasketItemItemID,\n quantity : basketItem.BasketItemQuantity,\n basketItemID: BasketItemID\n } ).done( function( resp )\n {\n // checking for order params!\n Modal.prepare()\n .setContent( resp.data[0] )\n .setTitle( pm.translate( \"Edit order parameters\" ) )\n .setLabelConfirm( pm.translate( \"Save\" ) )\n .onConfirm( function()\n {\n // validate form\n if ( $( '[data-plenty-checkout-form=\"OrderParamsForm\"]' ).validateForm() )\n {\n // save order params\n updateArticle( saveOrderParams( [basketItem] ) );\n\n // close modal after saving order params\n return true;\n }\n else\n {\n return false;\n }\n } )\n .show();\n } );\n }\n\n function getBasketItem( BasketItemID )\n {\n var basketItems = Checkout.getCheckout().BasketItemsList;\n for ( var i = 0; i < basketItems.length; i++ )\n {\n if ( basketItems[i].BasketItemID == BasketItemID )\n {\n return basketItems[i];\n }\n }\n\n return null;\n }\n\n /**\n * Remove item from basket. Will show a confirmation popup at first.\n * @function removeBasketItem\n * @param {number} BasketItemID The ID of the basket item to remove\n * @param {boolean} [forceDelete=false] Set true to remove the basket item without showing a confirmation popup\n * @return Promise\n */\n function removeBasketItem( BasketItemID, forceDelete )\n {\n\n var deferred = $.Deferred();\n\n // get item name\n var itemName = getBasketItem( BasketItemID ).BasketItemNameMap[1];\n\n // calling the delete request\n function doDelete()\n {\n API.delete( '/rest/checkout/basketitemslist/?basketItemIdsList[0]=' + BasketItemID )\n .done( function()\n {\n Checkout.loadCheckout().done( function()\n {\n //$( '[data-basket-item-id=\"' + BasketItemID + '\"]' ).remove();\n\n if ( !Checkout.getCheckout().BasketItemsList || Checkout.getCheckout().BasketItemsList.length <= 0 )\n {\n Checkout.reloadCatContent( pm.getGlobal( 'basketCatID' ) );\n }\n else\n {\n // FALLBACK if design not support selector\n // [data-plenty-checkout-template=\"BasketItemsList\"]\n if ( $( '[data-plenty-checkout-template=\"BasketItemsList\"]' ).length >= 0 )\n {\n API.get( \"/rest/checkout/container_checkoutbasketitemslist/\" ).done( function( response )\n {\n var $oldBasketList = $( '[data-basket-item-id]' ).parents( \"ul\" );\n var $basketListContainer = $oldBasketList.parents( \".panel-body\" );\n $oldBasketList.fadeOut( function()\n {\n $( this ).siblings( \":not('[data-plenty-checkout-template]')\" ).remove();\n $( this ).remove();\n $basketListContainer.prepend( $( response.data[0] ) ).hide().fadeIn( function()\n {\n pm.getInstance().bindDirectives( $basketListContainer );\n } );\n } );\n } );\n }\n else\n {\n Checkout.reloadContainer( 'BasketItemsList' );\n }\n Checkout.reloadContainer( 'Totals' );\n }\n\n refreshBasketPreview();\n\n deferred.resolve();\n } );\n } );\n }\n\n if ( !forceDelete )\n {\n // show confirmation popup\n Modal.prepare()\n .setTitle( pm.translate( 'Please confirm' ) )\n .setContent( '

    ' + pm.translate( \"Do you really want to remove \\\"{{item}}\\\" from your basket?\", {item: itemName} ) + '

    ' )\n .onDismiss( function()\n {\n //$('[data-basket-item-id=\"' + BasketItemID +\n // '\"]').find('[data-plenty=\"quantityInput\"]').val(originalItemQuantity);\n deferred.reject();\n } )\n .onConfirm( function()\n {\n doDelete();\n } )\n .setLabelConfirm( pm.translate( \"Delete\" ) )\n .show();\n }\n else\n {\n doDelete();\n }\n\n return deferred;\n }\n\n /**\n * Set a new quantity for the given BasketItem. If quantity is set to 0,\n * remove the item.\n * @function setItemQuantity\n * @param {number} BasketItemID The ID of the basket item to change the quantity of\n * @param {number} BasketItemQuantity The new quantity to set or 0 to remove the item\n */\n function setItemQuantity( BasketItemID, BasketItemQuantity )\n {\n // delete item if quantity is 0\n if ( BasketItemQuantity <= 0 )\n {\n return removeBasketItem( BasketItemID );\n }\n\n var deferred = $.Deferred();\n var params = Checkout.getCheckout().BasketItemsList;\n var basketItem;\n var basketItemIndex;\n\n for ( var i = 0; i < params.length; i++ )\n {\n if ( params[i].BasketItemID == BasketItemID )\n {\n basketItemIndex = i;\n basketItem = params[i];\n break;\n\n }\n }\n\n if ( !!basketItem && basketItem.BasketItemQuantity != BasketItemQuantity )\n {\n params[basketItemIndex].BasketItemQuantity = parseInt( BasketItemQuantity );\n\n API.post( \"/rest/checkout/basketitemslist/\", params )\n .done( function()\n {\n Checkout.setCheckout().done( function()\n {\n Checkout.reloadCatContent( pm.getGlobal( 'basketCatID' ) );\n refreshBasketPreview();\n deferred.resolve();\n } );\n } );\n }\n\n return deferred;\n }\n\n /**\n * Reload BasketPreview-Template and update basket totals\n * @function refreshBasketPreview\n * @private\n */\n function refreshBasketPreview()\n {\n\n Checkout.reloadItemContainer( 'BasketPreviewList' )\n .done( function()\n {\n\n $( '[data-plenty-basket-empty]' ).each( function( i, elem )\n {\n var toggleClass = $( elem ).attr( 'data-plenty-basket-empty' );\n if ( Checkout.getCheckout().BasketItemsList.length <= 0 )\n {\n $( elem ).addClass( toggleClass );\n }\n else\n {\n $( elem ).removeClass( toggleClass );\n }\n } );\n\n } );\n\n //update quantity\n var itemQuantityTotal = 0;\n $.each( Checkout.getCheckout().BasketItemsList, function( i, basketItem )\n {\n itemQuantityTotal += basketItem.BasketItemQuantity;\n } );\n\n $( '[data-plenty-basket-preview=\"itemQuantityTotal\"]' ).text( itemQuantityTotal );\n $( '[data-plenty-basket-preview=\"totalsItemSum\"]' ).text( Checkout.getCheckout().Totals.TotalsItemSum );\n }\n\n /**\n * Read the coupon code from an <input> element marked with data-plenty-checkout-form=\"couponCode\"\n * and try to add this coupon.\n * @function addCoupon\n * @return {object} jQuery deferred\n * Object\n */\n function addCoupon()\n {\n var params = {\n CouponActiveCouponCode: $( '[data-plenty-checkout-form=\"couponCode\"]' ).val()\n };\n\n return API.post( \"/rest/checkout/coupon/\", params )\n .done( function()\n {\n Checkout.setCheckout()\n .done( function()\n {\n\n updateContainer();\n } );\n } );\n }\n\n /**\n * Remove the currently added coupon\n * @function removeCoupon\n * @return {object} jQuery deferred\n * Object\n */\n function removeCoupon()\n {\n var params = {\n CouponActiveCouponCode: Checkout.getCheckout().Coupon.CouponActiveCouponCode\n };\n\n return API.delete( \"/rest/checkout/coupon/\", params )\n .done( function()\n {\n Checkout.setCheckout()\n .done( function()\n {\n delete Checkout.getCheckout().Coupon;\n\n updateContainer();\n } );\n } );\n }\n\n // update container\n function updateContainer()\n {\n Checkout.reloadContainer( 'Coupon' );\n // reload totals, if we are at basket\n if ( $( '[data-plenty-checkout-template=\"Totals\"]' ).length > 0 )\n {\n Checkout.reloadContainer( 'Totals' );\n }\n }\n\n }, ['APIFactory', 'UIFactory', 'CMSFactory', 'CheckoutFactory', 'ModalFactory'] );\n}( jQuery, PlentyFramework ));\n\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Providing methods for checkout process like setting shipping & payment information and placing the order.
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CMSFactory\"}}CMSFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CheckoutFactory\"}}CheckoutFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"ModalFactory\"}}ModalFactory{{/crossLink}}
    • \n *
    \n * @class CheckoutService\n * @static\n */\n pm.service( 'CheckoutService', function( API, UI, CMS, Checkout, Modal )\n {\n\n return {\n init : init,\n setCustomerSignAndInfo: setCustomerSignAndInfo,\n registerGuest : registerGuest,\n setShippingProfile : setShippingProfile,\n saveShippingAddress : saveShippingAddress,\n loadAddressSuggestion : loadAddressSuggestion,\n preparePayment : preparePayment,\n setMethodOfPayment : setMethodOfPayment,\n confirmAtrigaPaymax : confirmAtrigaPaymax,\n editBankDetails : editBankDetails,\n editCreditCard : editCreditCard,\n placeOrder : placeOrder\n };\n\n /**\n * Load checkout data initially on page load\n * @function init\n */\n function init()\n {\n Checkout.loadCheckout( true );\n }\n\n /**\n * Read customer sign and order information text from <form> marked with\n * data-plenty-checkout-form=\"details\" and update checkout.\n * @function setCustomerSignAndInfo\n * @return {object} jQuery deferred\n * Object\n */\n function setCustomerSignAndInfo()\n {\n var form = $( '[data-plenty-checkout-form=\"details\"]' );\n var values = form.getFormValues();\n\n // initialize CustomerSign & InfoText to avoid updating empty values\n if ( !Checkout.getCheckout().CheckoutCustomerSign )\n {\n Checkout.getCheckout().CheckoutCustomerSign = \"\";\n }\n if ( !Checkout.getCheckout().CheckoutOrderInfoText )\n {\n Checkout.getCheckout().CheckoutOrderInfoText = \"\";\n }\n\n if ( ( Checkout.getCheckout().CheckoutCustomerSign !== values.CustomerSign && $( form ).find( '[name=\"CustomerSign\"]' ).length > 0 )\n || ( Checkout.getCheckout().CheckoutOrderInfoText !== values.OrderInfoText && $( form ).find( '[name=\"OrderInfoText\"]' ).length > 0 ) )\n {\n\n Checkout.getCheckout().CheckoutCustomerSign = values.CustomerSign;\n Checkout.getCheckout().CheckoutOrderInfoText = values.OrderInfoText;\n\n return Checkout.setCheckout();\n\n }\n else\n {\n // No changes detected -> Do nothing\n return API.idle();\n }\n }\n\n /**\n * Read address data from <form> marked with data-plenty-checkout-form=\"shippingAddress\".\n * Create new shipping address or update the shipping address ID.\n * @function saveShippingAddress\n * @param {boolean} [validateForm = false] validate form before processing requests\n * @return {object} jQuery deferred\n * Object\n */\n function saveShippingAddress( validateForm )\n {\n var form = $( '[data-plenty-checkout-form=\"shippingAddress\"]' );\n\n if ( !validateForm && !form.validateForm() )\n {\n return false;\n }\n\n if ( !validateForm && !pm.getInstance().AddressDoctorService.validateAddress( form ) )\n {\n return false;\n }\n\n var values = form.getFormValues();\n var shippingAddressID = $( '[name=\"shippingAddressID\"]:checked' ).val();\n\n if ( shippingAddressID < 0 )\n {\n // save separate\n var shippingAddress = values;\n\n if ( !addressesAreEqual( shippingAddress, Checkout.getCheckout().CustomerShippingAddress ) )\n {\n if ( shippingAddress.Street == \"PACKSTATION\" )\n {\n shippingAddress.IsPackstation = 1;\n shippingAddress.PackstationNo = shippingAddress.HouseNo;\n }\n else if ( shippingAddress.Street == \"POSTFILIALE\" )\n {\n shippingAddress.IsPostfiliale = 1;\n shippingAddress.PostfilialNo = shippingAddress.HouseNo;\n }\n\n // new shipping address\n return API.post( \"/rest/checkout/customershippingaddress/\", shippingAddress )\n .done( function( response )\n {\n\n Checkout.getCheckout().CheckoutCustomerShippingAddressID = response.data.ID;\n Checkout.getCheckout().CheckoutShippingCountryID = response.data.CountryID;\n\n updatePaymentAndShippingDependencies();\n } );\n }\n else\n {\n // no changes detected\n return API.idle();\n }\n\n }\n else\n {\n if ( shippingAddressID != Checkout.getCheckout().CheckoutCustomerShippingAddressID )\n {\n // change shipping address id\n Checkout.getCheckout().CheckoutCustomerShippingAddressID = shippingAddressID;\n\n updatePaymentAndShippingDependencies();\n }\n else\n {\n return API.idle();\n }\n }\n }\n\n function updatePaymentAndShippingDependencies()\n {\n delete Checkout.getCheckout().CheckoutMethodOfPaymentID;\n delete Checkout.getCheckout().CheckoutShippingProfileID;\n\n return Checkout.setCheckout().done( function()\n {\n Checkout.reloadContainer( \"MethodsOfPaymentList\" );\n Checkout.reloadContainer( \"ShippingProfilesList\" );\n\n if ( Checkout.getCheckout().CustomerInvoiceAddress.LoginType == 2 )\n {\n Checkout.reloadContainer( 'CustomerShippingAddress' );\n }\n $( '#shippingAdressSelect' ).modal( 'hide' );\n\n // don't hit me. Ugly hack: this is to force quit/remove everything from modal.\n if ( $( \".modal-backdrop\" ) )\n {\n $( \".modal-backdrop\" ).remove();\n }\n } );\n }\n\n /**\n * Prepare address-data to register a guest. Reads the address-data from a <form> marked with\n * data-plenty-checkout-form=\"guestRegistration\"\n * @function registerGuest\n * @return {object} jQuery deferred\n * Object\n */\n function registerGuest()\n {\n var form = $( '[data-plenty-checkout-form=\"guestRegistration\"]' );\n\n var invoiceAddress = form.getFormValues();\n invoiceAddress.LoginType = 1;\n\n // add custom properties if necessary.\n if ( invoiceAddress.checkout\n && invoiceAddress.checkout.customerInvoiceAddress\n && invoiceAddress.checkout.customerInvoiceAddress.CustomerProperty )\n {\n var tmpProperties = invoiceAddress.checkout.customerInvoiceAddress.CustomerProperty;\n invoiceAddress.CustomerPropertiesList = invoiceAddress.CustomerPropertiesList || [];\n\n for ( var property in tmpProperties )\n {\n if ( tmpProperties[property] )\n {\n invoiceAddress.CustomerPropertiesList.push( {\n PropertyID : property,\n PropertyValue: tmpProperties[property]\n } );\n }\n }\n }\n\n if ( !addressesAreEqual( invoiceAddress, Checkout.getCheckout().CustomerInvoiceAddress ) )\n {\n return API.post( \"/rest/checkout/customerinvoiceaddress/\", invoiceAddress )\n .done( function( response )\n {\n saveShippingAddress().done( Checkout.loadCheckout );\n } );\n }\n else\n {\n return saveShippingAddress();\n }\n }\n\n /**\n * Check if values of addresses are equal\n * @function addressesAreEqual\n * @private\n * @param {object} address1\n * @param {object} address2\n * @returns {boolean}\n */\n function addressesAreEqual( address1, address2 )\n {\n for ( var key in address1 )\n {\n if ( address1[key] + '' !== address2[key] + '' && key !== 'EmailRepeat' )\n {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Set the shipping profile used for this order and update checkout. Selected shipping profile will be\n * read from <form> marked with data-plenty-checkout-form=\"shippingProfileSelect\"\n * @function setShippingProfile\n * @return {object} jQuery deferred\n * Object\n */\n function setShippingProfile()\n {\n\n var values = $( '[data-plenty-checkout-form=\"shippingProfileSelect\"]' ).getFormValues();\n\n Checkout.getCheckout().CheckoutShippingProfileID = values.ShippingProfileID;\n delete Checkout.getCheckout().CheckoutCustomerShippingAddressID;\n delete Checkout.getCheckout().CheckoutMethodOfPaymentID;\n\n return Checkout.setCheckout()\n .done( function()\n {\n Checkout.reloadContainer( 'MethodsOfPaymentList' );\n } );\n\n }\n\n /**\n * Prepare method of payment to check if external checkout is used or addition content should be displayed\n * @function preparePayment\n * @return {object} jQuery deferred\n * Object\n */\n function preparePayment()\n {\n var paymentID = Checkout.getCheckout().CheckoutMethodOfPaymentID;\n var paymentData = $( 'input[type=\"radio\"][name=\"MethodOfPaymentID\"][value=\"' + paymentID + '\"]' ).parent().getFormValues();\n return API.post( \"/rest/checkout/preparepayment/\", paymentData, true )\n .done( function( response )\n {\n if ( response.data.CheckoutMethodOfPaymentRedirectURL != '' )\n {\n\n document.location.assign( response.data.CheckoutMethodOfPaymentRedirectURL );\n\n }\n else if ( !!response.data.CheckoutMethodOfPaymentAdditionalContent )\n {\n\n var isBankDetails = $( response.data.CheckoutMethodOfPaymentAdditionalContent ).find( '[data-plenty-checkout-form=\"bankDetails\"]' ).length > 0;\n Modal.prepare()\n .setContent( response.data.CheckoutMethodOfPaymentAdditionalContent )\n .onConfirm( function()\n {\n if ( isBankDetails )\n {\n return saveBankDetails();\n }\n else\n {\n return saveCreditCard();\n }\n } )\n .show();\n }\n } )\n .fail( function( jqXHR )\n {\n try\n {\n var response = $.parseJSON( jqXHR.responseText );\n\n var errorStack = [];\n for ( var i = 0; i < response.error.error_stack.length; i++ )\n {\n if ( response.error.error_stack[i].code == 651 )\n {\n // notify atriga validation errors\n Checkout.reloadContainer( 'MethodsOfPaymentList' ).done( function()\n {\n $( document ).trigger( 'plenty.AtrigaValidationFailed' );\n } );\n }\n else\n {\n errorStack.push( response.error.error_stack[i] );\n }\n }\n\n // display remaining errors\n if ( errorStack.length > 0 )\n {\n UI.printErrors( errorStack );\n }\n }\n catch ( e )\n {\n UI.throwError( jqXHR.status, jqXHR.statusText );\n }\n } );\n\n }\n\n /**\n * Set the method of payment used for this order.\n * @function setMethodOfPayment\n * @param {number|undefined} paymentID ID of the method of payment to use. Read from <form> marked with\n * data-plenty-checkout-form=\"methodOfPayment\" if unset.\n * @return {object} jQuery deferred\n * Object\n */\n function setMethodOfPayment( paymentID )\n {\n /*\n var methodsOfPaymentList = Checkout.getCheckout().MethodsOfPaymentList;\n var methodOfPayment;\n for( var i = 0; i < methodsOfPaymentList.length; i++ )\n {\n if( methodsOfPaymentList[i].MethodOfPaymentID == paymentID )\n {\n methodOfPayment = methodsOfPaymentList[i];\n break;\n }\n }\n */\n\n if ( !paymentID )\n {\n // FIX for older callisto layouts (< 3.3): get payment id from input field\n paymentID = $( 'input[name=\"MethodOfPaymentID\"]:checked' ).val();\n }\n\n Checkout.getCheckout().CheckoutMethodOfPaymentID = paymentID;\n\n if ( !pm.getGlobal( 'Checkout.AtrigaRequireUserConfirmation' ) )\n {\n Checkout.getCheckout().CheckoutAtrigapaymaxChecked = true;\n }\n\n delete Checkout.getCheckout().CheckoutCustomerShippingAddressID;\n delete Checkout.getCheckout().CheckoutShippingProfileID;\n\n return Checkout.setCheckout()\n .done( function()\n {\n Checkout.reloadContainer( 'ShippingProfilesList' );\n } );\n }\n\n function confirmAtrigaPaymax( atrigaPaymaxChecked )\n {\n Checkout.getCheckout().CheckoutAtrigapaymaxChecked = !!atrigaPaymaxChecked;\n return API.put( '/rest/checkout', {\n CheckoutAtrigapaymaxChecked: !!atrigaPaymaxChecked\n } );\n //return Checkout.setCheckout();\n }\n\n /**\n * Display the popup to enter or edit customers bank details\n * @function editBankDetails\n */\n function editBankDetails()\n {\n\n CMS.getContainer( 'CheckoutPaymentInformationBankDetails' ).from( 'Checkout' )\n .done( function( response )\n {\n Modal.prepare()\n .setContent( response.data[0] )\n .onDismiss( function()\n {\n $( 'input[name=\"MethodOfPaymentID\"]' ).each( function( i, radio )\n {\n if ( $( radio ).val() == Checkout.getCheckout().CheckoutMethodOfPaymentID )\n {\n $( radio ).attr( 'checked', 'checked' );\n }\n else\n {\n $( radio ).removeAttr( 'checked' );\n }\n } );\n } ).onConfirm( function()\n {\n return saveBankDetails();\n } )\n .show();\n } );\n\n }\n\n /**\n * Read entered bank details from data-plenty-checkout-form=\"bankDetails\" and update checkout.\n * @function saveBankDetails\n * @private\n * @return {boolean} the result of form validation\n */\n function saveBankDetails()\n {\n var form = $( '[data-plenty-checkout-form=\"bankDetails\"]' );\n\n if ( form.validateForm() )\n {\n var values = form.getFormValues().checkout.customerBankDetails;\n\n var bankDetails = {\n CustomerBankName : values.bankName,\n CustomerBLZ : values.blz,\n CustomerAccountNumber: values.accountNo,\n CustomerAccountOwner : values.accountOwner,\n CustomerIBAN : values.iban,\n CustomerBIC : values.bic\n };\n\n API.post( \"/rest/checkout/paymentinformationbankdetails/\", bankDetails )\n .done( function()\n {\n Checkout.loadCheckout().done( function()\n {\n setMethodOfPayment( 3 );\n Checkout.reloadContainer( 'MethodsOfPaymentList' );\n } );\n } );\n return true;\n }\n else\n {\n return false;\n }\n }\n\n /**\n * Display a popup containing credit card form\n * @function editCreditCard\n */\n function editCreditCard()\n {\n\n CMS.getContainer( 'CheckoutPaymentInformationCreditCard' ).from( 'Checkout' )\n .done( function( response )\n {\n Modal.prepare()\n .setContent( response.data[0] )\n .onDismiss( function()\n {\n $( 'input[name=\"MethodOfPaymentID\"]' ).each( function( i, radio )\n {\n if ( $( radio ).val() == Checkout.getCheckout().CheckoutMethodOfPaymentID )\n {\n $( radio ).attr( 'checked', 'checked' );\n }\n else\n {\n $( radio ).removeAttr( 'checked' );\n }\n } );\n } ).onConfirm( function()\n {\n return saveCreditCard();\n } )\n .show();\n } );\n }\n\n /**\n * Read values from <form> marked with data-plenty-checkout-form=\"creditCard\" and update checkout.\n * @function saveCreditCard\n * @private\n * @return {boolean} the result of form validation\n */\n function saveCreditCard()\n {\n var form = $( '[data-plenty-checkout-form=\"creditCard\"]' );\n\n if ( form.validateForm() )\n {\n\n var values = form.getFormValues().checkout.paymentInformationCC;\n\n var creditCard = {\n Owner : values.owner,\n Cvv2 : values.cvv2,\n Number : values.number,\n Year : values.year,\n Month : values.month,\n Provider: values.provider\n };\n\n API.post( '/rest/checkout/paymentinformationcreditcard/', creditCard )\n .done( function()\n {\n Checkout.loadCheckout();\n } );\n return true;\n }\n else\n {\n return false;\n }\n }\n\n /**\n * Display a popup containing address suggestions\n * @param {string} type\n */\n function loadAddressSuggestion( type )\n {\n\n //check login type\n if ( Checkout.getCheckout().CustomerInvoiceAddress.LoginType == 2 )\n {\n var values = $( '[data-plenty-checkout-form=\"shippingAddress\"]' ).getFormValues();\n }\n else\n {\n var values = $( '[data-plenty-checkout-form=\"guestRegistration\"]' ).getFormValues();\n }\n\n var params = {\n street : values.Street,\n houseNo : values.HouseNo,\n ZIP : values.ZIP,\n city : values.City,\n postnummer : values.Postnummer,\n suggestionType: 'postfinder'\n };\n\n CMS.getContainer( 'CheckoutAddressSuggestionResultsList', params ).from( 'Checkout' )\n .done( function( response )\n {\n Modal.prepare()\n .setContent( response.data[0] )\n .show();\n } );\n }\n\n /**\n * Place the order prepared before and finish the checkout process.
    \n * Validate required checkboxes in data-plenty-checkout-form=\"placeOrder\"\n * @function placeOrder\n * @return {object} jQuery deferred\n * Object\n */\n function placeOrder()\n {\n var form = $( '[data-plenty-checkout-form=\"placeOrder\"]' );\n if ( form.validateForm() )\n {\n\n var values = form.getFormValues();\n\n // if not shown in layout set default 1 for mandatory fields\n var params = {\n TermsAndConditionsCheck : values.termsAndConditionsCheck || 0,\n WithdrawalCheck : values.withdrawalCheck || 0,\n PrivacyPolicyCheck : values.privacyPolicyCheck || 0,\n AgeRestrictionCheck : values.ageRestrictionCheck || 0,\n NewsletterCheck : values.newsletterCheck || 0,\n KlarnaTermsAndConditionsCheck: values.klarnaTermsAndConditionsCheck || 0,\n PayoneDirectDebitMandateCheck: values.payoneDirectDebitMandateCheck || 0,\n PayoneInvoiceCheck : values.payoneInvoiceCheck || 0\n };\n\n return API.post( \"/rest/checkout/placeorder/\", params )\n .done( function( response )\n {\n if ( response.data.MethodOfPaymentRedirectURL != '' )\n {\n\n window.location.assign( response.data.MethodOfPaymentRedirectURL );\n\n }\n else if ( response.data.MethodOfPaymentAdditionalContent != '' )\n {\n\n Modal.prepare()\n .setContent( response.data.MethodOfPaymentAdditionalContent )\n .setLabelDismiss( '' )\n .onDismiss( function()\n {\n window.location.assign( form.attr( 'action' ) );\n } ).onConfirm( function()\n {\n window.location.assign( form.attr( 'action' ) );\n } ).show();\n\n }\n else\n {\n\n window.location.assign( form.attr( 'action' ) );\n\n }\n } );\n }\n }\n\n }, ['APIFactory', 'UIFactory', 'CMSFactory', 'CheckoutFactory', 'ModalFactory'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n pm.service( 'FeedbackService', function( API )\n {\n\n return {\n getFeedbacks : getFeedbacks,\n addFeedback : addFeedback,\n ArticleTypes : articleTypes(),\n FeedbackTypes: feedbackTypes()\n };\n\n /*\n FeedbackService\n .getFeedbacks().between('2014-12-03', '2015-07-01')\n .for( FeedbackService.ArticleTypes.ITEM, 2732, FeedbackService.FeedbackTypes.COMMENTS_ONLY );\n */\n function getFeedbacks()\n {\n var feedbackInterval = {\n dateStart: null,\n dateEnd : null\n };\n\n return {\n between: setFeedbackInterval,\n for : listFeedbacks\n };\n\n function setFeedbackInterval( start, end )\n {\n feedbackInterval.dateStart = start;\n feedbackInterval.dateEnd = end;\n return this;\n }\n\n function listFeedbacks( articleType, referenceId, feedbackType )\n {\n\n var params = {\n ReferenceId : referenceId,\n FromDate : feedbackInterval.dateStart,\n ToDate : feedbackInterval.dateEnd,\n FeedbackType: feedbackType || feedbackTypes().COMMENTS_AND_RATINGS\n };\n return API.get( '/rest/feedback/' + articleType + '/', params );\n\n }\n }\n\n /*\n FeedbackService\n .addFeedback()\n .withRating( 5 )\n .withComment( 'Hallo' )\n .withAuthor( 'Felix', 'felix.dausch@plentymarkets.com', 123456 )\n .to( FeedbackService.ArticleTypes.ITEM, 2732 );\n */\n function addFeedback()\n {\n\n var params = {\n Rating : 1.0,\n Text : '',\n Author : '',\n Email : '',\n CustomerId: 0\n };\n\n return {\n withRating : withRating,\n withComment: withComment,\n withAuthor : withAuthor,\n to : sendFeedback\n };\n\n function withRating( rating )\n {\n params.Rating = rating;\n return this;\n }\n\n function withComment( comment )\n {\n params.Text = comment;\n return this;\n }\n\n function withAuthor( author, mail, customerID )\n {\n params.Author = author;\n if ( !!mail )\n {\n params.Email = mail;\n }\n if ( !!customerID )\n {\n params.CustomerId = customerID;\n }\n return this;\n }\n\n function sendFeedback( articleType, referenceId )\n {\n return API.post( '/rest/feedback/' + articleType + '/', params );\n\n }\n\n }\n\n function feedbackTypes()\n {\n return {\n COMMENTS_ONLY : 'comments_only',\n RATINGS_ONLY : 'ratings_only',\n COMMENTS_AND_RATINGS: 'comments_with_ratings'\n }\n }\n\n function articleTypes()\n {\n return {\n ITEM : 'item',\n CATEGORY: 'category',\n BLOG : 'blog'\n }\n }\n\n }, ['APIFactory'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Listens to window's size and trigger 'sizeChange' event if the Bootstrap interval changes.\n * @class MediaSizeService\n * @static\n * @example\n * $(window).on('sizeChange', function(newValue, oldValue) {\n * console.log('The interval changed from ' + oldValue + ' to ' + newValue.');\n * });\n */\n pm.service( 'MediaSizeService', function()\n {\n\n var bsInterval;\n\n // recalculation of the current interval on window resize\n $( window ).resize( calculateMediaSize );\n\n // initially calculation of the interval\n $( document ).ready( calculateMediaSize );\n\n return {\n interval : getInterval,\n isInterval: isInterval\n };\n\n /**\n * Get the currently used Bootstrap interval\n * @function getInterval\n * @return {\"xs\"|\"sm\"|\"md\"|\"lg\"}\n */\n function getInterval()\n {\n if ( !!bsInterval )\n {\n calculateMediaSize();\n }\n\n return bsInterval;\n }\n\n /**\n * Calculate the currently used Bootstrap interval\n * @function calculateMediaSize\n * @private\n */\n function calculateMediaSize()\n {\n var size;\n if ( !!window.matchMedia )\n { // FIX IE support\n if ( window.matchMedia( '(min-width:1200px)' ).matches )\n {\n size = 'lg';\n }\n else if ( window.matchMedia( '(min-width:992px)' ).matches )\n {\n size = 'md';\n }\n else if ( window.matchMedia( '(min-width:768px)' ).matches )\n {\n size = 'sm';\n }\n else\n {\n size = 'xs';\n }\n }\n else\n {\n if ( $( window ).width() >= 1200 )\n {\n size = 'lg';\n }\n else if ( $( window ).width() >= 992 )\n {\n size = 'md';\n }\n else if ( $( window ).width() >= 768 )\n {\n size = 'sm';\n }\n else\n {\n size = 'xs';\n }\n }\n if ( size != bsInterval || size === 'xs' )\n {\n var oldValue = bsInterval;\n bsInterval = size;\n $( window ).trigger( 'sizeChange', [bsInterval, oldValue] );\n }\n }\n\n function isInterval( interval )\n {\n var intervalList = interval.replace( /\\s/g, '' ).split( ',' );\n for ( var i = 0; i < intervalList.length; i++ )\n {\n if ( intervalList[i] == bsInterval )\n {\n return true;\n }\n }\n return false;\n }\n\n } );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Handling navigation while checkout processes\n * @class NavigatorService\n * @static\n *\n */\n pm.service( 'NavigatorService', function( CMS, Checkout )\n {\n var navigation = [];\t\t// contains navigation list elements\n var container = [];\t\t// content containers\n var current = -1;\t\t// index of currently shown content container\n var buttonPrev = {};\t\t// navigation buttons\n var buttonNext = {};\n var interceptors = {\n beforeChange: [],\n afterChange : []\n };\n var checkoutStates = [];\n\n return {\n init : init,\n getCurrentContainer: getCurrentContainer,\n goTo : goTo,\n beforeChange : beforeChange,\n afterChange : afterChange,\n continueChange : continueChange,\n next : next,\n previous : previous,\n goToID : goToID,\n fillNavigation : fillNavigation\n };\n\n /**\n * Initialize checkout navigation. Shows first container.\n * @function init\n * @example\n * ```html\n * \n *
      \n *
    • Checkout Step 1
    • \n *
    • Checkout Step 2
    • \n *
    • ...
    • \n *
    \n * \n *\n *
    \n *
    \n * Checkout Step 1 Content\n *
    \n *
    \n * Checkout Step 2 Content\n *
    \n *
    ...
    \n *
    \n * ```\n */\n function init()\n {\n\n // get elements from DOM\n navigation = $( '[data-plenty-checkout=\"navigation\"] > li' );\n container = $( '[data-plenty-checkout=\"container\"] > div' );\n buttonNext = $( '[data-plenty-checkout=\"next\"]' );\n buttonPrev = $( '[data-plenty-checkout=\"prev\"]' );\n\n if ( navigation.length == container.length && container.length > 0 )\n {\n var checkout = Checkout.getCheckout();\n\n container.hide();\n\n // initialize navigation\n navigation.each( function( i, elem )\n {\n $( elem ).addClass( 'disabled' );\n // handle navigation click events\n $( elem ).click( function()\n {\n if ( !$( this ).is( '.disabled' ) )\n {\n goTo( i );\n }\n } );\n } );\n\n buttonNext.attr( \"disabled\", \"disabled\" );\n buttonNext.click( function()\n {\n next();\n } );\n\n buttonPrev.attr( \"disabled\", \"disabled\" );\n buttonPrev.click( function()\n {\n previous();\n } );\n\n window.addEventListener( 'hashchange', function()\n {\n if ( window.location.hash.length > 0 )\n {\n goToID( window.location.hash );\n }\n else\n {\n goTo( 0 );\n }\n }, false );\n\n // initialize GUI\n // check url param for jumping to tab\n $.urlParam = function( name )\n {\n var results = new RegExp( '[\\?&]' + name + '=([^&#]*)' ).exec( window.location.href );\n if ( results == null )\n {\n return null;\n }\n else\n {\n return results[1] || 0;\n }\n };\n\n var param = $.urlParam( 'gototab' );\n // jump to hash from url param 'gototab'\n if ( window.location.hash.length == 0 && !!param && $( '[data-plenty-checkout-id=\"' + param + '\"]' ).length > 0 )\n {\n window.location.hash = param;\n }\n // jump to hash\n else if ( !goToID( window.location.hash ) && current >= 0 )\n {\n goTo( current );\n }\n else\n {\n goTo( 0 );\n }\n\n fillNavigation();\n $( window ).on( 'sizeChange', fillNavigation );\n $( window ).resize( function()\n {\n if ( pm.getInstance().MediaSizeService.interval() == 'xs' )\n {\n fillNavigation();\n }\n } );\n\n }\n }\n\n /**\n * Get the currently active checkout container.\n * @function getCurrentContainer\n * @return {{id: string, index: number}}\n */\n function getCurrentContainer()\n {\n if ( current >= 0 )\n {\n return {\n id : $( container[current] ).attr( 'data-plenty-checkout-id' ),\n index: current\n };\n }\n else\n {\n return null;\n }\n }\n\n /**\n * Register an interceptor called before each tab change.\n * Tabchange will break if any interceptor returns false.\n * @param {function} interceptor The interceptor callback to register\n * @chainable\n * @returns {NavigatorService}\n * @example\n * plenty.NavigatorService.beforeChange( function(targetContainer) {\n * if( targetContainer.id === 'details' ) {\n * // stop tabchange if user tries to access checkout container with id \"details\"\n * return false;\n * }\n * return true;\n * });\n */\n function beforeChange( interceptor )\n {\n interceptors.beforeChange.push( interceptor );\n return pm.getInstance().NavigatorService;\n }\n\n /**\n * Register an interceptor called after each tab change.\n * @param {function} interceptor The interceptor callback to register\n * @chainable\n * @returns {NavigatorService}\n */\n function afterChange( interceptor )\n {\n interceptors.afterChange.push( interceptor );\n return pm.getInstance().NavigatorService;\n }\n\n /**\n * Call registered interceptors. Break if any interceptor returns false.\n * Do not call beforeChange-interceptors on initially tabchange\n * @function resolveInterceptors\n * @private\n * @param {\"beforeChange\"|\"afterChange\"} identifier Describe which interceptors should be called\n * @param {number} index the index of the target container\n * @returns {boolean} Conjunction of all interceptor return values\n */\n function resolveInterceptors( identifier, index )\n {\n var continueTabChange = true;\n\n if ( current >= 0 || identifier === 'afterChange' )\n {\n\n var currentContainer = getCurrentContainer();\n var targetContainer = {\n index: index,\n id : $( container[index] ).attr( 'data-plenty-checkout-id' )\n };\n\n $.each( interceptors[identifier], function( i, interceptor )\n {\n if ( interceptor( currentContainer, targetContainer ) === false )\n {\n continueTabChange = false;\n return false;\n }\n } );\n }\n\n return continueTabChange;\n }\n\n /**\n * Show checkout tab given by index\n * @function goTo\n * @param {number} index Index of target tab, starting at 0\n * @param {boolean} [ignoreInterceptors=false] Set true to not call registered interceptors and force changing\n * tab\n */\n function goTo( index, ignoreInterceptors )\n {\n\n var contentChanged = current !== index;\n\n if ( contentChanged && !ignoreInterceptors )\n {\n if ( !resolveInterceptors( \"beforeChange\", index ) )\n {\n return;\n }\n }\n\n current = index;\n\n if ( !Object.equals( checkoutStates[current], Checkout.getCheckout( true ) ) && contentChanged && !!$( container[current] ).attr( 'data-plenty-checkout-content' ) )\n {\n checkoutStates[current] = Checkout.getCheckout( true );\n // reload tab content\n CMS.getCategoryContent( $( container[current] ).attr( 'data-plenty-checkout-content' ) )\n .done( function( response )\n {\n $( container[current] ).html( response.data[0] );\n // continue tab change\n proceedTabChange( contentChanged );\n pm.getInstance().bindDirectives( container[current] );\n $( window ).trigger( 'contentChanged' );\n } );\n }\n else\n {\n // continue tab change without reloading tab content\n proceedTabChange( contentChanged );\n //pm.getInstance().bindDirectives();\n }\n\n }\n\n function proceedTabChange( contentChanged )\n {\n\n // hide content containers\n $( container ).hide();\n\n // refresh navigation elements\n var $elem;\n $( navigation ).each( function( i, elem )\n {\n $elem = $( elem );\n $elem.removeClass( 'disabled active' );\n\n $elem.find( '[role=\"tab\"]' ).attr( 'aria-selected', 'false' );\n\n if ( i < current )\n {\n // set current element as active\n $elem.addClass( 'visited' );\n }\n else\n {\n if ( i == current )\n {\n $elem.addClass( 'active visited' );\n $elem.find( '[role=\"tab\"]' ).attr( 'aria-selected', 'true' );\n }\n else\n {\n if ( i > current && !$elem.is( '.visited' ) )\n {\n // disable elements behind active\n $elem.addClass( 'disabled' );\n }\n }\n }\n } );\n fillNavigation();\n\n // hide \"previous\"-button if first content container is shown\n if ( current <= 0 )\n {\n buttonPrev.attr( \"disabled\", \"disabled\" );\n }\n else\n {\n buttonPrev.removeAttr( \"disabled\" );\n }\n\n // hide \"next\"-button if last content container is shown\n if ( current + 1 == navigation.length )\n {\n buttonNext.attr( \"disabled\", \"disabled\" );\n }\n else\n {\n buttonNext.removeAttr( \"disabled\" );\n }\n\n // show current content container\n $( container[current] ).show();\n\n // set location hash\n if ( current > 0 )\n {\n window.location.hash = $( container[current] ).attr( 'data-plenty-checkout-id' );\n }\n else\n {\n if ( window.location.hash.length > 0 )\n {\n window.location.hash = '';\n }\n }\n\n if ( contentChanged )\n {\n resolveInterceptors( \"afterChange\", current );\n }\n }\n\n /**\n * Continue interrupted tabchange. Shorthand for: goTo(targetContainer.index, true)\n * @function continueChange\n * @param targetContainer The tab-object received from an interceptor\n */\n function continueChange( targetContainer )\n {\n goTo( targetContainer.index, true );\n }\n\n /**\n * Show next checkout tab if available. Shorthand for\n * \n * if (current < navigation.length - 1) {\n * goTo(current + 1);\n * }\n * \n * @function next\n */\n function next()\n {\n if ( current < navigation.length - 1 )\n {\n goTo( current + 1 );\n }\n }\n\n /**\n * Show previous checkout tab if available\n * @function next\n */\n function previous()\n {\n if ( current > 0 )\n {\n goTo( current - 1 );\n }\n }\n\n /**\n * Show checkout tab given by ID\n * @function goToID\n * @param {string} containerID ID of tab to show. Target tab must be marked with\n * data-plenty-checkout-id=\"#...\"\n */\n function goToID( containerID )\n {\n if ( containerID == 'next' )\n {\n next();\n return true;\n }\n else if ( containerID == 'prev' )\n {\n previous();\n return true;\n }\n else\n {\n containerID = containerID.replace( '#', '' );\n $( container ).each( function( i, elem )\n {\n if ( $( elem ).attr( 'data-plenty-checkout-id' ) == containerID )\n {\n goTo( i );\n return true;\n }\n } );\n }\n\n return false;\n }\n\n /**\n * Calculate navigation's width to match its parent element\n * by increasing its items padding.\n * @function fillNavigation\n */\n function fillNavigation()\n {\n // break if manager has not been initialized\n var navigationCount = navigation.length;\n if ( navigationCount <= 0 )\n {\n return;\n }\n\n // reset inline styles\n $( navigation ).removeAttr( 'style' );\n $( navigation ).children( 'span' ).removeAttr( 'style' );\n $( buttonNext ).removeAttr( 'style' );\n $( buttonPrev ).removeAttr( 'style' );\n\n var buttonWidth = ($( buttonPrev ).outerWidth() < $( buttonNext ).outerWidth()) ? $( buttonNext ).outerWidth( true ) + 1 : $( buttonPrev ).outerWidth( true ) + 1;\n $( buttonNext ).css( {width: buttonWidth + 'px'} );\n $( buttonPrev ).css( {width: buttonWidth + 'px'} );\n\n // calculate width to fill\n var width = $( navigation ).parent().parent().outerWidth( true ) - ( 2 * buttonWidth);\n width -= parseInt( $( navigation ).parent().css( 'marginLeft' ) ) + parseInt( $( navigation ).parent().css( 'marginRight' ) );\n\n var padding = width;\n var tabWidth = [];\n\n $( navigation ).each( function( i, elem )\n {\n padding -= parseInt( $( elem ).css( 'marginLeft' ) );\n padding -= parseInt( $( elem ).css( 'marginRight' ) );\n\n tabWidth[i] = $( elem ).children( 'span' ).width();\n padding -= tabWidth[i];\n\n padding -= parseInt( $( elem ).children( 'span' ).css( 'marginLeft' ) );\n padding -= parseInt( $( elem ).children( 'span' ).css( 'marginRight' ) );\n } );\n\n var paddingEachItem = parseInt( padding / navigationCount );\n\n var paddingLeft, paddingRight;\n if ( paddingEachItem % 2 == 1 )\n {\n paddingLeft = ( paddingEachItem / 2 ) + 0.5;\n paddingRight = ( paddingEachItem / 2 ) - 0.5;\n }\n else\n {\n paddingLeft = paddingEachItem / 2;\n paddingRight = paddingEachItem / 2;\n }\n\n var paddingLastItem = parseInt( padding - ( ( navigationCount - 1 ) * ( paddingLeft + paddingRight ) ) );\n var paddingLastLeft, paddingLastRight;\n if ( paddingLastItem % 2 == 1 )\n {\n paddingLastLeft = ( paddingLastItem / 2 ) + 0.5;\n paddingLastRight = ( paddingLastItem / 2) - 0.5;\n }\n else\n {\n paddingLastLeft = paddingLastItem / 2;\n paddingLastRight = paddingLastItem / 2;\n }\n\n var diff = width;\n $( navigation ).each( function( i, elem )\n {\n if ( i < navigationCount - 1 )\n {\n $( elem ).children( 'span' ).css( {'paddingLeft': paddingLeft + 'px', 'paddingRight': paddingRight + 'px'} ); //.parent().css({ width: ( tabWidth[i] + paddingLeft + paddingRight + parseInt( $(elem).children('span').css('marginLeft') ) + parseInt( $(elem).children('span').css('marginRight') ) )+'px' });\n }\n else\n {\n $( elem ).children( 'span' ).css( {'paddingLeft': paddingLastLeft + 'px', 'paddingRight': paddingLastRight + 'px'} ); //.parent().css({ width: ( tabWidth[i] + paddingLastLeft + paddingLastRight + parseInt( $(elem).children('span').css('marginLeft') ) + parseInt( $(elem).children('span').css('marginRight') ) )+'px' });\n }\n } );\n\n //$(navigation).parent().css('marginRight', 0);\n }\n\n }, ['CMSFactory', 'CheckoutFactory'] );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Magnus Martin \n * =====================================================================================\n */\n\n\n(function( $, pm )\n{\n pm.service( 'PostfinderService', function( API, Modal, UIFactory )\n {\n var packstationID = '';\n var shippingFields = {};\n var numberOfResults = {};\n var result = {};\n\n return {\n openPostfinderModal: openPostfinderModal,\n isPackstation : isPackstation\n };\n\n function isPackstation()\n {\n var street = $( 'input[name=\"Street\"]' ).val();\n return ( street.toUpperCase() == \"PACKSTATION\" || street.toUpperCase() == \"POSTFILIALE\" );\n }\n\n function openPostfinderModal()\n {\n shippingFields = {\n PostfinderItemStreet : $( 'input[name=\"Street\"]', '[data-plenty-checkout-form=\"shippingAddress\"]' ),\n PostfinderItemZIP : $( 'input[name=\"ZIP\"]', '[data-plenty-checkout-form=\"shippingAddress\"]' ),\n PostfinderItemCity : $( 'input[name=\"City\"]', '[data-plenty-checkout-form=\"shippingAddress\"]' ),\n PostfinderItemHouseNo: $( 'input[name=\"HouseNo\"]', '[data-plenty-checkout-form=\"shippingAddress\"]' )\n\n };\n\n shippingFields.PostfinderItemStreet.val( '' );\n\n if ( (shippingFields.PostfinderItemZIP.val().length > 2 || shippingFields.PostfinderItemCity.val().length > 2) )\n {\n\n API.get( '/rest/checkout/shippingaddresspostfinderlist/',\n {\n suggestionType: \"postfinder\",\n zip : shippingFields.PostfinderItemZIP.val(),\n city : shippingFields.PostfinderItemCity.val()\n } )\n\n .done( function( response )\n {\n result = response.data;\n numberOfResults = result.length;\n\n if ( numberOfResults == 0 )\n {\n showErrorMessage();\n }\n\n var params = {\n addresses: []\n };\n\n for ( var i = 0; i < numberOfResults; i++ )\n {\n var dimension = 'km';\n var distInMeters = result[i].PostfinderItemDistance;\n var distInKilometers = distInMeters / 1000;\n distInKilometers = ((Math.round( distInKilometers * 100 ) / 100).toFixed( 2 )).replace( '.', ',' );\n\n if ( distInMeters < 1000 )\n {\n distInKilometers = distInMeters;\n dimension = 'm';\n }\n\n params.addresses.push( {\n index : i,\n dimension: dimension,\n type : result[i].PostfinderItemIsPackstation ? 'Packstation' : 'Postfiliale',\n number : result[i].PostfinderItemIsPackstation ? result[i].PostfinderItemPackstationNo : result[i].PostfinderItemPostfilialNo,\n street : result[i].PostfinderItemStreet,\n houseNo : result[i].PostfinderItemHouseNo,\n zip : result[i].PostfinderItemZIP,\n city : result[i].PostfinderItemCity,\n district : result[i].PostfinderItemDistrict,\n distance : distInKilometers,\n remark : result[i].PostfinderItemRemark\n } );\n }\n\n var html = pm.compileTemplate( 'addressSuggestions/postFinder.html', params );\n\n Modal.prepare()\n .setTitle( pm.translate( 'Packstations and post offices in your area' ) )\n .setContent( html )\n .setClass( 'checkout' )\n .onConfirm( function()\n {\n shippingFields.PostfinderItemCity.removeClass( 'has-error' ).addClass( 'has-success' );\n $( 'label[for=\"' + shippingFields.PostfinderItemCity.attr( 'id' ) + '\"]' ).removeClass( 'has-error' ).addClass( 'has-success' );\n\n shippingFields.PostfinderItemZIP.removeClass( 'has-error' ).addClass( 'has-success' );\n $( 'label[for=\"' + shippingFields.PostfinderItemZIP.attr( 'id' ) + '\"]' ).removeClass( 'has-error' ).addClass( 'has-success' );\n\n shippingFields.PostfinderItemStreet.removeClass( 'has-error' ).addClass( 'has-success' );\n $( 'label[for=\"' + shippingFields.PostfinderItemStreet.attr( 'id' ) + '\"]' ).removeClass( 'has-error' ).addClass( 'has-success' );\n\n shippingFields.PostfinderItemHouseNo.removeClass( 'has-error' ).addClass( 'has-success' );\n $( 'label[for=\"' + shippingFields.PostfinderItemHouseNo.attr( 'id' ) + '\"]' ).removeClass( 'has-error' ).addClass( 'has-success' );\n\n packstationID = $( 'input[type=\"radio\"][name=\"postfinder\"]:checked' ).val();\n\n if ( result[packstationID].PostfinderItemIsPackstation )\n {\n $( shippingFields.PostfinderItemStreet ).val( 'PACKSTATION' );\n $( shippingFields.PostfinderItemHouseNo ).val( result[packstationID].PostfinderItemPackstationNo );\n }\n else\n {\n $( shippingFields.PostfinderItemStreet ).val( 'POSTFILIALE' );\n $( shippingFields.PostfinderItemHouseNo ).val( result[packstationID].PostfinderItemPostfilialNo );\n }\n $( shippingFields.PostfinderItemStreet ).trigger( 'change' );\n\n $( shippingFields.PostfinderItemCity ).val( result[packstationID].PostfinderItemCity );\n $( shippingFields.PostfinderItemZIP ).val( result[packstationID].PostfinderItemZIP );\n return true;\n } )\n .show()\n } );\n }\n else\n {\n showErrorMessage();\n }\n\n }\n\n function showErrorMessage()\n {\n UIFactory.throwError( 0, pm.translate( 'Please enter a ZIP code and/or a city.' ) );\n\n shippingFields.PostfinderItemCity.removeClass( 'has-success' ).addClass( 'has-error' );\n $( 'label[for=\"' + shippingFields.PostfinderItemCity.attr( 'id' ) + '\"]' ).removeClass( 'has-success' ).addClass( 'has-error' );\n\n shippingFields.PostfinderItemZIP.removeClass( 'has-success' ).addClass( 'has-error' );\n $( 'label[for=\"' + shippingFields.PostfinderItemZIP.attr( 'id' ) + '\"]' ).removeClass( 'has-success' ).addClass( 'has-error' );\n\n shippingFields.PostfinderItemCity.focus( function()\n {\n $( this ).removeClass( 'has-error' );\n var inputId = $( this ).attr( 'id' );\n $( this ).closest( '.form-group' ).find( '[for=\"' + inputId + '\"]' ).removeClass( 'has-error' );\n } );\n\n shippingFields.PostfinderItemZIP.focus( function()\n {\n $( this ).removeClass( 'has-error' );\n var inputId = $( this ).attr( 'id' );\n $( this ).closest( '.form-group' ).find( '[for=\"' + inputId + '\"]' ).removeClass( 'has-error' );\n } );\n }\n }, ['APIFactory', 'ModalFactory', 'UIFactory'] );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Provide templates for social share providers to inject them dynamically.\n * @class SocialShareService\n * @static\n */\n pm.service( 'SocialShareService', function()\n {\n\n //TODO: move to global variables\n if ( typeof(socialLangLocale) == 'undefined' )\n {\n socialLangLocale = 'en_US';\n }\n if ( typeof(socialLang) == 'undefined' )\n {\n socialLang = 'en';\n }\n\n return {\n getSocialService: getService\n };\n\n /**\n * Get the template for social media provider\n * @function getService\n * @param {string} identifier name of the social media provider to get the template for\n * @returns {string} the template to inject in DOM\n */\n function getService( identifier )\n {\n var services = {\n 'facebook-like': '',\n\n 'facebook-recommend': '',\n\n 'twitter': '',\n\n 'google-plus': '
    '\n + '',\n };\n\n return services[identifier];\n }\n\n /**\n * get the canonical URL if defined\n * @function getURL\n * @private\n * @return {string} The Canonical URL if defined or the current URI\n */\n function getURI()\n {\n var uri = document.location.href;\n var canonical = $( \"link[rel=canonical]\" ).attr( \"href\" );\n\n if ( canonical && canonical.length > 0 )\n {\n if ( canonical.indexOf( \"http\" ) < 0 )\n {\n canonical = document.location.protocol + \"//\" + document.location.host + canonical;\n }\n uri = canonical;\n }\n\n return uri;\n }\n\n /**\n * returns content of <meta name=\"\" content=\"\"> tags or '' if empty/non existant\n * @function getMeta\n * @private\n * @param {string} name The meta name to get the value of;\n */\n function getMeta( name )\n {\n var metaContent = $( 'meta[name=\"' + name + '\"]' ).attr( 'content' );\n return metaContent || '';\n }\n\n /**\n * create tweet text from content of <meta name=\"DC.title\"> and <meta name=\"DC.creator\">\n * fallback to content of <title> tag\n * @function getTweetText\n * @private\n */\n function getTweetText()\n {\n var title = getMeta( 'DC.title' );\n var creator = getMeta( 'DC.creator' );\n\n if ( title.length > 0 && creator.length > 0 )\n {\n title += ' - ' + creator;\n }\n else\n {\n title = $( 'title' ).text();\n }\n\n return encodeURIComponent( title );\n }\n\n } );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Provide methods for client-side form validation.\n * @class ValidationService\n * @static\n */\n pm.service( 'ValidationService', function()\n {\n\n return {\n validate: validate\n };\n\n /**\n * Check if element is a form element (input, select, textarea) or search for child form elements\n * @function getFormControl\n * @private\n * @param {object} element the element to get the form element from\n * @return {object} a valid form element (input, select, textarea)\n */\n function getFormControl( element )\n {\n element = $( element );\n if ( element.is( 'input' ) || element.is( 'select' ) || element.is( 'textarea' ) )\n {\n return element;\n }\n else\n {\n if ( element.find( 'input' ).length > 0 )\n {\n return element.find( 'input' );\n }\n\n else if ( element.find( 'select' ).length > 0 )\n {\n return element.find( 'select' );\n }\n\n else if ( element.find( 'textarea' ).length > 0 )\n {\n return element.find( 'textarea' );\n }\n\n else\n {\n return null;\n }\n }\n\n }\n\n /**\n * Check given element has any value\n * @function validateText\n * @private\n * @param {object} formControl the form element to validate\n * @return {boolean}\n */\n function validateText( formControl )\n {\n // check if formControl is no checkbox or radio\n if ( formControl.is( 'input' ) || formControl.is( 'select' ) || formControl.is( 'textarea' ) )\n {\n // check if length of trimmed value is greater then zero\n return $.trim( formControl.val() ).length > 0;\n\n }\n else\n {\n console.error( 'Validation Error: Cannot validate Text for <' + formControl.prop( \"tagName\" ) + '>' );\n return false;\n }\n }\n\n /**\n * Check given element's value is a valid email-address\n * @function validateMail\n * @private\n * @param {object} formControl the form element to validate\n * @return {boolean}\n */\n function validateMail( formControl )\n {\n var mailRegExp = /[a-zA-Z0-9!#$%&'*+\\/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;\n if ( validateText( formControl ) )\n {\n return mailRegExp.test( $.trim( formControl.val() ) );\n }\n else\n {\n return false;\n }\n }\n\n /**\n * Check given element's value is a valid number\n * @function validateNumber\n * @private\n * @param {object} formControl the form element to validate\n * @return {boolean}\n */\n function validateNumber( formControl )\n {\n if ( validateText( formControl ) )\n {\n return $.isNumeric( $.trim( formControl.val() ) );\n }\n else\n {\n return false;\n }\n }\n\n /**\n * Check given element's value is equal to a references value\n * @function compareValues\n * @private\n * @param {object} formControl the form element to validate\n * @param {string} reference the required value\n * @param {boolean} caseSensitive direct compare, without convert to lowerCase\n * @return {boolean}\n */\n function compareValues( formControl, reference, caseSensitive )\n {\n formControl = $.trim( formControl.val() );\n reference = $.trim(\n $( reference ).length > 0\n ? $( reference ).val()\n : reference );\n\n if ( caseSensitive )\n {\n return formControl == reference;\n }\n return formControl.toLowerCase() == reference.toLowerCase();\n }\n\n function isNotVisibleOrEnabled( formControl )\n {\n return (!formControl.is( ':visible' ) || !formControl.is( ':enabled' ));\n }\n\n /**\n * Validate a form. Triggers event 'validationFailed' if any element has an invalid value\n * @function validate\n * @param {object} form The form element to validate\n * @returns {boolean}\n * @example\n * ```html\n * \n *
    \n * \n * \n *\n * \n * \n *\n * \n * \n *\n * \n * \n *\n * \n * \n * \n *\n * \n * \n * \n * \n *\n * \n * \n * \n * \n *\n * \n *
    \n * \n * \n *
    \n *\n *
    \n * ```\n *\n * @example\n * $(form).on('validationFailed', function(missingFields) {\n * // handle missing fields\n * });\n */\n function validate( form, errorClass )\n {\n var $formControl, formControls, validationKey, currentHasError, group, checked, checkedMin, checkedMax, attrValidate, validationKeys, formControlAttrType;\n var $form = $( form );\n errorClass = errorClass || 'has-error';\n var missingFields = [];\n var hasError = false;\n\n // check every required input inside form\n $form.find( '[data-plenty-validate], :required' ).each( function( i, elem )\n {\n attrValidate = $( elem ).attr( 'data-plenty-validate' );\n formControls = getFormControl( elem );\n // validate text inputs\n validationKeys = !!attrValidate ? attrValidate : 'text';\n validationKeys = validationKeys.split( ',' );\n\n for ( var i = 0, length = formControls.length; i < length; i++ )\n {\n $formControl = $( formControls[i] );\n formControlAttrType = $formControl.attr( 'type' );\n\n // skip validation, if input is invisible or disabled\n if ( isNotVisibleOrEnabled( $formControl ) )\n {\n return;\n }\n\n validationKey = validationKeys[i].trim() || validationKeys[0].trim();\n currentHasError = false;\n\n // formControl is textfield (text, mail, password) or textarea\n if ( ($formControl.is( 'input' )\n && formControlAttrType != 'radio'\n && formControlAttrType != 'checkbox')\n || $formControl.is( 'textarea' ) )\n {\n switch ( validationKey )\n {\n\n case 'text':\n currentHasError = !validateText( $formControl );\n break;\n\n case 'mail':\n currentHasError = !validateMail( $formControl );\n break;\n\n case 'number':\n currentHasError = !validateNumber( $formControl );\n break;\n\n case 'value':\n currentHasError = !compareValues( $formControl, $( elem ).attr( 'data-plenty-validation-value' ), ($formControl.context.type === \"password\") );\n break;\n\n case 'none':\n // do not validate\n break;\n\n default:\n console.error( 'Form validation error: unknown validate property: \"' + attrValidate + '\"' );\n break;\n }\n }\n else if ( $formControl.is( 'input' )\n && (formControlAttrType == 'radio'\n || formControlAttrType == 'checkbox') )\n {\n // validate radio buttons\n group = $formControl.attr( 'name' );\n checked = $form.find( 'input[name=\"' + group + '\"]:checked' ).length;\n\n if ( formControlAttrType == 'radio' )\n {\n checkedMin = 1;\n checkedMax = 1;\n }\n else\n {\n var minMax = (new Function( \"return \" + attrValidate ))() || {min: 1, max: 1};\n checkedMin = minMax.min;\n checkedMax = minMax.max;\n }\n\n currentHasError = ( checked < checkedMin || checked > checkedMax );\n\n }\n else if ( $formControl.is( 'select' ) )\n {\n // validate selects\n currentHasError = ( $formControl.val() == '' || $formControl.val() == '-1' );\n }\n else\n {\n console.error( 'Form validation error: ' + $( elem ).prop( \"tagName\" ) + ' does not contain an form element' );\n return;\n }\n\n if ( currentHasError )\n {\n hasError = true;\n missingFields.push( $formControl );\n\n if ( formControls.length > 1 )\n {\n $formControl.addClass( errorClass );\n $form.find( 'label[for=\"' + $formControl.attr( 'id' ) + '\"]' ).addClass( errorClass );\n }\n else\n {\n $( elem ).addClass( errorClass );\n }\n }\n }\n\n } );\n\n // scroll to element on 'validationFailed'\n $form.on( 'validationFailed', function()\n {\n var distanceTop = 50;\n var $error = $form.find( '.' + errorClass ).first();\n var errorOffset = $error.offset().top;\n var $scrollTarget = $( 'html, body' );\n\n // if form is inside of modal, scroll modal instead of body\n if ( $form.parents( '.modal' ).length > 0 )\n {\n $scrollTarget = $form.parents( '.modal' ).find( '.modal-body' );\n errorOffset = $scrollTarget.scrollTop() - ( $scrollTarget.offset().top - $error.offset().top );\n\n }\n else if ( $form.is( '.modal' ) )\n {\n $scrollTarget = $form.find( '.modal-body' );\n errorOffset = $scrollTarget.scrollTop() - ( $scrollTarget.offset().top - $error.offset().top );\n }\n\n // only scroll if error is outside of viewport\n if ( errorOffset - distanceTop < window.pageYOffset || errorOffset > (window.pageYOffset + window.innerHeight) )\n {\n $scrollTarget.animate( {\n scrollTop: errorOffset - distanceTop\n } );\n }\n } );\n\n if ( hasError )\n {\n // remove error class on focus\n $form.find( '.' + errorClass ).each( function( i, elem )\n {\n $formControl = $( getFormControl( elem ) );\n $formControl.on( 'focus click', function()\n {\n var $errorElement = $( elem );\n $errorElement.removeClass( errorClass );\n $form.find( 'label[for=\"' + $( this ).attr( 'id' ) + '\"]' ).removeClass( errorClass );\n } );\n } );\n\n $form.trigger( 'validationFailed', [missingFields] );\n }\n\n var callback = $form.attr( 'data-plenty-callback' );\n\n if ( !hasError && !!callback && callback != \"submit\" && typeof window[callback] == \"function\" )\n {\n\n var fields = {};\n $form.find( 'input, textarea, select' ).each( function()\n {\n if ( $( this ).attr( 'type' ) == 'checkbox' )\n {\n fields[$( this ).attr( 'name' )] = $( this ).is( ':checked' );\n }\n else\n {\n fields[$( this ).attr( 'name' )] = $( this ).val();\n }\n } );\n\n window[callback]( fields );\n return false;\n }\n else\n {\n return !hasError;\n }\n }\n } );\n\n /**\n * jQuery-Plugin to calling {{#crossLink \"ValidationService/validate\"}}ValidationService.validate{{/crossLink}}\n * on jQuery wrapped elements.\n * @return {boolean}\n */\n $.fn.validateForm = function()\n {\n return pm.getInstance().ValidationService.validate( this );\n };\n\n /**\n * jQuery-Plugin to get the values of contained form elements.\n * @return {object}\n */\n $.fn.getFormValues = function()\n {\n\n var form = this;\n var values = {};\n\n function inject( position, value )\n {\n var match = position.match( /^([^\\[]+)(.*)/ );\n\n if ( !!match[2] )\n {\n var exp = /\\[([^\\]]+)]/g;\n var child;\n var children = [];\n children[0] = match[1];\n while ( (child = exp.exec( match[2] )) !== null )\n {\n children.push( child[1] );\n }\n\n for ( var i = children.length - 1; i >= 0; i-- )\n {\n var val = {};\n val[children[i]] = value;\n value = val;\n }\n values = $.extend( true, values, value );\n }\n else\n {\n values[match[1]] = value;\n }\n }\n\n form.find( 'input, select, textarea' ).each( function( i, elem )\n {\n if ( !!$( elem ).attr( 'name' ) )\n {\n if ( $( elem ).attr( 'type' ) == \"checkbox\" )\n {\n // get checkbox group\n var groupValues = [];\n $( form ).find( '[name=\"' + $( elem ).attr( 'name' ) + '\"]:checked' ).each( function( j, checkbox )\n {\n groupValues.push( $( checkbox ).val() );\n } );\n inject( $( elem ).attr( 'name' ), groupValues );\n }\n else if ( $( elem ).attr( 'type' ) == 'radio' )\n {\n if ( $( elem ).is( ':checked' ) )\n {\n inject( $( elem ).attr( 'name' ), $( elem ).val() );\n }\n }\n else\n {\n inject( $( elem ).attr( 'name' ), $( elem ).val() );\n }\n }\n\n } );\n return values;\n }\n}( jQuery, PlentyFramework ));\n/**\n * Services provide functions to be called from the instanced PlentyFramework.
    \n * Services can inject Factories and can be injected into Directives. The are also\n * available from the global instance of PlentyFramework\n * @module Services\n * @main Services\n * @example\n * PlentyFramework.service('ServiceName', serviceFunctions() {\n * return {\n * functionInService: function() {}\n * }\n * });\n * //...\n * plenty.ServiceName.functionInService/();\n */\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\nPlentyFramework.compile();\n\n// Create global instance of PlentyFramework for usage in Webshop-Layouts\nvar plenty = PlentyFramework.getInstance();\n\n/*\n * initially bind all registered directives\n *\n * will not be tested. reasons:\n * http://stackoverflow.com/questions/29153733/how-to-unit-test-a-document-ready-function-using-jasmine\n */\njQuery( document ).ready( function()\n{\n plenty.bindDirectives();\n} );" - ] -} \ No newline at end of file diff --git a/dist/plentymarketsCMStools-1.0.11.js b/dist/plentymarketsCMStools-1.0.12.js similarity index 99% rename from dist/plentymarketsCMStools-1.0.11.js rename to dist/plentymarketsCMStools-1.0.12.js index d96f53c..c2fc5c6 100644 --- a/dist/plentymarketsCMStools-1.0.11.js +++ b/dist/plentymarketsCMStools-1.0.12.js @@ -651,7 +651,7 @@ TemplateCache["waitscreen/waitscreen.html"] = "
    0 + && $p_id.val() > 0 ) { - basketItemsList.BasketItemPriceID = parentForm.find( '[name="P_ID"]:checked' ).val(); + basketItemsList.BasketItemPriceID = $p_id.val(); } //attributes @@ -4503,7 +4506,7 @@ PlentyFramework.cssClasses = { .done( function() { var $artAttr = $( "[name^=ArticleAttribute]" ); - var $unitCombinationId = $( "[name^=P_ID]:checked" ); + var $unitCombinationId = article[0].BasketItemPriceID; var requestData = {ArticleID: article[0].BasketItemItemID}; if ( $artAttr.val() > 0 ) @@ -4514,9 +4517,9 @@ PlentyFramework.cssClasses = { requestData[value.attr( "name" )] = value.val(); } ); } - else if ( $unitCombinationId && $unitCombinationId.val() > 0 ) + else if ( $unitCombinationId && $unitCombinationId > 0 ) { - requestData["UnitCombinationId"] = $unitCombinationId.val(); + requestData["UnitCombinationId"] = $unitCombinationId; } refreshBasketPreview(); diff --git a/dist/plentymarketsCMStools-1.0.12.min.js b/dist/plentymarketsCMStools-1.0.12.min.js new file mode 100644 index 0000000..09bb229 --- /dev/null +++ b/dist/plentymarketsCMStools-1.0.12.min.js @@ -0,0 +1,12 @@ +/** + * Licensed under AGPL v3 + * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE) + * ===================================================================================== + * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com) + * @author Felix Dausch + * ===================================================================================== +*/ +var TemplateCache={};TemplateCache["addressSuggestions/addressDoctor.html"]='',TemplateCache["addressSuggestions/postFinder.html"]='{{#addresses}}\n
    \n
    \n \n
    \n
    \n{{/addresses}}\n',TemplateCache["error/errorMessage.html"]='
    \n Code {{code}}:\n {{{message}}}\n
    \n',TemplateCache["error/errorPopup.html"]='
    \n \n
    \n
    \n
    \n',TemplateCache["modal/modal.html"]='\n',TemplateCache["waitscreen/waitscreen.html"]='
    ',function(a,b){"object"==typeof exports&&exports&&"string"!=typeof exports.nodeName?b(exports):"function"==typeof define&&define.amd?define(["exports"],b):(a.Mustache={},b(Mustache))}(this,function(a){function b(a){return"function"==typeof a}function c(a){return p(a)?"array":typeof a}function d(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function e(a,b){return null!=a&&"object"==typeof a&&b in a}function f(a,b){return q.call(a,b)}function g(a){return!f(r,a)}function h(a){return String(a).replace(/[&<>"'\/]/g,function(a){return s[a]})}function i(b,c){function e(){if(r&&!s)for(;q.length;)delete o[q.pop()];else q=[];r=!1,s=!1}function f(a){if("string"==typeof a&&(a=a.split(u,2)),!p(a)||2!==a.length)throw new Error("Invalid tags: "+a);h=new RegExp(d(a[0])+"\\s*"),i=new RegExp("\\s*"+d(a[1])),m=new RegExp("\\s*"+d("}"+a[1]))}if(!b)return[];var h,i,m,n=[],o=[],q=[],r=!1,s=!1;f(c||a.tags);for(var y,z,A,B,C,D,E=new l(b);!E.eos();){if(y=E.pos,A=E.scanUntil(h))for(var F=0,G=A.length;G>F;++F)B=A.charAt(F),g(B)?q.push(o.length):s=!0,o.push(["text",B,y,y+1]),y+=1,"\n"===B&&e();if(!E.scan(h))break;if(r=!0,z=E.scan(x)||"name",E.scan(t),"="===z?(A=E.scanUntil(v),E.scan(v),E.scanUntil(i)):"{"===z?(A=E.scanUntil(m),E.scan(w),E.scanUntil(i),z="&"):A=E.scanUntil(i),!E.scan(i))throw new Error("Unclosed tag at "+E.pos);if(C=[z,A,y,E.pos],o.push(C),"#"===z||"^"===z)n.push(C);else if("/"===z){if(D=n.pop(),!D)throw new Error('Unopened section "'+A+'" at '+y);if(D[1]!==A)throw new Error('Unclosed section "'+D[1]+'" at '+y)}else"name"===z||"{"===z||"&"===z?s=!0:"="===z&&f(A)}if(D=n.pop())throw new Error('Unclosed section "'+D[1]+'" at '+E.pos);return k(j(o))}function j(a){for(var b,c,d=[],e=0,f=a.length;f>e;++e)b=a[e],b&&("text"===b[0]&&c&&"text"===c[0]?(c[1]+=b[1],c[3]=b[3]):(d.push(b),c=b));return d}function k(a){for(var b,c,d=[],e=d,f=[],g=0,h=a.length;h>g;++g)switch(b=a[g],b[0]){case"#":case"^":e.push(b),f.push(b),e=b[4]=[];break;case"/":c=f.pop(),c[5]=b[2],e=f.length>0?f[f.length-1][4]:d;break;default:e.push(b)}return d}function l(a){this.string=a,this.tail=a,this.pos=0}function m(a,b){this.view=a,this.cache={".":this.view},this.parent=b}function n(){this.cache={}}var o=Object.prototype.toString,p=Array.isArray||function(a){return"[object Array]"===o.call(a)},q=RegExp.prototype.test,r=/\S/,s={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},t=/\s*/,u=/\s+/,v=/\s*=/,w=/\s*\}/,x=/#|\^|\/|>|\{|&|=|!/;l.prototype.eos=function(){return""===this.tail},l.prototype.scan=function(a){var b=this.tail.match(a);if(!b||0!==b.index)return"";var c=b[0];return this.tail=this.tail.substring(c.length),this.pos+=c.length,c},l.prototype.scanUntil=function(a){var b,c=this.tail.search(a);switch(c){case-1:b=this.tail,this.tail="";break;case 0:b="";break;default:b=this.tail.substring(0,c),this.tail=this.tail.substring(c)}return this.pos+=b.length,b},m.prototype.push=function(a){return new m(a,this)},m.prototype.lookup=function(a){var c,d=this.cache;if(d.hasOwnProperty(a))c=d[a];else{for(var f,g,h=this,i=!1;h;){if(a.indexOf(".")>0)for(c=h.view,f=a.split("."),g=0;null!=c&&gi;++i)g=void 0,e=a[i],f=e[0],"#"===f?g=this.renderSection(e,b,c,d):"^"===f?g=this.renderInverted(e,b,c,d):">"===f?g=this.renderPartial(e,b,c,d):"&"===f?g=this.unescapedValue(e,b):"name"===f?g=this.escapedValue(e,b):"text"===f&&(g=this.rawValue(e)),void 0!==g&&(h+=g);return h},n.prototype.renderSection=function(a,c,d,e){function f(a){return g.render(a,c,d)}var g=this,h="",i=c.lookup(a[1]);if(i){if(p(i))for(var j=0,k=i.length;k>j;++j)h+=this.renderTokens(a[4],c.push(i[j]),d,e);else if("object"==typeof i||"string"==typeof i||"number"==typeof i)h+=this.renderTokens(a[4],c.push(i),d,e);else if(b(i)){if("string"!=typeof e)throw new Error("Cannot use higher-order sections without the original template");i=i.call(c.view,e.slice(a[3],a[5]),f),null!=i&&(h+=i)}else h+=this.renderTokens(a[4],c,d,e);return h}},n.prototype.renderInverted=function(a,b,c,d){var e=b.lookup(a[1]);return!e||p(e)&&0===e.length?this.renderTokens(a[4],b,c,d):void 0},n.prototype.renderPartial=function(a,c,d){if(d){var e=b(d)?d(a[1]):d[a[1]];return null!=e?this.renderTokens(this.parse(e),c,d,e):void 0}},n.prototype.unescapedValue=function(a,b){var c=b.lookup(a[1]);return null!=c?c:void 0},n.prototype.escapedValue=function(b,c){var d=c.lookup(b[1]);return null!=d?a.escape(d):void 0},n.prototype.rawValue=function(a){return a[1]},a.name="mustache.js",a.version="2.1.3",a.tags=["{{","}}"];var y=new n;a.clearCache=function(){return y.clearCache()},a.parse=function(a,b){return y.parse(a,b)},a.render=function(a,b,d){if("string"!=typeof a)throw new TypeError('Invalid template! Template should be a "string" but "'+c(a)+'" was given as the first argument for mustache#render(template, view, partials)');return y.render(a,b,d)},a.to_html=function(c,d,e,f){var g=a.render(c,d,e);return b(f)?void f(g):g},a.escape=h,a.Scanner=l,a.Context=m,a.Writer=n}),function(a){function b(a,b,c,d){a.on(b,function(a){return i.push(a),c.apply(null,d)}),"complete"===document.readyState&&"ready"===b&&c.apply(null,d)}function c(b){var c=a(b);c.is('input[type="checkbox"]')&&c.on("change",function(){c.is(":checked")?c.trigger("check"):c.trigger("uncheck")}),c.is('input[type="radio"]')&&c.on("change",function(){var b=c.attr("name");a('input[type="radio"][name="'+b+'"]').each(function(b,c){var d=a(c);d.is(":checked")?d.trigger("check"):d.trigger("uncheck")})})}function d(a,b){for(var c=/^(([\w]+):)?([\w]+)\.([\w]+)(\((.*)\))?$/,d=a.split(";"),e=[],f=0;f0)for(var j=h[6].match(/(['][^']+['])|([\w-]+)|(["][^"]+["])/g),k=0;k=c&&g.services.hasOwnProperty(i)){PlentyFramework.prototype.hasOwnProperty(i)||e(g.services[i],2,d),f.push(PlentyFramework.prototype[i]);continue}if(1>=c&&g.directives.hasOwnProperty(i)){PlentyFramework.directives.hasOwnProperty(i)||e(g.directives[i],1,d),f.push(PlentyFramework.directives[i]);continue}console.error('Cannot inject dependency "'+i+'": Object not found.')}else console.error("Cyclic dependency injection: "+d.join(" -> ")+" -> "+i)}3==c?PlentyFramework.factories[b.name]=b.setup.apply(null,f):2==c?PlentyFramework.prototype[b.name]=b.setup.apply(null,f):1==c&&(PlentyFramework.directives[b.name]=b.setup.apply(null,f))}var f="1.0.12",g={factories:{},services:{},directives:{}};PlentyFramework=function(){};var h=null;PlentyFramework.getInstance=function(){return h=h||new PlentyFramework},PlentyFramework.version=function(){function a(a){for(var b=f.split("."),c=a.split("."),d=0;dparseInt(c[d]))return 1}return 0}return{get:function(){return f},equals:function(b){return 0==a(b)},compare:a}}(),PlentyFramework.partials={},PlentyFramework.globals={},PlentyFramework.setGlobal=function(a,b){return PlentyFramework.globals.hasOwnProperty(a)?(console.error('Global variable "'+a+'" already exists and cannot be overridden.'),null):(PlentyFramework.globals[a]=b,PlentyFramework.globals[a])},PlentyFramework.getGlobal=function(a,b){return PlentyFramework.globals.hasOwnProperty(a)?PlentyFramework.globals[a]:b},PlentyFramework.directives={},PlentyFramework.directive=function(a,b,c){return"string"!=typeof a?void console.error("Type mismatch: Expect first parameter to be a 'string', '"+typeof a+"' given."):"function"!=typeof b?void console.error("Type mismatch: Expect second parameter to be a 'function', '"+typeof b+"' given."):(c=c||[],void(g.directives[a]={name:a,dependencies:c,setup:b}))},PlentyFramework.prototype.bindDirectives=function(e){e=e||"html",a(e).find("[data-plenty]").each(function(e,f){var g=d(a(f).attr("data-plenty"),a(f));if(!(g.length<=0)){c(f);for(var e=0;e=0;c--)if(a==i[c].type)return i[c];return null},PlentyFramework.pushEvent=function(a){i.push(a)},PlentyFramework.service=function(a,b,c){return"string"!=typeof a?void console.error("Type mismatch: Expect first parameter to be a 'string', '"+typeof a+"' given."):"function"!=typeof b?void console.error("Type mismatch: Expect second parameter to be a 'function', '"+typeof b+"' given."):(c=c||[],void(g.services[a]={name:a,dependencies:c,setup:b}))},PlentyFramework.factories={},PlentyFramework.factory=function(a,b,c){return"string"!=typeof a?void console.error("Type mismatch: Expect first parameter to be a 'string', '"+typeof a+"' given."):"function"!=typeof b?void console.error("Type mismatch: Expect second parameter to be a 'function', '"+typeof b+"' given."):(c=c||[],void(g.factories[a]={name:a,dependencies:c,setup:b}))},PlentyFramework.compileTemplate=function(a,b){return b=b||{},b.translate=function(){return function(a,b){return b(PlentyFramework.translate(a))}},Mustache.render(TemplateCache[a],b)},PlentyFramework.scriptPath="",PlentyFramework.Strings={},PlentyFramework.loadLanguageFile=function(b){a.ajax({url:PlentyFramework.scriptPath+b,dataType:"json"}).done(function(a){PlentyFramework.Strings=a})},PlentyFramework.translate=function(a,b){var c;return PlentyFramework.Strings.hasOwnProperty(a)?c=PlentyFramework.Strings[a]:(c=a,console.warn('No translation found for "'+c+'".')),b&&(c=Mustache.render(c,b)),c},PlentyFramework.compile=function(){for(var a in g.factories)PlentyFramework.factories.hasOwnProperty(a)||e(g.factories[a],3);for(var b in g.services)PlentyFramework.prototype.hasOwnProperty(b)||e(g.services[b],2);for(var c in g.directives)PlentyFramework.directives.hasOwnProperty(c)||e(g.directives[c],1);for(var d=document.getElementsByTagName("SCRIPT"),f=d.length-1;f>=0;f--){var h=d[f].src.match(/(.*)\/(.*)\.js(\?\S*)?$/);if(h){PlentyFramework.scriptPath=h[1];break}}}}(jQuery),function(a,b){b.directive("Authentication",function(c){function d(d){b.getRecentEvent().preventDefault(),c.customerLogin(a(d))}return{login:d}},["AuthenticationService"])}(jQuery,PlentyFramework),function(a,b){b.directive("Basket",function(c){function d(d){b.getRecentEvent().preventDefault();var e={},f=a(d),g=f.parents("form"),h=g.find('[name="P_ID"]:checked');e.BasketItemItemID=g.find('[name="ArticleID"]').val(),e.BasketItemPriceID=g.find('[name="SYS_P_ID"]').val(),e.BasketItemQuantity=g.find('[name="ArticleQuantity"]').val(),e.BasketItemBranchID=g.find('[name="source_category"]').val(),h.length>0&&h.val()>0&&(e.BasketItemPriceID=h.val());var i=g.find('[name^="ArticleAttribute"]'),j=[];a.each(i,function(b,c){var d=c.name.match(/^ArticleAttribute\[\d+]\[\d+]\[(\d+)]$/);d&&d[1]&&j.push({BasketItemAttributeID:d[1],BasketItemAttributeValueID:a(c).val()})}),0!=j.length&&(e.BasketItemAttributesList=j),c.addItem([e])}function e(b,c){var d=a(b),e=d.parent().find("input"),f=parseInt(e.attr("maxlength"))||5,g=parseInt(e.val())+c,h=d.parents("[data-basket-item-id]").length>0;if(h){(g+"").length<=f&&g>=0&&e.val(g);var i=d.data("timeout");i&&window.clearTimeout(i),i=window.setTimeout(function(){e.trigger("change")},1e3),d.data("timeout",i)}else(g+"").length<=f&&g>=1&&e.val(g)}function f(b,d){c.setItemQuantity(b,parseInt(a(d).val())).fail(function(){var e=c.getItem(b);a(d).val(e.BasketItemQuantity)})}return{addBasketItem:d,changeItemQuantity:e,setItemQuantity:f}},["BasketService"])}(jQuery,PlentyFramework),function(a,b){b.directive("Checkout",function(a){function b(b){a.setMethodOfPayment(b)}function c(b){a.confirmAtrigaPaymax(b)}return{setMethodOfPayment:b,confirmAtrigaPaymax:c}},["CheckoutService"])}(jQuery,PlentyFramework),function(a,b){b.directive("MobileDropdown",function(c){function d(){a(window).on("orientationchange sizeChange",function(){a("input").is(":focus")||(e(k),e(l))})}function e(b,c){for(var d,e=0;e0?window.location.assign(a(c).attr("href")):window.location.assign(c))}function e(a){c.goToID(a)}return{to:d,toCheckoutTab:e}},["MediaSizeService","NavigatorService"])}(jQuery,PlentyFramework),function(a,b){b.directive("Tab",function(c){function d(b){a(b).tab("show")}function e(a,b,c){j[c]||(j[c]=new h),j[c].getTab(b)||j[c].addTab(b),j[c].getTab(b).addLabel(a)}function f(a,b,c){j[c]||(j[c]=new h),j[c].getTab(b)||j[c].addTab(b),j[c].getTab(b).setContent(a)}function g(a,d,e){c.isInterval(e)&&(b.getRecentEvent().preventDefault(),j[d]&&j[d].getTab(a)&&j[d].showTab(a))}function h(){function b(a){return g[a]=new i(a),g[a]}function c(b){var c=0;if(f)c=parseInt(f.getContent().parent().css("zIndex")),f.hide(),f.getContent().parent().css("zIndex",c-1);else{for(var d in g)if(g[d].getContent()){var h=parseInt(g[d].getContent().parent().css("zIndex"));(0==c||c>h)&&(c=h),g[d].hide()}for(var d in g)g[d].getContent()&&g[d].getContent().parent().css("zIndex",c-1);a(window).on("sizeChange",e)}f=g[b],f.getContent().parent().css("zIndex",c),f.show()}function d(a){return g[a]}function e(){for(var a in g)g[a].getContent()&&g[a].show();f=null}var f,g={};return{addTab:b,showTab:c,getTab:d,resetTabs:e}}function i(a){function b(){return j}function c(a){return i.push(a),this}function d(a){return h=a,this}function e(){return h}function f(){for(var a=0;a0&&(a(document).scrollTop()>100?x(z,"addClass","visible"):x(z,"removeClass","visible"))})}function g(){e.showWaitscreen()}function h(a){e.hideWaitscreen(a)}function i(b){a(b).owlCarousel({navigation:!0,navigationText:!1,slideSpeed:1e3,paginationSpeed:1e3,singleItem:!0,autoPlay:6e3,stopOnHover:!0,afterMove:function(b){a(b).find('[data-plenty-rel="lazyload"]').trigger("appear")}})}function j(b,d,e){var f=a(b),g=0,h={},i=f.find('[data-plenty-rel="equal-target"]').length>0?f.find('[data-plenty-rel="equal-target"]'):f.children();e!==!0&&y.push(b);for(var j=i.length;j>=0;j--)h=a(i[j]),h.css("height",""),h.outerHeight(!0)>g&&(g=h.outerHeight(!0));(!d||c.isInterval(d))&&i.height(g)}function k(b){var c=a(b);c.click(function(){return a("html, body").animate({scrollTop:0},400),!1}),a.inArray(c,z)&&z.push(c)}function l(b,c){var d=a(b);d.lazyload({effect:c}),d.is("img")&&d.on("loaded",function(){d.css("display","inline-block")})}function m(b){console.log(b);var c=a(b),d=c.parent();d.addClass("animating"),c.siblings("ul").slideToggle(200,function(){d.is(".open")?d.removeClass("open"):d.addClass("open"),c.siblings("ul").removeAttr("style"),d.removeClass("animating")})}function n(b,c){var d=a(b),e=a(d.attr("data-plenty-rel"));if(d.is('input[type="radio"]')){var f=a('input[type="radio"][name="'+d.attr("name")+'"]'),g=!c||"checked"==c;f.change(function(){var b=a(this);e.parents('[data-plenty-rel="equal-target"]').css("height","auto"),b.is(":checked")&&b[0]===d[0]&&1==g?e.slideDown(400,function(){w()}):e.slideUp(400,function(){w()})})}else d.click(function(){d.addClass("animating"),e.slideToggle(400,function(){d.removeClass("animating"),d.toggleClass("active"),w()})})}function o(b,c){r(a(b),c,"slideDown")}function p(b,c){r(a(b),c,"slideUp")}function q(b,c){r(a(b),c,"slideToggle")}function r(a,b,c){b=b||400,a.parents('[data-plenty-rel="equal-target"]').css("height","auto"),a[c](b,function(){w()})}function s(b,c){var e=a(b),f=e.find('[data-plenty-rel="social-switch"]');e.append(''),f.is("off, on")||f.addClass("off"),f.on("click",function(){f.hasClass("off")&&("tooltip"==e.attr("data-toggle")&&e.tooltip("destroy"),f.removeClass("off").addClass("on"),e.find('[data-plenty-rel="social-placeholder"]').hide(),e.find(".social-container").append(d.getSocialService(c)))})}function t(d,e,f){var g=a(e);if(g.parents(".navbar-main").length>0){var h=g.children("span");return b.directives.MobileDropdown.slideDropdown(h),!0}if(e&&d&&(!f||c.isInterval(f))){var i=b.getRecentEvent();return i&&i.preventDefault(),g.toggleClass(d),!1}}function u(d,e,f){if(e&&d&&(!f||c.isInterval(f))){var g=b.getRecentEvent();return g&&g.preventDefault(),a(e).addClass(d),!1}}function v(d,e,f){if(e&&d&&(!f||c.isInterval(f))){var g=b.getRecentEvent();return g&&g.preventDefault(),a(e).removeClass(d),!1}}function w(){for(var a=y.length-1;a>=0;a--)j(y[a],"",!0)}function x(a,b,c){for(var d=a.length-1;d>=0;d--)a[d][b](c)}var y=[],z=[];return{initUIWindowEvents:f,showWaitscreen:g,hideWaitscreen:h,addContentPageSlider:i,equalHeight:j,initToTop:k,initLazyload:l,initSlideToggle:n,slideDown:o,slideUp:p,slideToggle:q,toggleHideShow:m,toggleSocialShare:s,toggleClass:t,addClass:u,removeClass:v}},["MediaSizeService","SocialShareService","UIFactory"])}(jQuery,PlentyFramework),function(a,b){b.directive("Validator",function(a){function b(b,c){return a.validate(b,c)}return{validate:b}},["ValidationService"])}(jQuery,PlentyFramework),function(a,b){b.factory("APIFactory",function(c,d){function e(){b.getGlobal("LoginSession")&&(l&&clearTimeout(l),l=setTimeout(function(){a(window).trigger("login-expired"),"Checkout"===b.getGlobal("PageDesign")&&d.prepare().setTitle(b.translate("Your session has expired.")).setContent(b.translate("Please log in again to continue shopping.")).setLabelDismiss(null).setLabelConfirm(b.translate("OK")).onConfirm(function(){window.location.assign("/")}).onDismiss(function(){window.location.assign("/")}).show()},b.getGlobal("LoginSessionExpiration")))}function f(b){try{var d=a.parseJSON(b.responseText);c.printErrors(d.error.error_stack)}catch(e){c.throwError(b.status,b.statusText)}}function g(b,d,g,h,i){return h||c.showWaitScreen(),a.ajax(b,{type:"GET",data:d,dataType:"json",async:!i,error:function(a){g||f(a)}}).always(function(){h||c.hideWaitScreen(),e()})}function h(b,d,g,h){var i={type:"POST",dataType:"json",error:function(a){g||f(a)}};return d&&d.isFile?(i.cache=d.cache,i.processData=d.processData,i.data=d.data,i.contentType=!1):(i.data=JSON.stringify(d),i.contentType="application/json"),h||c.showWaitScreen(),a.ajax(b,i).always(function(){h||c.hideWaitScreen(),e()})}function i(b,d,g,h){return h||c.showWaitScreen(),a.ajax(b,{type:"PUT",data:JSON.stringify(d),dataType:"json",contentType:"application/json",error:function(a){g||f(a)}}).always(function(){h||c.hideWaitScreen(),e()})}function j(b,d,g,h){return h||c.showWaitScreen(),a.ajax(b,{type:"DELETE",data:JSON.stringify(d),dataType:"json",contentType:"application/json",error:function(a){g||f(a)}}).always(function(){h||c.hideWaitScreen(),e()})}function k(){return a.Deferred().resolve()}var l=null;return a(document).ready(function(){e()}),{get:g,post:h,put:i,"delete":j,idle:k}},["UIFactory","ModalFactory"])}(jQuery,PlentyFramework),function(a){a.factory("CMSFactory",function(a){function b(b,c){function d(d){return a.get("/rest/"+d.toLowerCase()+"/container_"+b.toLowerCase()+"/",c)}return{from:d}}function c(b,c){function d(d){return a.get("/rest/"+d.toLowerCase()+"/"+b.toLowerCase()+"/",c)}return{from:d}}function d(b){return a.get("/rest/categoryview/categorycontentbody/?categoryID="+b)}return{getContainer:b,getParams:c,getCategoryContent:d}},["APIFactory"])}(PlentyFramework),function(a){a.factory("CheckoutFactory",function(b,c,d){function e(){return l}function f(a){return m&&l||g(!0),a?$.extend(!0,{},l):m}function g(a){return b.get("/rest/checkout/",null,!1,!1,a).done(function(a){a?(l=a.data,m=new e):d.throwError(0,'Could not receive checkout data [GET "/rest/checkout/" receives null value]')})}function h(){return b.put("/rest/checkout",m).done(function(a){a?(l=a.data,m=new e):d.throwError(0,'Could not receive checkout data [GET "/rest/checkout/" receives null value]')})}function i(b){return c.getContainer("checkout"+b).from("checkout").done(function(c){$('[data-plenty-checkout-template="'+b+'"]').each(function(b,d){$(d).html(c.data[0]),a.getInstance().bindDirectives(d),$(window).trigger("contentChanged")})})}function j(b){return c.getCategoryContent(b).done(function(c){$('[data-plenty-checkout-catcontent="'+b+'"]').each(function(b,d){$(d).html(c.data[0]),a.getInstance().bindDirectives(d),$(window).trigger("contentChanged")})})}function k(b){return c.getContainer("itemview"+b).from("itemview").done(function(c){$('[data-plenty-itemview-template="'+b+'"]').each(function(b,d){$(d).html(c.data[0]),a.getInstance().bindDirectives(d),$(window).trigger("contentChanged")})})}var l,m;return{getCheckout:f,setCheckout:h,loadCheckout:g,reloadContainer:i,reloadCatContent:j,reloadItemContainer:k}},["APIFactory","CMSFactory","UIFactory"])}(PlentyFramework),function(a,b){b.factory("ModalFactory",function(){function c(a){return PlentyFramework.partials.Modal.isModal(a)}function d(a){return new e(a)}function e(d){function e(a){return t.title=a,this}function f(a){return t.cssClass=a,this}function g(a){return t.content=a,this}function h(a){return t.labelConfirm=a,this}function i(a){return t.labelDismiss=a,this}function j(a){return t.onConfirm=a,this}function k(a){return t.onDismiss=a,this}function l(a){return t.container=a,this}function m(a){return t.timeout=a,this}function n(){if(t.selector)u=a(t.selector);else{u=c(t.content)?PlentyFramework.partials.Modal.getModal(t.content):a(PlentyFramework.compileTemplate("modal/modal.html",t)),a(t.container).append(u);var b=a(t.content).filter("script");b.length>0&&b.each(function(b,c){var d=document.createElement("script");d.type="text/javascript",d.innerHTML=a(c).text(),a(t.container).append(d)})}PlentyFramework.partials.Modal.init(u,t),u.find('[data-plenty-modal="confirm"]').click(function(){var a=t.onConfirm();"undefined"==typeof a&&(a=!0),a&&o(!0)}),PlentyFramework.partials.Modal.show(u),t.timeout>0&&p()}function o(a){PlentyFramework.partials.Modal.hide(u),a||t.onDismiss()}function p(){x=t.timeout,y=(new Date).getTime(),v=window.setTimeout(function(){window.clearInterval(w),o()},t.timeout),u.find('[data-plenty-modal="timer"]').text(x/1e3),w=window.setInterval(function(){if(!z){var a=x-(new Date).getTime()+y;a=Math.round(a/1e3),u.find('[data-plenty-modal="timer"]').text(a)}},1e3)}function q(){z=!0,x-=(new Date).getTime()-y,window.clearTimeout(v)}function r(){z=!1,y=(new Date).getTime(),v=window.setTimeout(function(){o(),window.clearInterval(w)},x)}function s(){window.clearTimeout(v),window.clearInterval(w)}var t=this;t.selector=d,t.title="",t.cssClass="",t.content="",t.labelDismiss=b.translate("Cancel"),t.labelConfirm=b.translate("Confirm"),t.onConfirm=function(){},t.onDismiss=function(){},t.container="body",t.timeout=-1,t.hide=o,t.startTimeout=p,t.stopTimeout=s,t.pauseTimeout=q,t.continueTimeout=r;var u,v,w,x,y,z=!1;return{setTitle:e,setClass:f,setContent:g,setContainer:l,setLabelConfirm:h,setLabelDismiss:i,onConfirm:j,onDismiss:k,setTimeout:m,show:n,hide:o}}return{prepare:d,isModal:c}})}(jQuery,PlentyFramework),function(a,b){b.factory("UIFactory",function(){function c(a,b){d([{code:a,message:b}])}function d(c){(!i||a("body").has(i).length<=0)&&(i=a(b.compileTemplate("error/errorPopup.html")),a("body").append(i),b.partials.Error.init(i)),a.each(c,function(c,d){b.partials.Error.addError(i,a(b.compileTemplate("error/errorMessage.html",d)))}),b.partials.Error.show(i),f(!0)}function e(){return h=h||0,(!g||a("body").has(g).length<=0)&&(g=a(b.compileTemplate("waitscreen/waitscreen.html")),a("body").append(g)),b.partials.WaitScreen.show(g),h++,h}function f(a){return h--,(0>=h||a)&&(h=0,b.partials.WaitScreen.hide(g)),h}var g,h=0,i=null;return{throwError:c,printErrors:d,showWaitScreen:e,hideWaitScreen:f}})}(jQuery,PlentyFramework),Object.equals=function(a,b){if(a===b)return!0;if(!(a instanceof Object&&b instanceof Object))return!1;if(a.constructor!==b.constructor)return!1;for(var c in a)if(a.hasOwnProperty(c)){if(!b.hasOwnProperty(c))return!1;if(a[c]!==b[c]){if("object"!=typeof a[c])return!1;if(!Object.equals(a[c],b[c]))return!1}}for(var c in b)if(b.hasOwnProperty(c)&&!a.hasOwnProperty(c))return!1;return!0},PlentyFramework.cssClasses={active:"active"},function(a,b){b.partials.Error={init:function(c){a(c).find(".close").click(function(){b.partials.Error.hideAll()})},addError:function(b,c){var d=a(c).attr("data-plenty-error-code");a(b).find('[data-plenty-error-code="'+d+'"]').length<=0&&a(b).find(".plentyErrorBoxInner").append(c)},show:function(b){a(b).show()},hideAll:function(){a("#CheckoutErrorPane").hide(),a("#CheckoutErrorPane").find(".plentyErrorBoxInner").html("")}}}(jQuery,PlentyFramework),function(a,b){b.partials.Modal={init:function(a,b){a.on("hidden.bs.modal",function(){b.hide(),b.selector||a.remove()}),b.timeout>0&&(a.on("hide.bs.modal",b.stopTimeout),a.find(".modal-content").hover(function(){b.pauseTimeout()},function(){a.is(".in")&&b.continueTimeout()}))},show:function(a){a.modal("show")},hide:function(a){a.modal("hide")},isModal:function(b){return a(b).filter(".modal").length+a(b).find(".modal").length>0},getModal:function(b){var c=a(b);return c.length>1&&(c=a(b).filter(".modal")||a(b).find(".modal")),c}}}(jQuery,PlentyFramework),function(a){a(document).on("initPartials",function(b,c){a(c).find('[data-toggle="tooltip"]').tooltip({container:"body"})})}(jQuery),function(a,b){b.partials.WaitScreen={show:function(a){a.addClass("in")},hide:function(a){a.removeClass("in")}}}(jQuery,PlentyFramework),function(a,b){b.service("AddressDoctorService",function(c){function d(b){var c=!0;return b=b||"[data-plenty-address-doctor]",a(b).filter("[data-plenty-address-doctor]:visible").each(function(b,d){var f=new e(d),g=a(d).attr("data-plenty-address-doctor").replace(/\s/g,"").split(",");f.isValid(g)||(c=!1)}),c}function e(c){function d(a){return j()?!0:(k=new f(m.getFormValues()),l=a,e(),1==k.getAddresses().length)}function e(){a(".suggestion-list").remove();for(var b=!1,c=0;cc;c++){var d=a.data[c],f=e(d);f?f.HouseNo.push(d.HouseNo):(d.HouseNo=[d.HouseNo],j.push(d))}})}function e(a){for(var b=j.length,c=0;b>c;c++)if(a.Street==j[c].Street&&j.ZIP==j[c].ZIP&&a.City==j[c].City)return j[c];return null}function f(){return j}function g(b){for(var c=[],d=j.length,e=0;d>e;e++){var f=j[e];a.inArray(f[b],c)<0&&c.push(f[b])}return c}function h(a){for(var b=[],c=j.length,d=0;c>d;d++){var e=j[d];(a.Street&&a.Street==e.Street||a.ZIP&&a.ZIP==e.ZIP||a.City&&a.City==e.City)&&b.push(e)}j=b}function i(a){a=parseInt(a);for(var b=j.length,c=0;b>c;c++)for(var d=j[c],e=0;e=f[0]&&a<=f[1])return!0}return!1}var j=[];return d(),{getAddresses:f,getList:g,filter:h,houseNoAllowed:i}}return{validateAddress:d}},["APIFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("AuthenticationService",function(c,d,e){function f(){var b=a('[data-plenty-checkout="lostPasswordForm"]');if(b.validateForm()){var d=b.getFormValues(),e={Email:d.Email};return c.post("/rest/checkout/lostpassword/",e).done(function(b){1==b.data.IsMailSend&&(a('[data-plenty-checkout="lostPasswordTextContainer"]').hide(),a('[data-plenty-checkout="lostPasswordSuccessMessage"]').show())})}}function g(a){if(a.validateForm()){var b=a.getFormValues(),d={Email:b.loginMail,Password:b.loginPassword};return e.showWaitScreen(),c.post("/rest/checkout/login/",d).done(function(){window.location.assign(a.attr("action"))})}}function h(a){return c.post("/rest/checkout/customerinvoiceaddress/",a).done(function(a){d.getCheckout().CustomerInvoiceAddress=a.data})}function i(){var c=a('[data-plenty-checkout-form="customerRegistration"]');if(c.validateForm()&&b.getInstance().AddressDoctorService.validateAddress()){var d=c.getFormValues();if(d.LoginType=2,d.checkout&&d.checkout.customerInvoiceAddress&&d.checkout.customerInvoiceAddress.CustomerProperty){var e=d.checkout.customerInvoiceAddress.CustomerProperty;d.CustomerPropertiesList=d.CustomerPropertiesList||[];for(var f in e)e[f]&&d.CustomerPropertiesList.push({PropertyID:f,PropertyValue:e[f]})}return h(d).done(function(){window.location.assign(c.attr("action"))})}}return{resetPassword:f,customerLogin:g,setInvoiceAddress:h,registerCustomer:i}},["APIFactory","CheckoutFactory","UIFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("BasketService",function(c,d,e,f,g){function h(d){d&&c.get("/rest/checkout/container_"+"CheckoutOrderParamsList".toLowerCase()+"/",{itemID:d[0].BasketItemItemID,quantity:d[0].BasketItemQuantity},!1,!0).done(function(c){c.data[0].indexOf("form-group")>0?g.prepare().setContent(c.data[0]).setTitle(b.translate("Select order parameters")).setLabelConfirm(b.translate("Save")).onConfirm(function(){return a('[data-plenty-checkout-form="OrderParamsForm"]').validateForm()?(j(i(d)),!0):!1}).show():j(d)})}function i(b){var c,d=a('[data-plenty-checkout-form="OrderParamsForm"]'),e={},f="";return d.find('[name^="ParamGroup"]').each(function(){c=this.name.match(/^ParamGroup\[(\d+)]\[(\d+)]$/),b=m(b,c[1],a(this).val(),a(this).val())}),d.find('[name^="ParamValue"]').each(function(){if(e=a(this),f=e.attr("type"),("checkbox"==f&&e.is(":checked")||"radio"==f&&e.is(":checked")||"radio"!=f&&"checkbox"!=f)&&"file"!=f&&"hidden"!=f){var c=e[0].name.match(/^ParamValue\[(\d+)]\[(\d+)]$/);b=m(b,c[1],c[2],e.val())}else if("file"==f)if(e[0].files&&e[0].files.length>0)b=l(e,b);else{var c=e[0].name.match(/^ParamValueFile\[(\d+)]\[(\d+)]$/),d=a('input[type="hidden"][name="ParamValue['+c[1]+"]["+c[2]+']"]').val();b=m(b,c[1],c[2],d)}}),b}function j(h){c.post("/rest/checkout/basketitemslist/",h,!0).done(function(){f.loadCheckout().done(function(){var c=a("[name^=ArticleAttribute]"),d=h[0].BasketItemPriceID,f={ArticleID:h[0].BasketItemItemID};c.val()>0?c.each(function(b,c){c=a(c),f[c.attr("name")]=c.val()}):d&&d>0&&(f.UnitCombinationId=d),s(),e.getContainer("ItemViewItemToBasketConfirmationOverlay",f).from("ItemView").done(function(a){var c=b.getGlobal("TimeoutItemToBasketOverlay",5e3),d=g.prepare().setContent(a.data[0]);c>0&&d.setTimeout(c),d.show()})})}).fail(function(a){d.printErrors(JSON.parse(a.responseText).error.error_stack)})}function k(a){c.put("/rest/checkout/basketitemslist/",a).done(function(){f.reloadCatContent(b.getGlobal("basketCatID")),f.loadCheckout().done(function(){s()})})}function l(a,b){var d,e,f=a[0].id,g={},h=[],i={type:"POST",data:{},isFile:!0,cache:!1,dataType:"json",processData:!1,contentType:!1};g[f]=a[0].files,-1==h.indexOf(f)&&h.push(f);for(var j=0,k=h.length;k>j;++j)d=new FormData,e=g[h[j]],d.append("0",e[0],e[0].name),i.data=d,c.post("/rest/checkout/orderparamfile/",i);var l=a[0].name.match(/^ParamValueFile\[(\d+)]\[(\d+)]$/);return m(b,l[1],l[2],g[f][0].name)}function m(b,c,d,e){return c>0&&void 0==b[c]&&(b[c]=a.extend(!0,{},b[0]),b[c].BasketItemOrderParamsList=[]),void 0!=b[c]&&(b[c].BasketItemQuantity=1,void 0==b[c].BasketItemOrderParamsList&&(b[c].BasketItemOrderParamsList=[]),e&&b[c].BasketItemOrderParamsList.push({BasketItemOrderParamID:d,BasketItemOrderParamValue:e})),b}function n(b){var c=a('[data-plenty-basket-item="'+b+'"]');c.modal("show"),c.find('[data-plenty-modal="confirm"]').on("click",function(){var d=p(b),e=[];c.find('select, .PlentyFormContainer.AttrImage > input[type="hidden"]').each(function(b,c){var d=c.name.match(/^ArticleAttribute\[\d+]\[\d+]\[(\d+)]$/);d&&d[1]&&e.push({BasketItemAttributeID:d[1],BasketItemAttributeValueID:a(c).val()})}),0!=e.length&&(d.BasketItemAttributesList=e),k([d])})}function o(d){var e=p(d);e.BasketItemOrderParamsList=[],c.get("/rest/checkout/container_"+"CheckoutOrderParamsList".toLowerCase()+"/",{itemID:e.BasketItemItemID,quantity:e.BasketItemQuantity,basketItemID:d}).done(function(c){g.prepare().setContent(c.data[0]).setTitle(b.translate("Edit order parameters")).setLabelConfirm(b.translate("Save")).onConfirm(function(){return a('[data-plenty-checkout-form="OrderParamsForm"]').validateForm()?(k(i([e])),!0):!1}).show()})}function p(a){for(var b=f.getCheckout().BasketItemsList,c=0;c=0?c.get("/rest/checkout/container_checkoutbasketitemslist/").done(function(c){var d=a("[data-basket-item-id]").parents("ul"),e=d.parents(".panel-body");d.fadeOut(function(){a(this).siblings(":not('[data-plenty-checkout-template]')").remove(),a(this).remove(),e.prepend(a(c.data[0])).hide().fadeIn(function(){b.getInstance().bindDirectives(e)})})}):f.reloadContainer("BasketItemsList"),f.reloadContainer("Totals")),s(),i.resolve()})})}var i=a.Deferred(),j=p(d).BasketItemNameMap[1];return e?h():g.prepare().setTitle(b.translate("Please confirm")).setContent("

    "+b.translate('Do you really want to remove "{{item}}" from your basket?',{item:j})+"

    ").onDismiss(function(){i.reject()}).onConfirm(function(){h()}).setLabelConfirm(b.translate("Delete")).show(),i}function r(d,e){if(0>=e)return q(d);for(var g,h,i=a.Deferred(),j=f.getCheckout().BasketItemsList,k=0;k0&&f.reloadContainer("Totals")}return{addItem:h,removeItem:q,getItem:p,setItemQuantity:r,editItemAttributes:n,editOrderParams:o,addCoupon:t,removeCoupon:u}},["APIFactory","UIFactory","CMSFactory","CheckoutFactory","ModalFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("CheckoutService",function(c,d,e,f,g){function h(){f.loadCheckout(!0)}function i(){var b=a('[data-plenty-checkout-form="details"]'),d=b.getFormValues();return f.getCheckout().CheckoutCustomerSign||(f.getCheckout().CheckoutCustomerSign=""),f.getCheckout().CheckoutOrderInfoText||(f.getCheckout().CheckoutOrderInfoText=""),f.getCheckout().CheckoutCustomerSign!==d.CustomerSign&&a(b).find('[name="CustomerSign"]').length>0||f.getCheckout().CheckoutOrderInfoText!==d.OrderInfoText&&a(b).find('[name="OrderInfoText"]').length>0?(f.getCheckout().CheckoutCustomerSign=d.CustomerSign,f.getCheckout().CheckoutOrderInfoText=d.OrderInfoText,f.setCheckout()):c.idle()}function j(d){var e=a('[data-plenty-checkout-form="shippingAddress"]');if(!d&&!e.validateForm())return!1;if(!d&&!b.getInstance().AddressDoctorService.validateAddress(e))return!1;var g=e.getFormValues(),h=a('[name="shippingAddressID"]:checked').val();if(0>h){var i=g;return m(i,f.getCheckout().CustomerShippingAddress)?c.idle():("PACKSTATION"==i.Street?(i.IsPackstation=1,i.PackstationNo=i.HouseNo):"POSTFILIALE"==i.Street&&(i.IsPostfiliale=1,i.PostfilialNo=i.HouseNo),c.post("/rest/checkout/customershippingaddress/",i).done(function(a){f.getCheckout().CheckoutCustomerShippingAddressID=a.data.ID,f.getCheckout().CheckoutShippingCountryID=a.data.CountryID,k()}))}return h==f.getCheckout().CheckoutCustomerShippingAddressID?c.idle():(f.getCheckout().CheckoutCustomerShippingAddressID=h,void k())}function k(){return delete f.getCheckout().CheckoutMethodOfPaymentID,delete f.getCheckout().CheckoutShippingProfileID,f.setCheckout().done(function(){f.reloadContainer("MethodsOfPaymentList"),f.reloadContainer("ShippingProfilesList"),2==f.getCheckout().CustomerInvoiceAddress.LoginType&&f.reloadContainer("CustomerShippingAddress"),a("#shippingAdressSelect").modal("hide"),a(".modal-backdrop")&&a(".modal-backdrop").remove()})}function l(){var b=a('[data-plenty-checkout-form="guestRegistration"]'),d=b.getFormValues();if(d.LoginType=1,d.checkout&&d.checkout.customerInvoiceAddress&&d.checkout.customerInvoiceAddress.CustomerProperty){var e=d.checkout.customerInvoiceAddress.CustomerProperty;d.CustomerPropertiesList=d.CustomerPropertiesList||[];for(var g in e)e[g]&&d.CustomerPropertiesList.push({PropertyID:g,PropertyValue:e[g]})}return m(d,f.getCheckout().CustomerInvoiceAddress)?j():c.post("/rest/checkout/customerinvoiceaddress/",d).done(function(a){j().done(f.loadCheckout)})}function m(a,b){for(var c in a)if(a[c]+""!=b[c]+""&&"EmailRepeat"!==c)return!1;return!0}function n(){var b=a('[data-plenty-checkout-form="shippingProfileSelect"]').getFormValues();return f.getCheckout().CheckoutShippingProfileID=b.ShippingProfileID,delete f.getCheckout().CheckoutCustomerShippingAddressID,delete f.getCheckout().CheckoutMethodOfPaymentID,f.setCheckout().done(function(){f.reloadContainer("MethodsOfPaymentList")})}function o(){var b=f.getCheckout().CheckoutMethodOfPaymentID,e=a('input[type="radio"][name="MethodOfPaymentID"][value="'+b+'"]').parent().getFormValues();return c.post("/rest/checkout/preparepayment/",e,!0).done(function(b){if(""!=b.data.CheckoutMethodOfPaymentRedirectURL)document.location.assign(b.data.CheckoutMethodOfPaymentRedirectURL);else if(b.data.CheckoutMethodOfPaymentAdditionalContent){var c=a(b.data.CheckoutMethodOfPaymentAdditionalContent).find('[data-plenty-checkout-form="bankDetails"]').length>0;g.prepare().setContent(b.data.CheckoutMethodOfPaymentAdditionalContent).onConfirm(function(){return c?s():u()}).show()}}).fail(function(b){try{for(var c=a.parseJSON(b.responseText),e=[],g=0;g0&&d.printErrors(e)}catch(h){d.throwError(b.status,b.statusText)}})}function p(c){return c||(c=a('input[name="MethodOfPaymentID"]:checked').val()),f.getCheckout().CheckoutMethodOfPaymentID=c,b.getGlobal("Checkout.AtrigaRequireUserConfirmation")||(f.getCheckout().CheckoutAtrigapaymaxChecked=!0),delete f.getCheckout().CheckoutCustomerShippingAddressID,delete f.getCheckout().CheckoutShippingProfileID,f.setCheckout().done(function(){f.reloadContainer("ShippingProfilesList")})}function q(a){return f.getCheckout().CheckoutAtrigapaymaxChecked=!!a,c.put("/rest/checkout",{CheckoutAtrigapaymaxChecked:!!a})}function r(){e.getContainer("CheckoutPaymentInformationBankDetails").from("Checkout").done(function(b){g.prepare().setContent(b.data[0]).onDismiss(function(){a('input[name="MethodOfPaymentID"]').each(function(b,c){a(c).val()==f.getCheckout().CheckoutMethodOfPaymentID?a(c).attr("checked","checked"):a(c).removeAttr("checked")})}).onConfirm(function(){return s()}).show()})}function s(){var b=a('[data-plenty-checkout-form="bankDetails"]');if(b.validateForm()){var d=b.getFormValues().checkout.customerBankDetails,e={CustomerBankName:d.bankName,CustomerBLZ:d.blz,CustomerAccountNumber:d.accountNo,CustomerAccountOwner:d.accountOwner,CustomerIBAN:d.iban,CustomerBIC:d.bic};return c.post("/rest/checkout/paymentinformationbankdetails/",e).done(function(){f.loadCheckout().done(function(){p(3),f.reloadContainer("MethodsOfPaymentList")})}),!0}return!1}function t(){e.getContainer("CheckoutPaymentInformationCreditCard").from("Checkout").done(function(b){g.prepare().setContent(b.data[0]).onDismiss(function(){a('input[name="MethodOfPaymentID"]').each(function(b,c){a(c).val()==f.getCheckout().CheckoutMethodOfPaymentID?a(c).attr("checked","checked"):a(c).removeAttr("checked")})}).onConfirm(function(){return u()}).show()})}function u(){var b=a('[data-plenty-checkout-form="creditCard"]');if(b.validateForm()){var d=b.getFormValues().checkout.paymentInformationCC,e={Owner:d.owner,Cvv2:d.cvv2,Number:d.number,Year:d.year,Month:d.month,Provider:d.provider};return c.post("/rest/checkout/paymentinformationcreditcard/",e).done(function(){f.loadCheckout()}),!0}return!1}function v(b){if(2==f.getCheckout().CustomerInvoiceAddress.LoginType)var c=a('[data-plenty-checkout-form="shippingAddress"]').getFormValues();else var c=a('[data-plenty-checkout-form="guestRegistration"]').getFormValues();var d={street:c.Street,houseNo:c.HouseNo,ZIP:c.ZIP,city:c.City,postnummer:c.Postnummer,suggestionType:"postfinder"};e.getContainer("CheckoutAddressSuggestionResultsList",d).from("Checkout").done(function(a){g.prepare().setContent(a.data[0]).show()})}function w(){var b=a('[data-plenty-checkout-form="placeOrder"]');if(b.validateForm()){var d=b.getFormValues(),e={TermsAndConditionsCheck:d.termsAndConditionsCheck||0,WithdrawalCheck:d.withdrawalCheck||0,PrivacyPolicyCheck:d.privacyPolicyCheck||0,AgeRestrictionCheck:d.ageRestrictionCheck||0,NewsletterCheck:d.newsletterCheck||0,KlarnaTermsAndConditionsCheck:d.klarnaTermsAndConditionsCheck||0,PayoneDirectDebitMandateCheck:d.payoneDirectDebitMandateCheck||0,PayoneInvoiceCheck:d.payoneInvoiceCheck||0};return c.post("/rest/checkout/placeorder/",e).done(function(a){""!=a.data.MethodOfPaymentRedirectURL?window.location.assign(a.data.MethodOfPaymentRedirectURL):""!=a.data.MethodOfPaymentAdditionalContent?g.prepare().setContent(a.data.MethodOfPaymentAdditionalContent).setLabelDismiss("").onDismiss(function(){window.location.assign(b.attr("action"))}).onConfirm(function(){window.location.assign(b.attr("action"))}).show():window.location.assign(b.attr("action"))})}}return{init:h,setCustomerSignAndInfo:i,registerGuest:l,setShippingProfile:n,saveShippingAddress:j,loadAddressSuggestion:v,preparePayment:o,setMethodOfPayment:p,confirmAtrigaPaymax:q,editBankDetails:r,editCreditCard:t,placeOrder:w}},["APIFactory","UIFactory","CMSFactory","CheckoutFactory","ModalFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("FeedbackService",function(a){function b(){function b(a,b){return e.dateStart=a,e.dateEnd=b,this}function c(b,c,f){var g={ReferenceId:c,FromDate:e.dateStart,ToDate:e.dateEnd,FeedbackType:f||d().COMMENTS_AND_RATINGS};return a.get("/rest/feedback/"+b+"/",g)}var e={dateStart:null,dateEnd:null};return{between:b,"for":c}}function c(){function b(a){return f.Rating=a,this}function c(a){return f.Text=a,this}function d(a,b,c){return f.Author=a,b&&(f.Email=b),c&&(f.CustomerId=c),this}function e(b,c){return a.post("/rest/feedback/"+b+"/",f)}var f={Rating:1,Text:"",Author:"",Email:"",CustomerId:0};return{withRating:b,withComment:c,withAuthor:d,to:e}}function d(){return{COMMENTS_ONLY:"comments_only",RATINGS_ONLY:"ratings_only",COMMENTS_AND_RATINGS:"comments_with_ratings"}}function e(){return{ITEM:"item",CATEGORY:"category",BLOG:"blog"}}return{getFeedbacks:b,addFeedback:c,ArticleTypes:e(),FeedbackTypes:d()}},["APIFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("MediaSizeService",function(){function b(){return e&&c(),e}function c(){var b;if(b=window.matchMedia?window.matchMedia("(min-width:1200px)").matches?"lg":window.matchMedia("(min-width:992px)").matches?"md":window.matchMedia("(min-width:768px)").matches?"sm":"xs":a(window).width()>=1200?"lg":a(window).width()>=992?"md":a(window).width()>=768?"sm":"xs",b!=e||"xs"===b){var c=e;e=b,a(window).trigger("sizeChange",[e,c])}}function d(a){for(var b=a.replace(/\s/g,"").split(","),c=0;c li'),r=a('[data-plenty-checkout="container"] > div'),u=a('[data-plenty-checkout="next"]'),t=a('[data-plenty-checkout="prev"]'),q.length==r.length&&r.length>0){d.getCheckout();r.hide(),q.each(function(b,c){a(c).addClass("disabled"),a(c).click(function(){a(this).is(".disabled")||j(b)})}),u.attr("disabled","disabled"),u.click(function(){m()}),t.attr("disabled","disabled"),t.click(function(){n()}),window.addEventListener("hashchange",function(){window.location.hash.length>0?o(window.location.hash):j(0)},!1),a.urlParam=function(a){var b=new RegExp("[?&]"+a+"=([^&#]*)").exec(window.location.href);return null==b?null:b[1]||0};var c=a.urlParam("gototab");0==window.location.hash.length&&c&&a('[data-plenty-checkout-id="'+c+'"]').length>0?window.location.hash=c:j(!o(window.location.hash)&&s>=0?s:0),p(),a(window).on("sizeChange",p),a(window).resize(function(){"xs"==b.getInstance().MediaSizeService.interval()&&p()})}}function f(){return s>=0?{id:a(r[s]).attr("data-plenty-checkout-id"),index:s}:null}function g(a){return v.beforeChange.push(a),b.getInstance().NavigatorService}function h(a){return v.afterChange.push(a),b.getInstance().NavigatorService}function i(b,c){var d=!0;if(s>=0||"afterChange"===b){var e=f(),g={index:c,id:a(r[c]).attr("data-plenty-checkout-id")};a.each(v[b],function(a,b){return b(e,g)===!1?(d=!1,!1):void 0})}return d}function j(e,f){var g=s!==e;(!g||f||i("beforeChange",e))&&(s=e,!Object.equals(w[s],d.getCheckout(!0))&&g&&a(r[s]).attr("data-plenty-checkout-content")?(w[s]=d.getCheckout(!0),c.getCategoryContent(a(r[s]).attr("data-plenty-checkout-content")).done(function(c){a(r[s]).html(c.data[0]),k(g),b.getInstance().bindDirectives(r[s]),a(window).trigger("contentChanged")})):k(g))}function k(b){a(r).hide();var c;a(q).each(function(b,d){c=a(d),c.removeClass("disabled active"),c.find('[role="tab"]').attr("aria-selected","false"),s>b?c.addClass("visited"):b==s?(c.addClass("active visited"),c.find('[role="tab"]').attr("aria-selected","true")):b>s&&!c.is(".visited")&&c.addClass("disabled")}),p(),0>=s?t.attr("disabled","disabled"):t.removeAttr("disabled"),s+1==q.length?u.attr("disabled","disabled"):u.removeAttr("disabled"),a(r[s]).show(),s>0?window.location.hash=a(r[s]).attr("data-plenty-checkout-id"):window.location.hash.length>0&&(window.location.hash=""),b&&i("afterChange",s)}function l(a){j(a.index,!0)}function m(){s0&&j(s-1)}function o(b){return"next"==b?(m(),!0):"prev"==b?(n(),!0):(b=b.replace("#",""),a(r).each(function(c,d){return a(d).attr("data-plenty-checkout-id")==b?(j(c),!0):void 0}),!1)}function p(){var b=q.length;if(!(0>=b)){a(q).removeAttr("style"),a(q).children("span").removeAttr("style"),a(u).removeAttr("style"),a(t).removeAttr("style");var c=a(t).outerWidth()c?a(d).children("span").css({paddingLeft:g+"px",paddingRight:h+"px"}):a(d).children("span").css({paddingLeft:j+"px",paddingRight:k+"px"})})}}var q=[],r=[],s=-1,t={},u={},v={beforeChange:[],afterChange:[]},w=[];return{init:e,getCurrentContainer:f,goTo:j,beforeChange:g,afterChange:h,continueChange:l,next:m,previous:n,goToID:o,fillNavigation:p}},["CMSFactory","CheckoutFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("PostfinderService",function(c,d,e){function f(){var b=a('input[name="Street"]').val();return"PACKSTATION"==b.toUpperCase()||"POSTFILIALE"==b.toUpperCase()}function g(){j={PostfinderItemStreet:a('input[name="Street"]','[data-plenty-checkout-form="shippingAddress"]'),PostfinderItemZIP:a('input[name="ZIP"]','[data-plenty-checkout-form="shippingAddress"]'),PostfinderItemCity:a('input[name="City"]','[data-plenty-checkout-form="shippingAddress"]'),PostfinderItemHouseNo:a('input[name="HouseNo"]','[data-plenty-checkout-form="shippingAddress"]')},j.PostfinderItemStreet.val(""),j.PostfinderItemZIP.val().length>2||j.PostfinderItemCity.val().length>2?c.get("/rest/checkout/shippingaddresspostfinderlist/",{suggestionType:"postfinder",zip:j.PostfinderItemZIP.val(),city:j.PostfinderItemCity.val()}).done(function(c){l=c.data,k=l.length,0==k&&h();for(var e={addresses:[]},f=0;k>f;f++){var g="km",m=l[f].PostfinderItemDistance,n=m/1e3;n=(Math.round(100*n)/100).toFixed(2).replace(".",","),1e3>m&&(n=m,g="m"),e.addresses.push({index:f,dimension:g,type:l[f].PostfinderItemIsPackstation?"Packstation":"Postfiliale",number:l[f].PostfinderItemIsPackstation?l[f].PostfinderItemPackstationNo:l[f].PostfinderItemPostfilialNo,street:l[f].PostfinderItemStreet,houseNo:l[f].PostfinderItemHouseNo,zip:l[f].PostfinderItemZIP,city:l[f].PostfinderItemCity,district:l[f].PostfinderItemDistrict,distance:n,remark:l[f].PostfinderItemRemark})}var o=b.compileTemplate("addressSuggestions/postFinder.html",e);d.prepare().setTitle(b.translate("Packstations and post offices in your area")).setContent(o).setClass("checkout").onConfirm(function(){return j.PostfinderItemCity.removeClass("has-error").addClass("has-success"),a('label[for="'+j.PostfinderItemCity.attr("id")+'"]').removeClass("has-error").addClass("has-success"),j.PostfinderItemZIP.removeClass("has-error").addClass("has-success"),a('label[for="'+j.PostfinderItemZIP.attr("id")+'"]').removeClass("has-error").addClass("has-success"),j.PostfinderItemStreet.removeClass("has-error").addClass("has-success"),a('label[for="'+j.PostfinderItemStreet.attr("id")+'"]').removeClass("has-error").addClass("has-success"),j.PostfinderItemHouseNo.removeClass("has-error").addClass("has-success"),a('label[for="'+j.PostfinderItemHouseNo.attr("id")+'"]').removeClass("has-error").addClass("has-success"),i=a('input[type="radio"][name="postfinder"]:checked').val(),l[i].PostfinderItemIsPackstation?(a(j.PostfinderItemStreet).val("PACKSTATION"),a(j.PostfinderItemHouseNo).val(l[i].PostfinderItemPackstationNo)):(a(j.PostfinderItemStreet).val("POSTFILIALE"),a(j.PostfinderItemHouseNo).val(l[i].PostfinderItemPostfilialNo)),a(j.PostfinderItemStreet).trigger("change"),a(j.PostfinderItemCity).val(l[i].PostfinderItemCity),a(j.PostfinderItemZIP).val(l[i].PostfinderItemZIP),!0}).show()}):h()}function h(){e.throwError(0,b.translate("Please enter a ZIP code and/or a city.")),j.PostfinderItemCity.removeClass("has-success").addClass("has-error"),a('label[for="'+j.PostfinderItemCity.attr("id")+'"]').removeClass("has-success").addClass("has-error"),j.PostfinderItemZIP.removeClass("has-success").addClass("has-error"),a('label[for="'+j.PostfinderItemZIP.attr("id")+'"]').removeClass("has-success").addClass("has-error"),j.PostfinderItemCity.focus(function(){a(this).removeClass("has-error");var b=a(this).attr("id");a(this).closest(".form-group").find('[for="'+b+'"]').removeClass("has-error")}),j.PostfinderItemZIP.focus(function(){a(this).removeClass("has-error");var b=a(this).attr("id");a(this).closest(".form-group").find('[for="'+b+'"]').removeClass("has-error")})}var i="",j={},k={},l={};return{openPostfinderModal:g,isPackstation:f}},["APIFactory","ModalFactory","UIFactory"])}(jQuery,PlentyFramework),function(a,b){b.service("SocialShareService",function(){function b(a){var b={"facebook-like":'',"facebook-recommend":'',twitter:'',"google-plus":'
    '};return b[a]}function c(){var b=document.location.href,c=a("link[rel=canonical]").attr("href");return c&&c.length>0&&(c.indexOf("http")<0&&(c=document.location.protocol+"//"+document.location.host+c),b=c),b}function d(b){var c=a('meta[name="'+b+'"]').attr("content");return c||""}function e(){var b=d("DC.title"),c=d("DC.creator");return b.length>0&&c.length>0?b+=" - "+c:b=a("title").text(),encodeURIComponent(b)}return"undefined"==typeof socialLangLocale&&(socialLangLocale="en_US"),"undefined"==typeof socialLang&&(socialLang="en"),{getSocialService:b}})}(jQuery,PlentyFramework),function(a,b){b.service("ValidationService",function(){function b(b){return b=a(b),b.is("input")||b.is("select")||b.is("textarea")?b:b.find("input").length>0?b.find("input"):b.find("select").length>0?b.find("select"):b.find("textarea").length>0?b.find("textarea"):null}function c(b){return b.is("input")||b.is("select")||b.is("textarea")?a.trim(b.val()).length>0:(console.error("Validation Error: Cannot validate Text for <"+b.prop("tagName")+">"),!1)}function d(b){var d=/[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;return c(b)?d.test(a.trim(b.val())):!1}function e(b){return c(b)?a.isNumeric(a.trim(b.val())):!1}function f(b,c,d){return b=a.trim(b.val()),c=a.trim(a(c).length>0?a(c).val():c),d?b==c:b.toLowerCase()==c.toLowerCase()}function g(a){return!a.is(":visible")||!a.is(":enabled")}function h(h,i){var j,k,l,m,n,o,p,q,r,s,t,u=a(h);i=i||"has-error";var v=[],w=!1;u.find("[data-plenty-validate], :required").each(function(h,x){r=a(x).attr("data-plenty-validate"),k=b(x),s=r?r:"text",s=s.split(",");for(var h=0,y=k.length;y>h;h++){if(j=a(k[h]),t=j.attr("type"),g(j))return;if(l=s[h].trim()||s[0].trim(),m=!1,j.is("input")&&"radio"!=t&&"checkbox"!=t||j.is("textarea"))switch(l){case"text":m=!c(j);break;case"mail":m=!d(j);break;case"number":m=!e(j);break;case"value":m=!f(j,a(x).attr("data-plenty-validation-value"),"password"===j.context.type);break;case"none":break;default:console.error('Form validation error: unknown validate property: "'+r+'"')}else if(!j.is("input")||"radio"!=t&&"checkbox"!=t){if(!j.is("select"))return void console.error("Form validation error: "+a(x).prop("tagName")+" does not contain an form element");m=""==j.val()||"-1"==j.val()}else{if(n=j.attr("name"),o=u.find('input[name="'+n+'"]:checked').length,"radio"==t)p=1,q=1;else{var z=new Function("return "+r)()||{min:1,max:1};p=z.min,q=z.max}m=p>o||o>q}m&&(w=!0,v.push(j),k.length>1?(j.addClass(i),u.find('label[for="'+j.attr("id")+'"]').addClass(i)):a(x).addClass(i)); +}}),u.on("validationFailed",function(){var b=50,c=u.find("."+i).first(),d=c.offset().top,e=a("html, body");u.parents(".modal").length>0?(e=u.parents(".modal").find(".modal-body"),d=e.scrollTop()-(e.offset().top-c.offset().top)):u.is(".modal")&&(e=u.find(".modal-body"),d=e.scrollTop()-(e.offset().top-c.offset().top)),(d-bwindow.pageYOffset+window.innerHeight)&&e.animate({scrollTop:d-b})}),w&&(u.find("."+i).each(function(c,d){j=a(b(d)),j.on("focus click",function(){var b=a(d);b.removeClass(i),u.find('label[for="'+a(this).attr("id")+'"]').removeClass(i)})}),u.trigger("validationFailed",[v]));var x=u.attr("data-plenty-callback");if(!w&&x&&"submit"!=x&&"function"==typeof window[x]){var y={};return u.find("input, textarea, select").each(function(){"checkbox"==a(this).attr("type")?y[a(this).attr("name")]=a(this).is(":checked"):y[a(this).attr("name")]=a(this).val()}),window[x](y),!1}return!w}return{validate:h}}),a.fn.validateForm=function(){return b.getInstance().ValidationService.validate(this)},a.fn.getFormValues=function(){function b(b,c){var e=b.match(/^([^\[]+)(.*)/);if(e[2]){var f,g=/\[([^\]]+)]/g,h=[];for(h[0]=e[1];null!==(f=g.exec(e[2]));)h.push(f[1]);for(var i=h.length-1;i>=0;i--){var j={};j[h[i]]=c,c=j}d=a.extend(!0,d,c)}else d[e[1]]=c}var c=this,d={};return c.find("input, select, textarea").each(function(d,e){if(a(e).attr("name"))if("checkbox"==a(e).attr("type")){var f=[];a(c).find('[name="'+a(e).attr("name")+'"]:checked').each(function(b,c){f.push(a(c).val())}),b(a(e).attr("name"),f)}else"radio"==a(e).attr("type")?a(e).is(":checked")&&b(a(e).attr("name"),a(e).val()):b(a(e).attr("name"),a(e).val())}),d}}(jQuery,PlentyFramework),PlentyFramework.compile();var plenty=PlentyFramework.getInstance();jQuery(document).ready(function(){plenty.bindDirectives()}); +//# sourceMappingURL=plentymarketsCMStools-1.0.12.min.js.map \ No newline at end of file diff --git a/dist/plentymarketsCMStools-1.0.12.min.js.map b/dist/plentymarketsCMStools-1.0.12.min.js.map new file mode 100644 index 0000000..e2e2108 --- /dev/null +++ b/dist/plentymarketsCMStools-1.0.12.min.js.map @@ -0,0 +1,937 @@ +{ + "version": 3, + "file": "plentymarketsCMStools-1.0.12.min.js", + "sources": [ + "plentymarketsCMStools-1.0.12.js" + ], + "names": [ + "TemplateCache", + "global", + "factory", + "exports", + "nodeName", + "define", + "amd", + "Mustache", + "this", + "mustache", + "isFunction", + "object", + "typeStr", + "obj", + "isArray", + "escapeRegExp", + "string", + "replace", + "hasProperty", + "propName", + "testRegExp", + "re", + "regExpTest", + "call", + "isWhitespace", + "nonSpaceRe", + "escapeHtml", + "String", + "s", + "entityMap", + "parseTemplate", + "template", + "tags", + "stripSpace", + "hasTag", + "nonSpace", + "spaces", + "length", + "tokens", + "pop", + "compileTags", + "tagsToCompile", + "split", + "spaceRe", + "Error", + "openingTagRe", + "RegExp", + "closingTagRe", + "closingCurlyRe", + "sections", + "start", + "type", + "value", + "chr", + "token", + "openSection", + "scanner", + "Scanner", + "eos", + "pos", + "scanUntil", + "i", + "valueLength", + "charAt", + "push", + "scan", + "tagRe", + "whiteRe", + "equalsRe", + "curlyRe", + "nestTokens", + "squashTokens", + "lastToken", + "squashedTokens", + "numTokens", + "section", + "nestedTokens", + "collector", + "tail", + "Context", + "view", + "parentContext", + "cache", + ".", + "parent", + "Writer", + "objectToString", + "Object", + "prototype", + "toString", + "Array", + "test", + "&", + "<", + ">", + "\"", + "'", + "/", + "match", + "index", + "substring", + "search", + "lookup", + "name", + "hasOwnProperty", + "names", + "context", + "lookupHit", + "indexOf", + "clearCache", + "parse", + "render", + "partials", + "renderTokens", + "originalTemplate", + "symbol", + "buffer", + "undefined", + "renderSection", + "renderInverted", + "renderPartial", + "unescapedValue", + "escapedValue", + "rawValue", + "subRender", + "self", + "j", + "slice", + "escape", + "version", + "defaultWriter", + "TypeError", + "to_html", + "send", + "result", + "$", + "bindEventCallback", + "$elem", + "eventType", + "callback", + "params", + "on", + "event", + "eventStack", + "apply", + "document", + "readyState", + "addCustomEvents", + "element", + "is", + "trigger", + "radioGroup", + "attr", + "each", + "radio", + "$radio", + "parseDirectives", + "input", + "thisValue", + "directivePattern", + "expressions", + "directives", + "expression", + "trim", + "console", + "error", + "directive", + "class", + "method", + "param", + "isNaN", + "parseFloat", + "toLowerCase", + "compileComponent", + "component", + "componentLevel", + "dependencyStack", + "compiledDependencies", + "dependencies", + "dependency", + "inArray", + "components", + "factories", + "PlentyFramework", + "services", + "join", + "setup", + "instance", + "getInstance", + "compare", + "localVersion", + "compareVersion", + "parseInt", + "get", + "equals", + "v", + "globals", + "setGlobal", + "identifier", + "getGlobal", + "fallbackValue", + "directiveName", + "directiveFunctions", + "bindDirectives", + "rootElement", + "find", + "getRecentEvent", + "lastEventIdx", + "pushEvent", + "service", + "serviceName", + "serviceFunctions", + "factoryName", + "factoryFunctions", + "compileTemplate", + "data", + "translate", + "text", + "scriptPath", + "Strings", + "loadLanguageFile", + "fileName", + "ajax", + "url", + "dataType", + "done", + "response", + "localeString", + "warn", + "compile", + "scripts", + "getElementsByTagName", + "path", + "src", + "jQuery", + "pm", + "AuthenticationService", + "login", + "elem", + "preventDefault", + "customerLogin", + "BasketService", + "addBasketItem", + "basketItemsList", + "parentForm", + "parents", + "$p_id", + "BasketItemItemID", + "val", + "BasketItemPriceID", + "BasketItemQuantity", + "BasketItemBranchID", + "attributeInputsList", + "attributesList", + "idx", + "BasketItemAttributeID", + "BasketItemAttributeValueID", + "BasketItemAttributesList", + "addItem", + "changeItemQuantity", + "increment", + "$quantityInput", + "maxLength", + "isBasketView", + "timeout", + "window", + "clearTimeout", + "setTimeout", + "setItemQuantity", + "basketItemID", + "fail", + "basketItem", + "getItem", + "CheckoutService", + "setMethodOfPayment", + "paymentID", + "confirmAtrigaPaymax", + "atrigaPaymaxConfirmed", + "MediaSize", + "initDropdowns", + "resetDropdowns", + "dropdownElements", + "closableDropdownElements", + "dropdownList", + "$current", + "target", + "removeClass", + "unbind", + "resetEvent", + "openDropdown", + "alwaysClickable", + "$parent", + "isInterval", + "Modernizr", + "touch", + "showDropdownHideOthers", + "avoidRedirectinStopPropagation", + "not", + "addClass", + "off", + "e", + "stopPropagation", + "slideDropdown", + "$elemParent", + "siblings", + "slideToggle", + "removeAttr", + "MediaSizeService", + "NavigatorService", + "to", + "href", + "interval", + "location", + "assign", + "toCheckoutTab", + "tabID", + "goToID", + "showTab", + "tabSelector", + "tab", + "initRemoteLabel", + "groupID", + "tabGroups", + "TabGroup", + "getTab", + "addTab", + "addLabel", + "initRemoteTab", + "setContent", + "showRemoteTab", + "tabs", + "Tab", + "zIndex", + "activeTab", + "getContent", + "css", + "hide", + "currentZ", + "resetTabs", + "show", + "id", + "getID", + "label", + "$labels", + "content", + "$content", + "SocialShareService", + "UIFactory", + "initUIWindowEvents", + "fireEqualHeight", + "toTopButtonList", + "scrollTop", + "doToArrayElements", + "showWaitscreen", + "hideWaitscreen", + "forceClose", + "addContentPageSlider", + "owlCarousel", + "navigation", + "navigationText", + "slideSpeed", + "paginationSpeed", + "singleItem", + "autoPlay", + "stopOnHover", + "afterMove", + "current", + "equalHeight", + "mediaSizes", + "elementExists", + "maxHeight", + "$equalTarget", + "$equalTargetList", + "children", + "equalHeightElementList", + "outerHeight", + "height", + "initToTop", + "click", + "animate", + "initLazyload", + "effect", + "lazyload", + "toggleHideShow", + "log", + "initSlideToggle", + "checked", + "$targetElement", + "$radioGroupList", + "visibleOnChecked", + "change", + "$self", + "slideDown", + "slideUp", + "toggleClass", + "duration", + "slideAction", + "$target", + "callbackString", + "toggleSocialShare", + "socialShareService", + "$toggle", + "append", + "hasClass", + "tooltip", + "getSocialService", + "cssClass", + "array", + "func", + "ValidationService", + "validate", + "form", + "errorClass", + "UI", + "Modal", + "renewLoginSession", + "sessionExpirationTimeout", + "prepare", + "setTitle", + "setLabelDismiss", + "setLabelConfirm", + "onConfirm", + "onDismiss", + "handleError", + "jqXHR", + "responseText", + "parseJSON", + "printErrors", + "error_stack", + "throwError", + "status", + "statusText", + "_get", + "ignoreErrors", + "runInBackground", + "sync", + "showWaitScreen", + "async", + "always", + "hideWaitScreen", + "_post", + "isFile", + "processData", + "contentType", + "JSON", + "stringify", + "_put", + "_delete", + "_idle", + "Deferred", + "resolve", + "ready", + "post", + "put", + "delete", + "idle", + "API", + "getContainer", + "containerName", + "from", + "layoutGroup", + "getParams", + "getCategoryContent", + "categoryID", + "CMS", + "Checkout", + "checkoutData", + "getCheckout", + "copy", + "checkout", + "loadCheckout", + "extend", + "setCheckout", + "reloadContainer", + "container", + "html", + "reloadCatContent", + "catId", + "reloadItemContainer", + "isModal", + "selector", + "title", + "modal", + "setClass", + "labelConfirm", + "labelDismiss", + "setContainer", + "bsModal", + "getModal", + "filter", + "script", + "createElement", + "innerHTML", + "init", + "close", + "startTimeout", + "confirmed", + "timeRemaining", + "timeStart", + "Date", + "getTime", + "clearInterval", + "setInterval", + "paused", + "secondsRemaining", + "Math", + "round", + "pauseTimeout", + "continueTimeout", + "stopTimeout", + "code", + "msg", + "message", + "errorMessages", + "errorPopup", + "has", + "key", + "addError", + "waitScreenCount", + "waitScreen", + "WaitScreen", + "a", + "b", + "constructor", + "cssClasses", + "active", + "popup", + "hideAll", + "errorCode", + "remove", + "hover", + "root", + "validateAddress", + "addressForms", + "addressIsValid", + "addressDoctor", + "AddressDoctor", + "requiredFields", + "isValid", + "fields", + "isPackstation", + "suggestions", + "AddressList", + "$form", + "getFormValues", + "refreshView", + "getAddresses", + "suggestionListVisible", + "validateInput", + "houseNoAllowed", + "$inputs", + "HouseNo", + "valueList", + "getList", + "$suggestionContainer", + "buildSuggestionList", + "focus", + "positionSuggestionList", + "suggestionKey", + "width", + "outerWidth", + "left", + "position", + "top", + "values", + "filterAddress", + "Street", + "toUpperCase", + "ZIP", + "City", + "addressInput", + "suggestionType", + "street", + "city", + "houseNo", + "country", + "CountryID", + "responseLength", + "currentResponse", + "address", + "getAddress", + "addresses", + "suggestion", + "addressCount", + "results", + "filteredAddresses", + "range", + "resetPassword", + "validateForm", + "Email", + "IsMailSend", + "loginMail", + "Password", + "loginPassword", + "setInvoiceAddress", + "invoiceAddress", + "CustomerInvoiceAddress", + "registerCustomer", + "AddressDoctorService", + "LoginType", + "customerInvoiceAddress", + "CustomerProperty", + "tmpProperties", + "CustomerPropertiesList", + "property", + "PropertyID", + "PropertyValue", + "article", + "itemID", + "quantity", + "resp", + "addArticle", + "saveOrderParams", + "articleWithParams", + "orderParamsForm", + "attrType", + "addOrderParamValue", + "files", + "orderParamFileUpload", + "paramValue", + "$artAttr", + "$unitCombinationId", + "requestData", + "ArticleID", + "refreshBasketPreview", + "updateArticle", + "$input", + "formData", + "fileData", + "orderParamUploadFiles", + "orderParamFileIdStack", + "FormData", + "basketList", + "paramId", + "BasketItemOrderParamsList", + "BasketItemOrderParamID", + "BasketItemOrderParamValue", + "editItemAttributes", + "BasketItemID", + "getBasketItem", + "attributeSelect", + "editOrderParams", + "basketItems", + "BasketItemsList", + "removeBasketItem", + "forceDelete", + "doDelete", + "$oldBasketList", + "$basketListContainer", + "fadeOut", + "prepend", + "fadeIn", + "deferred", + "itemName", + "BasketItemNameMap", + "item", + "reject", + "basketItemIndex", + "itemQuantityTotal", + "Totals", + "TotalsItemSum", + "addCoupon", + "CouponActiveCouponCode", + "updateContainer", + "removeCoupon", + "Coupon", + "removeItem", + "setCustomerSignAndInfo", + "CheckoutCustomerSign", + "CheckoutOrderInfoText", + "CustomerSign", + "OrderInfoText", + "saveShippingAddress", + "shippingAddressID", + "shippingAddress", + "addressesAreEqual", + "CustomerShippingAddress", + "IsPackstation", + "PackstationNo", + "IsPostfiliale", + "PostfilialNo", + "CheckoutCustomerShippingAddressID", + "ID", + "CheckoutShippingCountryID", + "updatePaymentAndShippingDependencies", + "CheckoutMethodOfPaymentID", + "CheckoutShippingProfileID", + "registerGuest", + "address1", + "address2", + "setShippingProfile", + "ShippingProfileID", + "preparePayment", + "paymentData", + "CheckoutMethodOfPaymentRedirectURL", + "CheckoutMethodOfPaymentAdditionalContent", + "isBankDetails", + "saveBankDetails", + "saveCreditCard", + "errorStack", + "CheckoutAtrigapaymaxChecked", + "atrigaPaymaxChecked", + "editBankDetails", + "customerBankDetails", + "bankDetails", + "CustomerBankName", + "bankName", + "CustomerBLZ", + "blz", + "CustomerAccountNumber", + "accountNo", + "CustomerAccountOwner", + "accountOwner", + "CustomerIBAN", + "iban", + "CustomerBIC", + "bic", + "editCreditCard", + "paymentInformationCC", + "creditCard", + "Owner", + "owner", + "Cvv2", + "cvv2", + "Number", + "number", + "Year", + "year", + "Month", + "month", + "Provider", + "provider", + "loadAddressSuggestion", + "postnummer", + "Postnummer", + "placeOrder", + "TermsAndConditionsCheck", + "termsAndConditionsCheck", + "WithdrawalCheck", + "withdrawalCheck", + "PrivacyPolicyCheck", + "privacyPolicyCheck", + "AgeRestrictionCheck", + "ageRestrictionCheck", + "NewsletterCheck", + "newsletterCheck", + "KlarnaTermsAndConditionsCheck", + "klarnaTermsAndConditionsCheck", + "PayoneDirectDebitMandateCheck", + "payoneDirectDebitMandateCheck", + "PayoneInvoiceCheck", + "payoneInvoiceCheck", + "MethodOfPaymentRedirectURL", + "MethodOfPaymentAdditionalContent", + "getFeedbacks", + "setFeedbackInterval", + "end", + "feedbackInterval", + "dateStart", + "dateEnd", + "listFeedbacks", + "articleType", + "referenceId", + "feedbackType", + "ReferenceId", + "FromDate", + "ToDate", + "FeedbackType", + "feedbackTypes", + "COMMENTS_AND_RATINGS", + "between", + "for", + "addFeedback", + "withRating", + "rating", + "Rating", + "withComment", + "comment", + "Text", + "withAuthor", + "author", + "mail", + "customerID", + "Author", + "CustomerId", + "sendFeedback", + "COMMENTS_ONLY", + "RATINGS_ONLY", + "articleTypes", + "ITEM", + "CATEGORY", + "BLOG", + "ArticleTypes", + "FeedbackTypes", + "getInterval", + "bsInterval", + "calculateMediaSize", + "size", + "matchMedia", + "matches", + "oldValue", + "intervalList", + "resize", + "buttonNext", + "buttonPrev", + "goTo", + "next", + "previous", + "addEventListener", + "hash", + "urlParam", + "exec", + "fillNavigation", + "getCurrentContainer", + "beforeChange", + "interceptor", + "interceptors", + "afterChange", + "resolveInterceptors", + "continueTabChange", + "currentContainer", + "targetContainer", + "ignoreInterceptors", + "contentChanged", + "checkoutStates", + "proceedTabChange", + "continueChange", + "containerID", + "navigationCount", + "buttonWidth", + "padding", + "tabWidth", + "paddingLeft", + "paddingRight", + "paddingEachItem", + "paddingLastLeft", + "paddingLastRight", + "paddingLastItem", + "openPostfinderModal", + "shippingFields", + "PostfinderItemStreet", + "PostfinderItemZIP", + "PostfinderItemCity", + "PostfinderItemHouseNo", + "zip", + "numberOfResults", + "showErrorMessage", + "dimension", + "distInMeters", + "PostfinderItemDistance", + "distInKilometers", + "toFixed", + "PostfinderItemIsPackstation", + "PostfinderItemPackstationNo", + "PostfinderItemPostfilialNo", + "district", + "PostfinderItemDistrict", + "distance", + "remark", + "PostfinderItemRemark", + "packstationID", + "inputId", + "closest", + "getService", + "facebook-like", + "socialLangLocale", + "encodeURIComponent", + "getURI", + "facebook-recommend", + "twitter", + "getTweetText", + "google-plus", + "socialLang", + "uri", + "canonical", + "protocol", + "host", + "getMeta", + "metaContent", + "creator", + "getFormControl", + "validateText", + "formControl", + "prop", + "validateMail", + "mailRegExp", + "validateNumber", + "isNumeric", + "compareValues", + "reference", + "caseSensitive", + "isNotVisibleOrEnabled", + "$formControl", + "formControls", + "validationKey", + "currentHasError", + "group", + "checkedMin", + "checkedMax", + "attrValidate", + "validationKeys", + "formControlAttrType", + "missingFields", + "hasError", + "minMax", + "Function", + "min", + "max", + "distanceTop", + "$error", + "first", + "errorOffset", + "offset", + "$scrollTarget", + "pageYOffset", + "innerHeight", + "$errorElement", + "fn", + "inject", + "child", + "exp", + "groupValues", + "checkbox", + "plenty" + ], + "mappings": "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", + "sourcesContent": [ + "var TemplateCache = {};\n\nTemplateCache[\"addressSuggestions/addressDoctor.html\"] = \"\";\n\nTemplateCache[\"addressSuggestions/postFinder.html\"] = \"{{#addresses}}\\n\" +\n \"
    \\n\" +\n \"
    \\n\" +\n \" \\n\" +\n \"
    \\n\" +\n \"
    \\n\" +\n \"{{/addresses}}\\n\" +\n \"\";\n\nTemplateCache[\"error/errorMessage.html\"] = \"
    \\n\" +\n \" Code {{code}}:\\n\" +\n \" {{{message}}}\\n\" +\n \"
    \\n\" +\n \"\";\n\nTemplateCache[\"error/errorPopup.html\"] = \"
    \\n\" +\n \" \\n\" +\n \"
    \\n\" +\n \"
    \\n\" +\n \"
    \\n\" +\n \"\";\n\nTemplateCache[\"modal/modal.html\"] = \"
    \\n\" +\n \"
    \\n\" +\n \"
    \\n\" +\n \"\\n\" +\n \" {{#title}}\\n\" +\n \"
    \\n\" +\n \" \\n\" +\n \"

    {{{title}}}

    \\n\" +\n \"
    \\n\" +\n \" {{/title}}\\n\" +\n \"\\n\" +\n \"
    {{{content}}}
    \\n\" +\n \"\\n\" +\n \"
    \\n\" +\n \"\\n\" +\n \" {{#labelDismiss}}\\n\" +\n \" \\n\" +\n \" {{/labelDismiss}}\\n\" +\n \"\\n\" +\n \" \\n\" +\n \"
    \\n\" +\n \"
    \\n\" +\n \"
    \\n\" +\n \"
    \\n\" +\n \"\";\n\nTemplateCache[\"waitscreen/waitscreen.html\"] = \"
    \";\n\n(function defineMustache(global,factory){if(typeof exports===\"object\"&&exports&&typeof exports.nodeName!==\"string\"){factory(exports)}else if(typeof define===\"function\"&&define.amd){define([\"exports\"],factory)}else{global.Mustache={};factory(Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)===\"[object Array]\"};function isFunction(object){return typeof object===\"function\"}function typeStr(obj){return isArray(obj)?\"array\":typeof obj}function escapeRegExp(string){return string.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g,\"\\\\$&\")}function hasProperty(obj,propName){return obj!=null&&typeof obj===\"object\"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={\"&\":\"&\",\"<\":\"<\",\">\":\">\",'\"':\""\",\"'\":\"'\",\"/\":\"/\"};function escapeHtml(string){return String(string).replace(/[&<>\"'\\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\\s*/;var spaceRe=/\\s+/;var equalsRe=/\\s*=/;var curlyRe=/\\s*\\}/;var tagRe=/#|\\^|\\/|>|\\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile===\"string\")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error(\"Invalid tags: \"+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+\"\\\\s*\");closingTagRe=new RegExp(\"\\\\s*\"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp(\"\\\\s*\"+escapeRegExp(\"}\"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===\"\"};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return\"\";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail=\"\";break;case 0:match=\"\";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={\".\":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(\".\")>0){value=context.view;names=name.split(\".\");index=0;while(value!=null&&index\")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol===\"&\")value=this.unescapedValue(token,context);else if(symbol===\"name\")value=this.escapedValue(token,context);else if(symbol===\"text\")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer=\"\";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j\n * =====================================================================================\n */\n\n/**\n * @module PlentyFramework\n */\n(function( $ )\n{\n // will be overridden by grunt\n var version = \"1.0.12\";\n\n /**\n * Collection of uncompiled registered factories & services.\n * See {{#crossLink \"PlentyFramework/compile:method\"}}.compile(){{/crossLink}}\n * @attribute components\n * @static\n * @type {{factories: {}, services: {}}}\n */\n var components = {\n factories : {},\n services : {},\n directives: {}\n };\n\n /**\n * Framework providing client functions for plentymarkets Webshops.\n * @class PlentyFramework\n * @constructor\n */\n PlentyFramework = function()\n {\n };\n\n var instance = null;\n PlentyFramework.getInstance = function()\n {\n instance = instance || new PlentyFramework();\n return instance;\n };\n\n PlentyFramework.version = (function() {\n\n return {\n get: function() {\n return version;\n },\n equals: function( v ) {\n return compare(v) == 0;\n },\n compare: compare\n };\n\n function compare( compare )\n {\n var localVersion = version.split(\".\");\n var compareVersion = compare.split(\".\");\n\n for( var i = 0; i < compareVersion.length; i++ )\n {\n if( localVersion[i] === compareVersion[i] || compareVersion[i] === \"*\" )\n {\n continue;\n }\n\n if( parseInt(localVersion[i]) < parseInt(compareVersion[i]) )\n {\n return -1;\n }\n\n if( parseInt(localVersion[i]) > parseInt(compareVersion[i]) )\n {\n return 1;\n }\n }\n return 0;\n }\n\n })();\n\n /**\n * Customizable controls for partials will be injected here.\n * (e.g. Modal)\n * @attribute\n * @static\n * @type {object}\n */\n PlentyFramework.partials = {};\n\n /**\n * Collection of registered global variables\n * @attribute\n * @static\n * @type {object}\n */\n PlentyFramework.globals = {};\n\n /**\n * Set a global variable.\n * @function setGlobal\n * @static\n * @param {string} identifier A unique identifier to reference this variable\n * @param {*} value The value to set\n * @return {*} The value\n */\n PlentyFramework.setGlobal = function( identifier, value )\n {\n if ( PlentyFramework.globals.hasOwnProperty( identifier ) )\n {\n console.error( 'Global variable \"' + identifier + '\" already exists and cannot be overridden.' );\n return null;\n }\n\n PlentyFramework.globals[identifier] = value;\n\n return PlentyFramework.globals[identifier];\n };\n\n /**\n * Get the value of a global variable or undefined if not exists\n * @function getGlobal\n * @static\n * @param identifier The identifier of the requested variable\n * @return {*} The value of the variable\n */\n PlentyFramework.getGlobal = function( identifier, fallbackValue )\n {\n if( !PlentyFramework.globals.hasOwnProperty( identifier ) )\n {\n return fallbackValue;\n }\n return PlentyFramework.globals[identifier];\n };\n\n /**\n * Collection of registered directives\n * @type {Array}\n * @static\n */\n PlentyFramework.directives = {};\n\n /**\n * Register directive. Directives can be bound to dynamically added nodes by calling pm.bindPlentyFunctions();\n * @function directive\n * @static\n * @param {string} selector jQuery selector of the DOM-elements to bind the directive to\n * @param {function} callback Function to add directives behaviour\n * @param {Array} dependencies List of required services. Services will be passed to callback function\n * @param {boolean} allowDuplicates Defines if a directive can be bound to the same element multiple times\n * @return {object} The created directive\n */\n PlentyFramework.directive = function( directiveName, directiveFunctions, dependencies )\n {\n // Catch type mismatching for 'directiveName'\n if ( typeof directiveName !== 'string' )\n {\n console.error( \"Type mismatch: Expect first parameter to be a 'string', '\" + typeof directiveName + \"' given.\" );\n return;\n }\n\n // Catch type mismatching for 'serviceFunctions'\n if ( typeof directiveFunctions !== 'function' )\n {\n console.error( \"Type mismatch: Expect second parameter to be a 'function', '\" + typeof directiveFunctions + \"' given.\" );\n return;\n }\n\n dependencies = dependencies || [];\n\n components.directives[directiveName] = {\n name : directiveName,\n dependencies: dependencies,\n setup : directiveFunctions\n };\n };\n\n /**\n * Bind registered directives.\n * @function bindDirectives\n * @param {string} [directiveSelector] restrict binding to elements matching this selector\n */\n PlentyFramework.prototype.bindDirectives = function( rootElement )\n {\n\n rootElement = rootElement || 'html';\n\n $( rootElement ).find( '[data-plenty]' ).each( function( i, element )\n {\n\n var directives = parseDirectives( $( element ).attr( 'data-plenty' ), $( element ) );\n\n if ( directives.length <= 0 )\n {\n // continue\n return;\n }\n\n addCustomEvents( element );\n\n for ( var i = 0; i < directives.length; i++ )\n {\n var directive = directives[i];\n if ( !!PlentyFramework.directives[directive.class] && PlentyFramework.directives.hasOwnProperty( directive.class ) )\n {\n\n var callback = PlentyFramework.directives[directive.class][directive.method];\n if ( !!callback && typeof callback == \"function\" )\n {\n\n if ( directive.event == \"ready\" )\n {\n callback.apply( null, directive.params );\n }\n else\n {\n bindEventCallback( $( element ), directive.event, callback, directive.params );\n /*\n $( element ).on( directive.event, function( e )\n {\n directive = injectEvent( directive, e );\n return callback.apply( null, directive.params );\n } );\n */\n }\n\n }\n else\n {\n console.error( \"Method not found: \" + directive.method + \" in \" + directive.class );\n }\n\n }\n else\n {\n console.error( \"Directive not found: \" + directive.class );\n }\n }\n } );\n\n $( document ).trigger( 'initPartials', rootElement );\n };\n\n var eventStack = [];\n\n PlentyFramework.getRecentEvent = function( eventType )\n {\n var lastEventIdx = eventStack.length - 1;\n if ( !eventType )\n {\n return eventStack[lastEventIdx];\n }\n else\n {\n for ( var i = lastEventIdx; i >= 0; i-- )\n {\n if ( eventType == eventStack[i].type )\n {\n return eventStack[i];\n }\n }\n }\n\n return null;\n\n };\n\n PlentyFramework.pushEvent = function( event )\n {\n eventStack.push( event );\n };\n\n /**\n * Bind event to element by eventType.\n * If cms says \"click:Foo.bar(this, event)\" eventType is \"click\".\n *\n * @param $elem - jQuery object on which event was triggered\n * @param eventType - type of event\n * @param callback - callback function of directive [example: \"bar(this, event)\"]\n * @param params - list of parameters for callback function.\n */\n function bindEventCallback( $elem, eventType, callback, params )\n {\n $elem.on( eventType, function( event )\n {\n eventStack.push( event );\n return callback.apply( null, params );\n } );\n\n if( document.readyState === \"complete\" && eventType === \"ready\" )\n {\n // execute 'ready' directives directly if document is already loaded\n callback.apply( null, params );\n }\n }\n\n function addCustomEvents( element )\n {\n\n var $elem = $( element );\n\n if ( $elem.is( 'input[type=\"checkbox\"]' ) )\n {\n $elem.on( 'change', function()\n {\n\n if ( $elem.is( ':checked' ) )\n {\n $elem.trigger( 'check' );\n }\n else\n {\n $elem.trigger( 'uncheck' );\n }\n } );\n }\n\n if ( $elem.is( 'input[type=\"radio\"]' ) )\n {\n $elem.on( 'change', function()\n {\n\n var radioGroup = $elem.attr( 'name' );\n\n $( 'input[type=\"radio\"][name=\"' + radioGroup + '\"]' ).each( function( i, radio )\n {\n var $radio = $( radio );\n if ( $radio.is( ':checked' ) )\n {\n $radio.trigger( 'check' );\n }\n else\n {\n $radio.trigger( 'uncheck' );\n }\n\n } );\n\n } );\n }\n }\n\n function parseDirectives( input, thisValue )\n {\n var directivePattern = /^(([\\w]+):)?([\\w]+)\\.([\\w]+)(\\((.*)\\))?$/;\n var expressions = input.split( ';' );\n var directives = [];\n\n for ( var i = 0; i < expressions.length; i++ )\n {\n var expression = expressions[i].trim();\n\n if ( !expression )\n {\n continue;\n }\n\n if ( !directivePattern.test( expression ) )\n {\n // console.warn( \"Invalid directive: \" + expression );\n continue;\n }\n\n var match = expression.match( directivePattern );\n\n if ( !match[3] || match[3].length <= 0 )\n {\n console.error( \"Cannot parse '\" + expression + \"': Class name not set.\" );\n continue;\n }\n\n if ( !match[4] || match[4].length <= 0 )\n {\n console.error( \"Cannot parse '\" + expression + \"': Method not set.\" );\n continue;\n }\n\n var directive = {\n event : match[2] || 'ready',\n class : match[3],\n method: match[4],\n params: []\n };\n\n if ( !!match[6] && match[6].length > 0 )\n {\n var params = match[6].match( /(['][^']+['])|([\\w-]+)|([\"][^\"]+[\"])/g );\n for ( var j = 0; j < params.length; j++ )\n {\n var param = params[j].trim();\n if ( !isNaN( parseFloat( param ) ) )\n {\n directive.params.push( parseFloat( param ) );\n }\n else if ( param.toLowerCase() == 'true' )\n {\n directive.params.push( true );\n }\n else if ( param.toLowerCase() == 'false' )\n {\n directive.params.push( false );\n }\n else if ( param.toLowerCase() == 'this' )\n {\n directive.params.push( thisValue );\n }\n else\n {\n directive.params.push( param.replace( /^['\"]|['\"]$/g, '' ) );\n }\n }\n }\n\n directives.push( directive );\n\n }\n return directives;\n }\n\n /**\n * Register a new service\n * @function service\n * @static\n * @param {string} serviceName Unique identifier of the service to get/ create\n * @param {function} serviceFunctions Callback containing all public functions of this service.\n * @param {Array} [dependencies] Identifiers of required services to inject in serviceFunctions\n * @return {object} The object described in serviceFunctions(). Can be received via\n * PlentyFramework.[serviceName]\n */\n PlentyFramework.service = function( serviceName, serviceFunctions, dependencies )\n {\n\n // Catch type mismatching for 'serviceName'\n if ( typeof serviceName !== 'string' )\n {\n console.error( \"Type mismatch: Expect first parameter to be a 'string', '\" + typeof serviceName + \"' given.\" );\n return;\n }\n\n // Catch type mismatching for 'serviceFunctions'\n if ( typeof serviceFunctions !== 'function' )\n {\n console.error( \"Type mismatch: Expect second parameter to be a 'function', '\" + typeof serviceFunctions + \"' given.\" );\n return;\n }\n\n dependencies = dependencies || [];\n\n components.services[serviceName] = {\n name : serviceName,\n dependencies: dependencies,\n setup : serviceFunctions\n };\n\n };\n\n /**\n * Collection of compiled factories\n * @attribute factories\n * @static\n * @type {object}\n */\n PlentyFramework.factories = {};\n\n /**\n * Register a new factory\n * @function factory\n * @static\n * @param {string} factoryName A unique name of the new factory\n * @param {function} factoryFunctions The function describing the factory\n * @param {Array} dependencies List of required factories to inject\n */\n PlentyFramework.factory = function( factoryName, factoryFunctions, dependencies )\n {\n\n // Catch type mismatching for 'serviceName'\n if ( typeof factoryName !== 'string' )\n {\n console.error( \"Type mismatch: Expect first parameter to be a 'string', '\" + typeof factoryName + \"' given.\" );\n return;\n }\n\n // Catch type mismatching for 'serviceFunctions'\n if ( typeof factoryFunctions !== 'function' )\n {\n console.error( \"Type mismatch: Expect second parameter to be a 'function', '\" + typeof factoryFunctions + \"' given.\" );\n return;\n }\n\n dependencies = dependencies || [];\n components.factories[factoryName] = {\n name : factoryName,\n dependencies: dependencies,\n setup : factoryFunctions\n }\n\n };\n\n /**\n * Renders html template. Will provide given data to templates scope.\n * Uses Mustache syntax for data-binding.\n * @function compileTemplate\n * @static\n * @param {String} template relative path to partials template to load. Base path = '/src/partials/'\n * @param {Object} data data to privide to templates scope.\n * @returns {String} The rendered html string\n */\n PlentyFramework.compileTemplate = function( template, data )\n {\n data = data || {};\n data.translate = function()\n {\n return function( text, render )\n {\n return render( PlentyFramework.translate( text ) );\n };\n };\n return Mustache.render( TemplateCache[template], data );\n };\n\n /**\n * The path on the server where the script is located in.\n * @attribute\n * @static\n * @type {String}\n */\n PlentyFramework.scriptPath = '';\n\n /**\n * Collection of locale strings will be injected here after reading language file.\n * @attribute\n * @static\n * @type {Object}\n */\n PlentyFramework.Strings = {};\n\n /**\n * Load language file containing translations of locale strings.\n * @function loadLanguageFile\n * @static\n * @param fileName relative path to language file.\n */\n PlentyFramework.loadLanguageFile = function( fileName )\n {\n $.ajax({\n url: PlentyFramework.scriptPath + fileName,\n dataType: 'json'\n }).done( function( response ) {\n PlentyFramework.Strings = response;\n });\n };\n\n /**\n * Try to get locale translation of given string.\n * Render translated string using Mustache syntax\n * if additional parameters are given.\n * @function translate\n * @static\n * @param {String} string The string to translate\n * @param {Object} [params] additional data for rendering\n * @returns {String} The translation of the given string if found. Otherwise returns the original string.\n */\n PlentyFramework.translate = function( string, params )\n {\n var localeString;\n if ( PlentyFramework.Strings.hasOwnProperty( string ) )\n {\n localeString = PlentyFramework.Strings[string];\n }\n else\n {\n localeString = string;\n console.warn( 'No translation found for \"' + localeString + '\".' );\n }\n\n if ( !!params )\n {\n localeString = Mustache.render( localeString, params );\n }\n\n return localeString;\n\n };\n\n /**\n * Compile registered factories & services\n * @function compile\n * @static\n */\n PlentyFramework.compile = function()\n {\n\n for ( var factory in components.factories )\n {\n if ( !PlentyFramework.factories.hasOwnProperty( factory ) )\n {\n //components.factories[factory].compile();\n compileComponent( components.factories[factory], 3 );\n }\n }\n\n for ( var service in components.services )\n {\n if ( !PlentyFramework.prototype.hasOwnProperty( service ) )\n {\n //components.factories[factory].compile();\n compileComponent( components.services[service], 2 );\n }\n }\n\n for ( var directive in components.directives )\n {\n if ( !PlentyFramework.directives.hasOwnProperty( directive ) )\n {\n //components.factories[factory].compile();\n compileComponent( components.directives[directive], 1 );\n }\n }\n\n var scripts = document.getElementsByTagName( 'SCRIPT' );\n for( var i = scripts.length - 1; i >= 0; i-- ) {\n var path = scripts[i].src.match( /(.*)\\/(.*)\\.js(\\?\\S*)?$/ );\n if( !!path ) {\n PlentyFramework.scriptPath = path[1];\n break;\n }\n }\n\n };\n\n // Level: 1 = directive, 2 = service, 3 = factory\n function compileComponent( component, componentLevel, dependencyStack )\n {\n dependencyStack = dependencyStack || [];\n\n // resolve dependencies\n var compiledDependencies = [];\n for ( var i = 0; i < component.dependencies.length; i++ )\n {\n var dependency = component.dependencies[i];\n if ( $.inArray( dependency, dependencyStack ) < 0 )\n {\n // add dependency to stack to avoid cyclic injection\n dependencyStack.push( dependency );\n\n if ( components.factories.hasOwnProperty( dependency ) )\n {\n // required dependency is a factory\n if ( !PlentyFramework.factories.hasOwnProperty( dependency ) )\n {\n // factory is not compiled yet\n compileComponent( components.factories[dependency], 3, dependencyStack );\n }\n compiledDependencies.push( PlentyFramework.factories[dependency] );\n continue;\n }\n\n if ( componentLevel <= 2 && components.services.hasOwnProperty( dependency ) )\n {\n // required dependency is a service\n if ( !PlentyFramework.prototype.hasOwnProperty( dependency ) )\n {\n // service is not compiled yet\n compileComponent( components.services[dependency], 2, dependencyStack );\n }\n compiledDependencies.push( PlentyFramework.prototype[dependency] );\n continue;\n }\n\n if ( componentLevel <= 1 && components.directives.hasOwnProperty( dependency ) )\n {\n // required dependency is a directive\n if ( !PlentyFramework.directives.hasOwnProperty( dependency ) )\n {\n // directive is not compiled yet\n compileComponent( components.directives[dependency], 1, dependencyStack );\n }\n compiledDependencies.push( PlentyFramework.directives[dependency] );\n continue;\n }\n\n console.error( 'Cannot inject dependency \"' + dependency + '\": Object not found.' );\n }\n else\n {\n console.error( 'Cyclic dependency injection: ' + dependencyStack.join( ' -> ' ) + ' -> ' + dependency );\n }\n }\n\n // compile component\n if ( componentLevel == 3 )\n {\n PlentyFramework.factories[component.name] = component.setup.apply( null, compiledDependencies );\n }\n else if ( componentLevel == 2 )\n {\n PlentyFramework.prototype[component.name] = component.setup.apply( null, compiledDependencies );\n }\n else if ( componentLevel == 1 )\n {\n PlentyFramework.directives[component.name] = component.setup.apply( null, compiledDependencies );\n }\n }\n\n}( jQuery ));\n\n\n\n\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n(function( $, pm )\n{\n pm.directive( 'Authentication', function( AuthenticationService )\n {\n return {\n login: login\n };\n\n function login( elem )\n {\n pm.getRecentEvent().preventDefault();\n AuthenticationService.customerLogin( $( elem ) );\n }\n }, [\"AuthenticationService\"] );\n\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Basket', function( BasketService )\n {\n\n return {\n addBasketItem : addBasketItem,\n changeItemQuantity: changeItemQuantity,\n setItemQuantity : setItemQuantity\n };\n\n function addBasketItem( elem )\n {\n pm.getRecentEvent().preventDefault();\n //init\n var basketItemsList = {};\n var $elem = $( elem );\n var parentForm = $elem.parents( 'form' );\n var $p_id = parentForm.find( '[name=\"P_ID\"]:checked' );\n\n basketItemsList.BasketItemItemID = parentForm.find( '[name=\"ArticleID\"]' ).val();\n basketItemsList.BasketItemPriceID = parentForm.find( '[name=\"SYS_P_ID\"]' ).val();\n basketItemsList.BasketItemQuantity = parentForm.find( '[name=\"ArticleQuantity\"]' ).val();\n basketItemsList.BasketItemBranchID = parentForm.find( '[name=\"source_category\"]' ).val();\n\n // look for occurrences of unit combination and take price id of combination, if available.\n if ( $p_id.length > 0\n && $p_id.val() > 0 )\n {\n basketItemsList.BasketItemPriceID = $p_id.val();\n }\n\n //attributes\n var attributeInputsList = parentForm.find( '[name^=\"ArticleAttribute\"]' );\n var attributesList = [];\n\n $.each( attributeInputsList, function( idx, elem )\n {\n var match = elem.name.match( /^ArticleAttribute\\[\\d+]\\[\\d+]\\[(\\d+)]$/ );\n if ( match && match[1] )\n {\n attributesList.push( {\n BasketItemAttributeID : match[1],\n BasketItemAttributeValueID: $( elem ).val()\n } );\n }\n } );\n\n if ( attributesList.length != 0 )\n {\n basketItemsList.BasketItemAttributesList = attributesList;\n }\n\n //add basketItem and refresh previewLists\n BasketService.addItem( [basketItemsList] );\n\n }\n\n function changeItemQuantity( elem, increment )\n {\n var $elem = $( elem );\n var $quantityInput = $elem.parent().find( 'input' );\n var maxLength = parseInt( $quantityInput.attr( 'maxlength' ) ) || 5;\n var value = parseInt( $quantityInput.val() ) + increment;\n\n var isBasketView = $elem.parents( '[data-basket-item-id]' ).length > 0;\n\n if ( isBasketView )\n {\n if ( (value + '').length <= maxLength && value >= 0 )\n {\n $quantityInput.val( value );\n }\n\n var timeout = $elem.data( 'timeout' );\n\n if ( !!timeout )\n {\n window.clearTimeout( timeout );\n }\n\n timeout = window.setTimeout( function()\n {\n $quantityInput.trigger( 'change' );\n }, 1000 );\n\n $elem.data( 'timeout', timeout );\n }\n else\n {\n if ( (value + '').length <= maxLength && value >= 1 )\n {\n $quantityInput.val( value );\n }\n }\n }\n\n function setItemQuantity( basketItemID, input )\n {\n BasketService.setItemQuantity(\n basketItemID,\n parseInt( $( input ).val() )\n ).fail( function()\n {\n // reset input's value on cancel\n var basketItem = BasketService.getItem( basketItemID );\n $( input ).val( basketItem.BasketItemQuantity );\n } );\n }\n\n }, ['BasketService'] );\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Checkout', function( CheckoutService )\n {\n\n return {\n setMethodOfPayment: setMethodOfPayment,\n confirmAtrigaPaymax: confirmAtrigaPaymax\n };\n\n function setMethodOfPayment( paymentID )\n {\n CheckoutService.setMethodOfPayment( paymentID );\n }\n\n function confirmAtrigaPaymax( atrigaPaymaxConfirmed )\n {\n CheckoutService.confirmAtrigaPaymax( atrigaPaymaxConfirmed );\n }\n }, ['CheckoutService'] );\n})( jQuery, PlentyFramework );\n/**\n * Mobile dropdowns\n * Toggles dropdowns using css class 'open' instead of pseudo class :hover\n * Usage:\n *
  • \n * ...\n *
  • \n *\n * possible values for CONDITION\n * \"touch\" : use 'open'-class if device is touch-device AND media size is 'md' or 'lg'\n * \"toggle-xs-sm-or-touch\" : use 'open'-class if device is \"touch\" (as above) OR media size is 'xs' or 'sm'\n *\n */\n(function( $, pm )\n{\n pm.directive( 'MobileDropdown', function( MediaSize )\n {\n // store all dropdown elements\n var dropdownElements = [];\n\n // store dropdown elements which should be closed by clicking outside the element itself\n var closableDropdownElements = [];\n\n return {\n initDropdowns: initDropdowns,\n openDropdown : openDropdown,\n slideDropdown: slideDropdown\n };\n\n function initDropdowns()\n {\n $( window ).on( 'orientationchange sizeChange', function()\n {\n if ( !$( \"input\" ).is( \":focus\" ) )\n {\n resetDropdowns( dropdownElements );\n resetDropdowns( closableDropdownElements );\n }\n } );\n }\n\n function resetDropdowns( dropdownList, event )\n {\n var $current;\n for ( var i = 0; i < dropdownList.length; i++ )\n {\n $current = $( dropdownList[i] );\n if ( !!event )\n {\n if ( $current.find( $( event.target ) ).length === 0\n && !$( \"input\" ).is( \":focus\" ) )\n {\n $current.removeClass( 'open' );\n $( 'html' ).unbind( \"click touchstart\", resetEvent );\n }\n }\n else\n {\n if ( !$( \"input\" ).is( \":focus\" ) )\n {\n $current.removeClass( 'open' );\n $( 'html' ).unbind( \"click touchstart\", resetEvent );\n }\n }\n }\n\n }\n\n function openDropdown( elem, alwaysClickable )\n {\n var $elem = $( elem );\n var $parent = $elem.parent();\n\n // case 1: xs || sm || ( touch && ( md || lg ) ) -> open/close via click on small devices, open/close via\n // css-hover on desktop, open/close via click on touch-desktop (e.g. top navigation)\n\n if ( !!alwaysClickable && ( MediaSize.isInterval( 'xs, sm' ) || ( Modernizr.touch && MediaSize.isInterval( 'md, lg' ) ) ) )\n {\n if ( !$parent.is( '.open' ) )\n {\n showDropdownHideOthers( $elem, $parent );\n\n // if href\n if ( !$elem.attr( 'href' ) )\n {\n avoidRedirectinStopPropagation( $parent.not( $elem ) );\n }\n }\n else\n {\n if ( !$elem.attr( 'href' ) )\n {\n // hide dropdown\n $parent.removeClass( 'open' );\n }\n }\n }\n\n // case 2: touch && ( md || lg ) -> open via 1st click on touch-desktop, return false (e.g. main navigation)\n\n if ( !alwaysClickable && ( Modernizr.touch && MediaSize.isInterval( 'md, lg' ) ) )\n {\n if ( !$parent.is( '.open' ) )\n {\n showDropdownHideOthers( $elem, $parent );\n\n avoidRedirectinStopPropagation( $parent );\n }\n else\n {\n // redirect to href if dropdown is already open\n // do nothing\n }\n }\n\n // handle \"close menu on click outside\"\n $( 'html' ).on( \"click touchstart\", resetEvent );\n }\n\n function showDropdownHideOthers( elem, parent )\n {\n var $parent = $( parent );\n\n // hide other dropdowns\n resetDropdowns( closableDropdownElements, elem );\n\n // remember opened dropdown\n if ( $.inArray( $parent[0], closableDropdownElements ) < 0 )\n {\n closableDropdownElements.push( $parent[0] );\n }\n\n // show dropdown\n $parent.addClass( 'open' );\n }\n\n function avoidRedirectinStopPropagation( elem )\n {\n var $elem = $( elem );\n\n // avoid redirecting\n pm.getRecentEvent().preventDefault();\n\n // avoid closing popup by clicking itself\n $elem.off( 'click' );\n $elem.on( 'click', function( e )\n {\n e.stopPropagation();\n } );\n }\n\n function slideDropdown( elem )\n {\n var $elem = $( elem );\n var $elemParent = $elem.parent();\n\n // size interval query is required since function is used on document ready to initial open active\n // navigation (on small devices)\n if ( MediaSize.isInterval( 'xs, sm' ) )\n {\n $elemParent.addClass( 'animating' );\n $elem.siblings( 'ul' ).slideToggle( 400, function()\n {\n if ( $elemParent.is( '.open' ) && !$( \"input\" ).is( \":focus\" ) )\n {\n $elemParent.removeClass( 'open' );\n $elem.siblings( 'ul' ).removeAttr( 'style' );\n $elemParent.removeClass( 'animating' );\n }\n else\n {\n $elemParent.addClass( 'open' );\n if ( $.inArray( $elemParent[0], dropdownElements ) < 0 )\n {\n dropdownElements.push( $elemParent[0] );\n }\n }\n } );\n }\n\n // handle \"close menu on click outside\"\n $( 'html' ).on( \"click touchstart\", resetEvent );\n }\n\n function resetEvent( event )\n {\n resetDropdowns( closableDropdownElements, event );\n }\n\n }, ['MediaSizeService'] );\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Redirect', function( MediaSizeService, NavigatorService )\n {\n\n return {\n to : to,\n toCheckoutTab: toCheckoutTab\n };\n\n function to( href )\n {\n if ( MediaSizeService.interval() != 'xs' )\n {\n if ( typeof href === 'string' && href.indexOf('/') == -1 && $( href ).length > 0 )\n {\n window.location.assign( $( href ).attr( 'href' ) );\n }\n else\n {\n window.location.assign( href );\n }\n }\n }\n\n function toCheckoutTab( tabID )\n {\n NavigatorService.goToID( tabID );\n }\n\n }, ['MediaSizeService', 'NavigatorService'] );\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Tab', function( MediaSize )\n {\n\n var tabGroups = {};\n\n return {\n showTab : showTab,\n initRemoteLabel: initRemoteLabel,\n initRemoteTab : initRemoteTab,\n showRemoteTab : showRemoteTab\n };\n\n function showTab( tabSelector )\n {\n $( tabSelector ).tab( 'show' );\n }\n\n function initRemoteLabel( $elem, tabID, groupID )\n {\n if ( !tabGroups[groupID] )\n {\n tabGroups[groupID] = new TabGroup();\n }\n\n if ( !tabGroups[groupID].getTab( tabID ) )\n {\n tabGroups[groupID].addTab( tabID );\n }\n\n tabGroups[groupID].getTab( tabID ).addLabel( $elem );\n }\n\n function initRemoteTab( $elem, tabID, groupID )\n {\n if ( !tabGroups[groupID] )\n {\n tabGroups[groupID] = new TabGroup();\n }\n\n if ( !tabGroups[groupID].getTab( tabID ) )\n {\n tabGroups[groupID].addTab( tabID );\n }\n\n tabGroups[groupID].getTab( tabID ).setContent( $elem );\n }\n\n function showRemoteTab( tabID, groupID, interval )\n {\n if ( MediaSize.isInterval( interval ) )\n {\n pm.getRecentEvent().preventDefault();\n\n if ( !!tabGroups[groupID] && !!tabGroups[groupID].getTab( tabID ) )\n {\n tabGroups[groupID].showTab( tabID );\n }\n\n }\n }\n\n function TabGroup()\n {\n var tabs = {};\n var activeTab;\n\n return {\n addTab : addTab,\n showTab : showTab,\n getTab : getTab,\n resetTabs: resetTabs\n };\n\n function addTab( tabID )\n {\n tabs[tabID] = new Tab( tabID );\n return tabs[tabID];\n }\n\n function showTab( tabID )\n {\n var zIndex = 0;\n if ( !!activeTab )\n {\n // activeTab is set\n zIndex = parseInt( activeTab.getContent().parent().css( 'zIndex' ) );\n activeTab.hide();\n activeTab.getContent().parent().css( 'zIndex', zIndex - 1 );\n }\n else\n {\n // activeTab not set before\n for ( var tab in tabs )\n {\n if ( !!tabs[tab].getContent() )\n {\n var currentZ = parseInt( tabs[tab].getContent().parent().css( 'zIndex' ) );\n if ( zIndex == 0 || currentZ < zIndex )\n {\n zIndex = currentZ;\n }\n tabs[tab].hide();\n }\n }\n\n for ( var tab in tabs )\n {\n if ( !!tabs[tab].getContent() )\n {\n tabs[tab].getContent().parent().css( 'zIndex', zIndex - 1 );\n }\n }\n\n $( window ).on( 'sizeChange', resetTabs );\n }\n\n activeTab = tabs[tabID];\n activeTab.getContent().parent().css( 'zIndex', zIndex );\n activeTab.show();\n }\n\n function getTab( tabID )\n {\n return tabs[tabID];\n }\n\n function resetTabs()\n {\n for ( var tab in tabs )\n {\n if ( !!tabs[tab].getContent() )\n {\n tabs[tab].show();\n }\n }\n\n activeTab = null;\n }\n }\n\n function Tab( id )\n {\n var $content;\n var $labels = [];\n var tabID = id;\n\n return {\n addLabel : addLabel,\n setContent: setContent,\n getContent: getContent,\n getID : getID,\n show : show,\n hide : hide\n };\n\n function getID()\n {\n return tabID;\n }\n\n function addLabel( label )\n {\n $labels.push( label );\n return this;\n }\n\n function setContent( content )\n {\n $content = content;\n return this;\n }\n\n function getContent()\n {\n return $content;\n }\n\n function show()\n {\n for ( var i = 0; i < $labels.length; i++ )\n {\n $labels[i].addClass( 'active' );\n }\n\n if ( !!$content )\n {\n $content.show().addClass( 'in' );\n }\n\n }\n\n function hide()\n {\n for ( var i = 0; i < $labels.length; i++ )\n {\n $labels[i].removeClass( 'active' );\n }\n\n if ( !!$content )\n {\n $content.hide().removeClass( 'in' );\n }\n }\n }\n\n }, ['MediaSizeService'] );\n})( jQuery, PlentyFramework );\n/**\n * Add fancy ui modifications - the visual stuff - here.\n * Respond functionality like 'event':UI.myFunctionality(currentElement)\n *\n * Example:\n * \n *\n */\n(function( $, pm )\n{\n pm.directive( 'UI', function( MediaSizeService, SocialShareService, UIFactory )\n {\n // elements to calculate height.\n var equalHeightElementList = [];\n var toTopButtonList = [];\n\n return {\n initUIWindowEvents : initUIWindowEvents,\n showWaitscreen : showWaitscreen,\n hideWaitscreen : hideWaitscreen,\n addContentPageSlider: addContentPageSlider,\n equalHeight : equalHeight,\n initToTop : initToTop,\n initLazyload : initLazyload,\n initSlideToggle : initSlideToggle,\n slideDown : slideDown,\n slideUp : slideUp,\n slideToggle : slideToggle,\n toggleHideShow : toggleHideShow,\n toggleSocialShare : toggleSocialShare,\n toggleClass : toggleClass,\n addClass : addClass,\n removeClass : removeClass\n };\n\n function initUIWindowEvents()\n {\n // resize elements on window size change.\n $( window ).on( 'sizeChange contentChanged', function()\n {\n fireEqualHeight();\n } );\n\n $( window ).on( \"scroll resize\", function()\n {\n if ( toTopButtonList.length > 0 )\n {\n if ( $( document ).scrollTop() > 100 )\n {\n doToArrayElements( toTopButtonList, \"addClass\", \"visible\" );\n }\n else\n {\n doToArrayElements( toTopButtonList, \"removeClass\", \"visible\" );\n }\n }\n } );\n }\n\n /**\n * Display waitscreen on page e.g. for requests.\n * Use with care and don't forget to hide waitscreen, if your calls are done or broke!!\n */\n function showWaitscreen()\n {\n UIFactory.showWaitscreen();\n }\n\n /**\n * Just hide the waitscreen.\n * @param forceClose\n */\n function hideWaitscreen( forceClose )\n {\n UIFactory.hideWaitscreen( forceClose );\n }\n\n /**\n * Adds content page slider (owlCarousel)\n *\n * usage:\n *
    \n *
    \n * ...\n *
    \n *
    \n * ...\n *
    \n * ...\n *
    \n *\n * Legacy directive selector: data-plenty=\"contentpageSlider\"\n *\n * @param elem\n */\n function addContentPageSlider( elem )\n {\n $( elem ).owlCarousel( {\n navigation : true,\n navigationText : false,\n slideSpeed : 1000,\n paginationSpeed: 1000,\n singleItem : true,\n autoPlay : 6000,\n stopOnHover : true,\n afterMove : function( current )\n {\n $( current ).find( '[data-plenty-rel=\"lazyload\"]' ).trigger( 'appear' );\n }\n } );\n }\n\n /**\n * Equal Box height\n * Calculates equal box height for chosen elements.\n *\n * Legacy directive selector: data-plenty-equal\n *\n * @param elem\n * @param elementExists - default false\n */\n function equalHeight( elem, mediaSizes, elementExists )\n {\n var $elem = $( elem );\n var maxHeight = 0;\n var $equalTarget = {};\n var $equalTargetList = $elem.find( '[data-plenty-rel=\"equal-target\"]' ).length > 0 ? $elem.find( '[data-plenty-rel=\"equal-target\"]' ) : $elem.children();\n\n // if element wasn't pushed before.\n if ( elementExists !== true )\n {\n equalHeightElementList.push( elem );\n }\n\n for ( var i = $equalTargetList.length; i >= 0; i-- )\n {\n $equalTarget = $( $equalTargetList[i] );\n $equalTarget.css( 'height', '' );\n\n if ( $equalTarget.outerHeight( true ) > maxHeight )\n {\n maxHeight = $equalTarget.outerHeight( true );\n }\n }\n\n if ( !mediaSizes || MediaSizeService.isInterval( mediaSizes ) )\n {\n $equalTargetList.height( maxHeight );\n }\n }\n\n /**\n * Scroll page to top.\n * Just add without events.\n *\n * Legacy directive selector: data-plenty=\"toTop\"\n *\n * @param elem\n */\n function initToTop( elem )\n {\n var $elem = $( elem );\n\n $elem.click( function()\n {\n $( 'html, body' ).animate( {\n scrollTop: 0\n }, 400 );\n return false;\n } );\n\n if ( !!$.inArray( $elem, toTopButtonList ) )\n {\n toTopButtonList.push( $elem );\n }\n }\n\n /**\n * lazy load on ready.\n *\n * Legacy directive selector: img[data-plenty-lazyload]\n *\n * @param elem\n */\n function initLazyload( elem, effect )\n {\n var $elem = $( elem );\n\n $elem.lazyload( {\n effect: effect\n } );\n if ( $elem.is( 'img' ) )\n {\n $elem.on( 'loaded', function()\n {\n $elem.css( 'display', 'inline-block' );\n } );\n }\n }\n\n /**\n * Toggle show and hide animation.\n *\n * Legacy directive selector: data-plenty=\"openCloseToggle\"\n *\n * @param elem\n */\n function toggleHideShow( elem )\n {\n\n console.log( elem );\n\n var $elem = $( elem );\n var $elemParent = $elem.parent();\n\n $elemParent.addClass( 'animating' );\n $elem.siblings( 'ul' ).slideToggle( 200, function()\n {\n if ( $elemParent.is( '.open' ) )\n {\n $elemParent.removeClass( 'open' );\n }\n else\n {\n $elemParent.addClass( 'open' );\n }\n $elem.siblings( 'ul' ).removeAttr( 'style' );\n $elemParent.removeClass( 'animating' );\n } );\n }\n\n /**\n * Toggle target content on click.\n * Bind to checked-/ unchecked-property of radio buttons\n *\n * Legacy directive selector: data-plenty-slidetoggle\n *\n * @param elem\n */\n function initSlideToggle( elem, checked )\n {\n var $elem = $( elem );\n var $targetElement = $( $elem.attr( 'data-plenty-rel' ) );\n\n if ( $elem.is( 'input[type=\"radio\"]' ) )\n {\n // is radio button\n var $radioGroupList = $( 'input[type=\"radio\"][name=\"' + ( $elem.attr( 'name' ) ) + '\"]' );\n var visibleOnChecked = !checked || checked == 'checked';\n\n $radioGroupList.change( function()\n {\n var $self = $( this );\n $targetElement.parents( '[data-plenty-rel=\"equal-target\"]' ).css( 'height', 'auto' );\n\n if ( $self.is( ':checked' ) && $self[0] === $elem[0] && visibleOnChecked == true )\n {\n // checked\n $targetElement.slideDown( 400, function()\n {\n fireEqualHeight();\n } );\n }\n else\n {\n // unchecked (since other radio button has been checked)\n $targetElement.slideUp( 400, function()\n {\n fireEqualHeight();\n } );\n }\n } );\n }\n else\n {\n // is not radio button\n $elem.click( function()\n {\n //$targetElement.parents( '[data-plenty-rel=\"equal-target\"]' ).css( 'height', 'auto' );\n\n $elem.addClass( 'animating' );\n $targetElement.slideToggle( 400, function()\n {\n $elem.removeClass( 'animating' );\n $elem.toggleClass( 'active' );\n fireEqualHeight();\n } );\n } );\n }\n }\n\n function slideDown( target, duration )\n {\n slideAction( $( target ), duration, 'slideDown' );\n }\n\n function slideUp( target, duration )\n {\n slideAction( $( target ), duration, 'slideUp' );\n }\n\n function slideToggle( target, duration )\n {\n slideAction( $( target ), duration, 'slideToggle' );\n }\n\n function slideAction( $target, duration, callbackString )\n {\n duration = duration || 400;\n $target.parents( '[data-plenty-rel=\"equal-target\"]' ).css( 'height', 'auto' );\n $target[callbackString]( duration, function()\n {\n fireEqualHeight();\n } );\n }\n\n /**\n * TODO check comment\n * Social Share Activation\n * Activate and load share-buttons manually by clicking a separate button\n * Usage / data-attributes:\n *
    \n * Will be used to activate the service set in\n * data-plenty-social=\"\"\n * Will be replaced with loaded share button\n *
    \n *\n * possible values for data-plenty-social:\n * \"facebook-like\" : Load Facebooks \"Like\"-Button\n * \"facebook-recommend\" : Load Facebooks \"Recommend\"-Button\n * \"twitter\" : Load Twitter Button\n * \"google-plus\" : Load google \"+1\"-Button\n *\n * Additional Tooltips\n * You can extend the parent element with a (bootstrap) tooltip by adding data-toggle=\"tooltip\" and\n * title=\"TOOLTIP CONTENT\" Tooltip will be destroyed after activating a social service\n * (!) Requires bootstrap.js\n *\n * Legacy directive selector: data-plenty-social\n *\n * @param elem\n */\n function toggleSocialShare( elem, socialShareService )\n {\n var $elem = $( elem );\n var $toggle = $elem.find( '[data-plenty-rel=\"social-switch\"]' );\n\n // append container to put / delete service.html\n $elem.append( '
    ' );\n\n // add \"off\" class to switch, if neither \"off\" or \"on\" is set\n // replaced hasClass() with is() benchmark: http://jsperf.com/hasclasstest\n if ( !$toggle.is( 'off, on' ) )\n {\n $toggle.addClass( 'off' );\n }\n\n // toggle switch\n $toggle.on( 'click', function()\n {\n if ( $toggle.hasClass( 'off' ) )\n {\n // TODO remove bootstrap dependency\n if ( $elem.attr( \"data-toggle\" ) == \"tooltip\" )\n {\n $elem.tooltip( 'destroy' )\n }\n $toggle.removeClass( 'off' ).addClass( 'on' );\n // hide dummy button\n $elem.find( '[data-plenty-rel=\"social-placeholder\"]' ).hide();\n // load HTML defined in 'api'\n $elem.find( '.social-container' ).append( SocialShareService.getSocialService( socialShareService ) );\n }\n // do not disable social medias after activation\n } );\n }\n\n /**\n * Toggle Class\n * toggle style-classes on click\n * Usage / data-attribute:\n *
    \n * target : jQuery selector to toggle the class at.\n * class : class(es) to toggle at target element\n * media : only toggle class on given media sizes (optional)\n *\n * (!) using data-plenty-toggle on -elements will prevent redirecting to href=\"\"\n *\n * Legacy directive selector: data-plenty-toggle\n *\n * @param cssClass\n * @param target\n * @param interval\n */\n function toggleClass( cssClass, target, interval )\n {\n var $target = $( target );\n /* FIXME\n * Callisto 3.1 Design adaption:\n * NavigationCategoriesList\n * Line 8\n * BEFORE:\n *
  • \n * AFTER:\n *
  • \n *\n * Line 10\n * BEFORE:\n * \n * AFTER:\n * \n *\n * */\n if ( $target.parents( \".navbar-main\" ).length > 0 )\n {\n var $elem = $target.children( \"span\" );\n pm.directives[\"MobileDropdown\"].slideDropdown( $elem );\n return true;\n }\n\n if ( !!target && !!cssClass && ( !interval || MediaSizeService.isInterval( interval ) ) )\n {\n var e = pm.getRecentEvent();\n if ( !!e )\n {\n e.preventDefault();\n }\n\n $target.toggleClass( cssClass );\n return false;\n }\n }\n\n function addClass( cssClass, target, interval )\n {\n if ( !!target && !!cssClass && ( !interval || MediaSizeService.isInterval( interval ) ) )\n {\n var e = pm.getRecentEvent();\n if ( !!e )\n {\n e.preventDefault();\n }\n\n $( target ).addClass( cssClass );\n return false;\n }\n }\n\n function removeClass( cssClass, target, interval )\n {\n if ( !!target && !!cssClass && ( !interval || MediaSizeService.isInterval( interval ) ) )\n {\n var e = pm.getRecentEvent();\n if ( !!e )\n {\n e.preventDefault();\n }\n\n $( target ).removeClass( cssClass );\n return false;\n }\n }\n\n /*\n ##### PRIVATE FUNCTIONS ######\n */\n\n function fireEqualHeight()\n {\n for ( var i = equalHeightElementList.length - 1; i >= 0; i-- )\n {\n equalHeight( equalHeightElementList[i], '', true );\n }\n }\n\n function doToArrayElements( array, func, params )\n {\n for ( var i = array.length - 1; i >= 0; i-- )\n {\n array[i][func]( params );\n }\n }\n\n }, ['MediaSizeService', 'SocialShareService', 'UIFactory'] );\n}( jQuery, PlentyFramework ));\n(function( $, pm )\n{\n pm.directive( 'Validator', function( ValidationService )\n {\n\n return {\n validate: validate\n };\n\n function validate( form, errorClass )\n {\n return ValidationService.validate( form, errorClass );\n }\n\n }, ['ValidationService'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( $, pm )\n{\n\n /**\n * Handles requests to ReST API. Provides a {{#crossLink \"APIFactory/handleError:method\"}}default\n * error-handling{{/crossLink}}. Request parameters will be parsed to json internally
    \n * Requires:\n *
      \n *
    • {{#crossLink \"UIFactory\"}}UIFactory{{/crossLink}}
    • \n *
    \n * @class APIFactory\n * @static\n */\n pm.factory( 'APIFactory', function( UI, Modal )\n {\n\n var sessionExpirationTimeout = null;\n $( document ).ready( function()\n {\n renewLoginSession();\n } );\n\n return {\n get : _get,\n post : _post,\n put : _put,\n delete: _delete,\n idle : _idle\n };\n\n function renewLoginSession()\n {\n if ( !pm.getGlobal( 'LoginSession' ) )\n {\n return;\n }\n\n if ( !!sessionExpirationTimeout )\n {\n clearTimeout( sessionExpirationTimeout );\n }\n\n sessionExpirationTimeout = setTimeout( function()\n {\n $( window ).trigger( 'login-expired' );\n\n if ( pm.getGlobal( 'PageDesign' ) === \"Checkout\" )\n {\n Modal.prepare()\n .setTitle( pm.translate( 'Your session has expired.' ) )\n .setContent( pm.translate( 'Please log in again to continue shopping.' ) )\n .setLabelDismiss( null )\n .setLabelConfirm( pm.translate( 'OK' ) )\n .onConfirm( function()\n {\n window.location.assign( '/' );\n } )\n .onDismiss( function()\n {\n window.location.assign( '/' );\n } )\n .show();\n }\n\n }, pm.getGlobal( 'LoginSessionExpiration' ) );\n }\n\n /**\n * Is called by default if a request failed.
    \n * Can be prevented by setting the requests last parameter to false.\n *\n * @function handleError\n * @private\n *\n * @param {object} jqXHR
    jQuery\n * deferred Object\n */\n function handleError( jqXHR )\n {\n try\n {\n var responseText = $.parseJSON( jqXHR.responseText );\n UI.printErrors( responseText.error.error_stack );\n }\n catch ( e )\n {\n UI.throwError( jqXHR.status, jqXHR.statusText );\n }\n }\n\n /**\n * Sends a GET request to ReST-API\n *\n * @function get\n *\n * @param {string} url The URL to send the request to\n * @param {object} params The data to append to requests body. Will be converted to JSON\n * internally\n * @param {boolean} [ignoreErrors=false] disable/ enable defaults error handling\n * @param {boolean} [runInBackground=false] show wait screen while request is in progress.\n * @return {object} jQuery\n * deferred Object\n */\n function _get( url, params, ignoreErrors, runInBackground, sync )\n {\n\n if ( !runInBackground )\n {\n UI.showWaitScreen();\n }\n\n return $.ajax(\n url,\n {\n type : 'GET',\n data : params,\n dataType: 'json',\n async : !sync,\n error : function( jqXHR )\n {\n if ( !ignoreErrors )\n {\n handleError( jqXHR )\n }\n }\n }\n ).always( function()\n {\n if ( !runInBackground )\n {\n UI.hideWaitScreen();\n }\n renewLoginSession();\n } );\n\n }\n\n /**\n * Sends a POST request to ReST-API\n *\n * @function post\n *\n * @param {string} url The URL to send the request to\n * @param {object} data The data to append to requests body. Will be converted to JSON\n * internally\n * @param {boolean} [ignoreErrors=false] disable/ enable defaults error handling\n * @param {boolean} [runInBackground=false] show wait screen while request is in progress.\n * @return {object} jQuery\n * deferred Object\n */\n function _post( url, data, ignoreErrors, runInBackground )\n {\n\n var params = {\n type : 'POST',\n dataType: 'json',\n error : function( jqXHR )\n {\n if ( !ignoreErrors )\n {\n handleError( jqXHR )\n }\n }\n };\n\n if ( !!data && data.isFile )\n {\n params.cache = data.cache;\n params.processData = data.processData;\n params.data = data.data;\n params.contentType = false;\n }\n else\n {\n params.data = JSON.stringify( data );\n params.contentType = 'application/json';\n }\n\n if ( !runInBackground )\n {\n UI.showWaitScreen();\n }\n\n return $.ajax(\n url, params\n ).always( function()\n {\n if ( !runInBackground )\n {\n UI.hideWaitScreen();\n }\n renewLoginSession();\n } );\n }\n\n /**\n * Sends a PUT request to ReST-API\n *\n * @function put\n *\n * @param {string} url The URL to send the request to\n * @param {object} data The data to append to requests body. Will be converted to JSON\n * internally\n * @param {boolean} [ignoreErrors=false] disable/ enable defaults error handling\n * @param {boolean} [runInBackground=false] show wait screen while request is in progress.\n * @return {object} jQuery\n * deferred Object\n */\n function _put( url, data, ignoreErrors, runInBackground )\n {\n\n if ( !runInBackground )\n {\n UI.showWaitScreen();\n }\n\n return $.ajax(\n url,\n {\n type : 'PUT',\n data : JSON.stringify( data ),\n dataType : 'json',\n contentType: 'application/json',\n error : function( jqXHR )\n {\n if ( !ignoreErrors )\n {\n handleError( jqXHR )\n }\n }\n }\n ).always( function()\n {\n if ( !runInBackground )\n {\n UI.hideWaitScreen();\n }\n renewLoginSession();\n } );\n\n }\n\n /**\n * Sends a DELETE request to ReST-API\n *\n * @function delete\n *\n * @param {string} url The URL to send the request to\n * @param {object} data The data to append to requests body. Will be converted to JSON\n * internally\n * @param {boolean} [ignoreErrors=false] disable/ enable defaults error handling\n * @param {boolean} [runInBackground=false] show wait screen while request is in progress.\n * @returns {object} jQuery\n * deferred Object\n */\n function _delete( url, data, ignoreErrors, runInBackground )\n {\n\n if ( !runInBackground )\n {\n UI.showWaitScreen();\n }\n\n return $.ajax(\n url,\n {\n type : 'DELETE',\n data : JSON.stringify( data ),\n dataType : 'json',\n contentType: 'application/json',\n error : function( jqXHR )\n {\n if ( !ignoreErrors )\n {\n handleError( jqXHR )\n }\n }\n }\n ).always( function()\n {\n if ( !runInBackground )\n {\n UI.hideWaitScreen();\n }\n renewLoginSession();\n } );\n\n }\n\n /**\n * Get a idle request doing nothing for chaining methods\n * @returns {object} jQuery\n * deferred Object\n */\n function _idle()\n {\n return $.Deferred().resolve();\n }\n\n }, ['UIFactory', 'ModalFactory'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( pm )\n{\n\n /**\n * Provide methods for receiving layout containers, layout parameters\n * or category content from API
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    \n * @class CMSFactory\n * @static\n */\n pm.factory( 'CMSFactory', function( API )\n {\n\n return {\n getContainer : getContainer,\n getParams : getParams,\n getCategoryContent: getCategoryContent\n };\n\n /**\n * Prepare the request to receive HTML-Content from CMS\n * @function getContainer\n * @param {string} containerName The Layoutcontainer to receive.\n * @param {object} params Additional GET-parameters.\n * @returns {object} The prepared request. Call .from( layoutGroup ) to specify the location in\n * the CMS\n * (e.g. 'Checkout')\n * @example\n * CMSFactory.getContainer( 'CheckoutTotals' ).from( 'Checkout' )\n * .done(function( response ) {\n * // container content\n * var html = response.data[0]\n * });\n */\n function getContainer( containerName, params )\n {\n\n function from( layoutGroup )\n {\n return API.get( '/rest/' + layoutGroup.toLowerCase() + '/container_' + containerName.toLowerCase() + '/', params );\n }\n\n return {\n from: from\n }\n\n }\n\n /**\n * Prepare the request to receive Layout parameters for a template\n * @function getParams\n * @param {string} containerName The Layoutcontainer to receive the parameteres of.\n * @param {object} params Additional GET-parameters.\n * @returns {object} The prepared request. Call .from( layoutGroup ) to specify the\n * location in the CMS\n * (e.g. 'ItemView')\n * @example\n * CMSFactory.getParams( 'BasketItemsList' ).from( 'ItemView' )\n * .done(function( response ) {\n * // BasketItems\n * var items = response.data;\n * });\n */\n function getParams( containerName, params )\n {\n\n function from( layoutGroup )\n {\n return API.get( '/rest/' + layoutGroup.toLowerCase() + '/' + containerName.toLowerCase() + '/', params );\n }\n\n return {\n from: from\n }\n }\n\n /**\n * Get the content of a category specified by its ID\n * @function getCategoryContent\n * @param {number} categoryID The ID of the category to get the content from\n * @returns {object} jQuery deferred\n * Object\n */\n function getCategoryContent( categoryID )\n {\n return API.get( '/rest/categoryview/categorycontentbody/?categoryID=' + categoryID );\n }\n\n }, ['APIFactory'] );\n}( PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( pm )\n{\n\n /**\n * Holds checkout data for global access and provides methods\n * for reloading content dynamically-
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CMSFactory\"}}CMSFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"UIFactory\"}}UIFactory{{/crossLink}}
    • \n *
    \n * @class CheckoutFactory\n * @static\n */\n pm.factory( 'CheckoutFactory', function( API, CMS, UI )\n {\n\n // data received from ReST API\n var checkoutData;\n\n // instance wrapped checkout object for global access\n var checkout;\n\n return {\n getCheckout : getCheckout,\n setCheckout : setCheckout,\n loadCheckout : loadCheckout,\n reloadContainer : reloadContainer,\n reloadCatContent : reloadCatContent,\n reloadItemContainer: reloadItemContainer\n };\n\n function Checkout()\n {\n return checkoutData;\n }\n\n /**\n * Returns instance of wrapped checkout object\n * @function getCheckout\n * @returns {Checkout} Instance of checkout object\n */\n function getCheckout( copy )\n {\n if ( !checkout || !checkoutData )\n {\n loadCheckout( true );\n }\n\n if ( !!copy )\n {\n return $.extend( true, {}, checkoutData );\n }\n return checkout;\n }\n\n /**\n * Receive global checkout data from ReST-API\n * @function loadCheckout\n * @return {object} jQuery deferred\n * Object\n */\n function loadCheckout( sync )\n {\n\n return API.get( '/rest/checkout/', null, false, false, sync )\n .done( function( response )\n {\n if ( !!response )\n {\n checkoutData = response.data;\n checkout = new Checkout();\n }\n else\n {\n UI.throwError( 0, 'Could not receive checkout data [GET \"/rest/checkout/\" receives null value]' );\n }\n } );\n }\n\n /**\n * Update checkout data on server\n * @function setCheckout\n * @return {object} jQuery deferred\n * Object\n */\n function setCheckout()\n {\n\n return API.put( '/rest/checkout', checkout )\n .done( function( response )\n {\n if ( !!response )\n {\n checkoutData = response.data;\n checkout = new Checkout();\n }\n else\n {\n UI.throwError( 0, 'Could not receive checkout data [GET \"/rest/checkout/\" receives null value]' );\n }\n } );\n\n }\n\n /**\n * Get layout container from server and replace received HTML\n * in containers marked with data-plenty-checkout-template=\"...\"\n * @function reloadContainer\n * @param {string} container Name of the template to load from server\n * @return {object} jQuery deferred\n * Object\n */\n function reloadContainer( container )\n {\n\n return CMS.getContainer( \"checkout\" + container ).from( 'checkout' )\n .done( function( response )\n {\n $( '[data-plenty-checkout-template=\"' + container + '\"]' )\n .each( function( i, elem )\n {\n $( elem ).html( response.data[0] );\n pm.getInstance().bindDirectives( elem );\n $( window ).trigger( 'contentChanged' );\n } );\n } );\n }\n\n /**\n * Get category content from server and replace received HTML\n * in containers marked with data-plenty-checkout-catcontent=\"...\"\n * @function reloadCatContent\n * @param {number} catId ID of the category to load content (description 1) from server\n * @return {object} jQuery deferred\n * Object\n * @deprecated\n */\n function reloadCatContent( catId )\n {\n\n return CMS.getCategoryContent( catId )\n .done( function( response )\n {\n $( '[data-plenty-checkout-catcontent=\"' + catId + '\"]' )\n .each( function( i, elem )\n {\n $( elem ).html( response.data[0] );\n pm.getInstance().bindDirectives( elem );\n $( window ).trigger( 'contentChanged' );\n\n } );\n } );\n\n }\n\n /**\n * Get layout container from server and replace received HTML\n * in containers marked with data-plenty-itemview-template=\"...\"\n * @function reloadItemContainer\n * @param {string} container Name of the (item view) template to load from server\n * @return {object} jQuery deferred\n * Object\n */\n function reloadItemContainer( container )\n {\n\n return CMS.getContainer( 'itemview' + container ).from( 'itemview' )\n .done( function( response )\n {\n $( '[data-plenty-itemview-template=\"' + container + '\"]' )\n .each( function( i, elem )\n {\n $( elem ).html( response.data[0] );\n pm.getInstance().bindDirectives( elem );\n $( window ).trigger( 'contentChanged' );\n\n } );\n } );\n\n }\n\n }, ['APIFactory', 'CMSFactory', 'UIFactory'] );\n}( PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( $, pm )\n{\n\n /**\n * Provides methods for creating and displaying modal popups.\n * @class ModalFactory\n * @static\n */\n pm.factory( 'ModalFactory', function()\n {\n\n return {\n prepare: prepare,\n isModal: isModal\n };\n\n /**\n * Detect if given html contains a valid modal\n * @function isModal\n * @param {string} html\n * @returns {boolean}\n */\n function isModal( html )\n {\n return PlentyFramework.partials.Modal.isModal( html );\n }\n\n /**\n * Create a new Instance of {{#crossLink \"ModalFactory.Modal\"}}Modal{{/crossLink}}\n * @function prepare\n * @returns {Modal}\n */\n function prepare( selector )\n {\n return new Modal( selector );\n }\n\n /**\n * Holds configuration of a modal and provides methods for displaying and hiding the modal\n * @class Modal\n * @for ModalFactory\n * @returns {Modal}\n * @constructor\n */\n function Modal( selector )\n {\n\n var modal = this;\n modal.selector = selector;\n\n /**\n * The title of the modal\n * @attribute title\n * @type {string}\n * @private\n * @default \"\"\n */\n modal.title = '';\n\n modal.cssClass = '';\n\n /**\n * The content of the modal\n * @attribute content\n * @type {string}\n * @private\n * @default \"\"\n */\n modal.content = '';\n\n /**\n * The content of the dismiss-button\n * @attribute labelDismiss\n * @type {string}\n * @private\n * @default \"Abbrechen\"\n */\n modal.labelDismiss = pm.translate( \"Cancel\" );\n\n /**\n * the label of the confirmation button\n * @attribute labelConfirm\n * @type {string}\n * @private\n * @default \"Bestätigen\"\n */\n modal.labelConfirm = pm.translate( \"Confirm\" );\n\n /**\n * Callback when modal is confirmed by clicking confirmation button.\n * Modal will not be dismissed if callback returns false.\n * @attribute onConfirm\n * @type {function}\n * @private\n * @default function() {}\n */\n modal.onConfirm = function()\n {\n };\n\n /**\n * Callback when modal is dismissed by closing the modal\n * @attribute onDismiss\n * @type {function}\n * @private\n * @default function() {}\n */\n modal.onDismiss = function()\n {\n };\n\n /**\n * jQuery selector of the container element to display the modal in.\n * @attribute container\n * @type {string}\n * @private\n * @default \"body\"\n */\n modal.container = 'body';\n\n /**\n * Timeout to close the modal automatically. Set <0 to disable.\n * @attribute timeout\n * @type {number}\n * @private\n * @default -1\n */\n modal.timeout = -1;\n\n modal.hide = hide;\n modal.startTimeout = startTimeout;\n modal.stopTimeout = stopTimeout;\n modal.pauseTimeout = pauseTimeout;\n modal.continueTimeout = continueTimeout;\n\n var bsModal;\n var timeout, interval;\n var timeRemaining, timeStart;\n var paused = false;\n\n return {\n setTitle : setTitle,\n setClass : setClass,\n setContent : setContent,\n setContainer : setContainer,\n setLabelConfirm: setLabelConfirm,\n setLabelDismiss: setLabelDismiss,\n onConfirm : onConfirm,\n onDismiss : onDismiss,\n setTimeout : setTimeout,\n show : show,\n hide : hide\n };\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/title:attribute}}title{{/crossLink}} of the modal\n * @function setTitle\n * @param {string} title The title\n * @returns {Modal} Modal object for chaining methods\n */\n function setTitle( title )\n {\n modal.title = title;\n return this;\n }\n\n function setClass( cssClass )\n {\n modal.cssClass = cssClass;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/content:attribute}}content{{/crossLink}} of the modal\n * @function setContent\n * @param {string} content The content\n * @returns {Modal} Modal object for chaining methods\n */\n function setContent( content )\n {\n modal.content = content;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/labelConfirm:attribute}}label of the confirmation\n * button{{/crossLink}} of the modal\n * @function setLabelConfirm\n * @param {string} label The label\n * @returns {Modal} Modal object for chaining methods\n */\n function setLabelConfirm( label )\n {\n modal.labelConfirm = label;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/labelDismiss:attribute}}label if the dismiss\n * button{{/crossLink}} of the modal\n * @function setLabelDismiss\n * @param {string} label The label\n * @returns {Modal} Modal object for chaining methods\n */\n function setLabelDismiss( label )\n {\n modal.labelDismiss = label;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/onConfirm:attribute}}confirmation callback{{/crossLink}} of the\n * modal\n * @function onConfirm\n * @param {function} callback The callback if modal is confirmed\n * @returns {Modal} Modal object for chaining methods\n */\n function onConfirm( callback )\n {\n modal.onConfirm = callback;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/onDismiss:attribute}}dismiss callback{{/crossLink}} of the modal\n * @function onDismiss\n * @param {function} callback The callback if modal is dismissed\n * @returns {Modal} Modal object for chaining methods\n */\n function onDismiss( callback )\n {\n modal.onDismiss = callback;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/container:attribute}}container{{/crossLink}} of the modal\n * @function setContainer\n * @param {string} container The jQuery selector of the container to display the modal in\n * @returns {Modal} Modal object for chaining methods\n */\n function setContainer( container )\n {\n modal.container = container;\n return this;\n }\n\n /**\n * Set the {{#crossLink \"ModalFactory.Modal/timeout:attribute}}timeout{{/crossLink}} of the modal\n * @function setTimeout\n * @param {number} timeout The timeout to close the modal automatically. Set <0 to disable\n * @returns {Modal} Modal object for chaining methods\n */\n function setTimeout( timeout )\n {\n modal.timeout = timeout;\n return this;\n }\n\n /**\n * Inject modal data in default template if not template is given\n * and display the modal inside the configured container.
    \n * Start timer to hide the modal automatically if timeout is set.\n * @function show\n */\n function show()\n {\n if( !!modal.selector )\n {\n bsModal = $( modal.selector );\n }\n else\n {\n if ( isModal( modal.content ) )\n {\n bsModal = PlentyFramework.partials.Modal.getModal( modal.content );\n }\n else\n {\n bsModal = $( PlentyFramework.compileTemplate( 'modal/modal.html', modal ) );\n }\n\n $( modal.container ).append( bsModal );\n\n // append additional scripts executable\n var scripts = $( modal.content ).filter( 'script' );\n if ( scripts.length > 0 )\n {\n scripts.each( function( i, script )\n {\n var element = document.createElement( 'script' );\n element.type = 'text/javascript';\n element.innerHTML = $( script ).text();\n $( modal.container ).append( element );\n } );\n }\n }\n\n // bind callback functions\n PlentyFramework.partials.Modal.init( bsModal, modal );\n bsModal.find( '[data-plenty-modal=\"confirm\"]' ).click( function()\n {\n var close = modal.onConfirm();\n\n if ( typeof close == \"undefined\" )\n {\n close = true;\n }\n\n if ( close )\n {\n hide( true );\n }\n } );\n\n PlentyFramework.partials.Modal.show( bsModal );\n\n if ( modal.timeout > 0 )\n {\n startTimeout();\n }\n\n }\n\n /**\n * Hide the modal.\n * @function hide\n * @param {boolean} confirmed Flag indicating of modal is closed by confirmation button or dismissed\n */\n function hide( confirmed )\n {\n PlentyFramework.partials.Modal.hide( bsModal );\n\n if ( !confirmed )\n {\n modal.onDismiss();\n }\n }\n\n /**\n * Start the configured timeout initially\n * @function startTimeout\n * @private\n */\n function startTimeout()\n {\n timeRemaining = modal.timeout;\n timeStart = (new Date()).getTime();\n\n timeout = window.setTimeout( function()\n {\n window.clearInterval( interval );\n hide();\n }, modal.timeout );\n\n bsModal.find( '[data-plenty-modal=\"timer\"]' ).text( timeRemaining / 1000 );\n interval = window.setInterval( function()\n {\n if ( !paused )\n {\n var secondsRemaining = timeRemaining - (new Date()).getTime() + timeStart;\n secondsRemaining = Math.round( secondsRemaining / 1000 );\n bsModal.find( '[data-plenty-modal=\"timer\"]' ).text( secondsRemaining );\n }\n }, 1000 )\n }\n\n /**\n * Pause the timeout (e.g. on hover)\n * @function pauseTimeout\n * @private\n */\n function pauseTimeout()\n {\n paused = true;\n timeRemaining -= (new Date()).getTime() - timeStart;\n window.clearTimeout( timeout );\n }\n\n /**\n * Continue paused timeout\n * @function continueTimeout\n * @private\n */\n function continueTimeout()\n {\n paused = false;\n timeStart = (new Date()).getTime();\n timeout = window.setTimeout( function()\n {\n hide();\n window.clearInterval( interval );\n }, timeRemaining );\n }\n\n /**\n * Stop timeout. Stopped timeouts cannot be continued.\n * @function stopTimeout\n * @private\n */\n function stopTimeout()\n {\n window.clearTimeout( timeout );\n window.clearInterval( interval );\n }\n\n }\n\n } );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Factories\n */\n(function( $, pm )\n{\n\n /**\n * Displaying error messages and handling wait screen\n * @class UIFactory\n * @static\n */\n pm.factory( 'UIFactory', function()\n {\n /**\n * Increased/ decreased when showing/ hiding wait screen to avoid stacking\n * multiple instances of overlays.\n * @attribute waitScreenCount\n * @private\n * @type {number}\n * @default 0\n */\n var waitScreenCount = 0;\n var waitScreen;\n var errorPopup = null;\n\n return {\n throwError : throwError,\n printErrors : printErrors,\n showWaitScreen: showWaitScreen,\n hideWaitScreen: hideWaitScreen\n };\n\n /**\n * Display a single error message.\n * @function throwError\n * @param {number} code A code identifying this error\n * @param {string} msg The error message to display\n */\n function throwError( code, msg )\n {\n printErrors( [{code: code, message: msg}] );\n }\n\n /**\n * Wrap error messages in error popup, if popup doesn't already contain this error\n * If popup is already visible, append new errors to popup's inner HTML\n * otherwise create new popup\n * @function printErrors\n * @param {Array} errorMessages A list of errors to display\n */\n function printErrors( errorMessages )\n {\n\n // create error-popup if not exist\n if ( !errorPopup || $( 'body' ).has( errorPopup ).length <= 0 )\n {\n errorPopup = $( pm.compileTemplate( 'error/errorPopup.html' ) );\n $( 'body' ).append( errorPopup );\n pm.partials.Error.init( errorPopup );\n }\n\n $.each( errorMessages, function( key, error )\n {\n // add additional error, if not exist.\n pm.partials.Error.addError( errorPopup, $( pm.compileTemplate( 'error/errorMessage.html', error ) ) );\n } );\n\n pm.partials.Error.show( errorPopup );\n\n hideWaitScreen( true );\n }\n\n /**\n * Show wait screen if not visible and increase\n * {{#crossLink \"UIFactory/waitScreenCount:attribute\"}}waitScreenCount{{/crossLink}}\n * @function showWaitScreen\n */\n function showWaitScreen()\n {\n waitScreenCount = waitScreenCount || 0;\n\n // create wait-overlay if not exist\n if ( !waitScreen || $( 'body' ).has( waitScreen ).length <= 0 )\n {\n waitScreen = $( pm.compileTemplate( 'waitscreen/waitscreen.html' ) );\n $( 'body' ).append( waitScreen );\n }\n\n pm.partials.WaitScreen.show( waitScreen );\n\n // increase instance counter to avoid showing multiple overlays\n waitScreenCount++;\n return waitScreenCount;\n }\n\n /**\n * Decrease {{#crossLink \"UIFactory/waitScreenCount:attribute\"}}waitScreenCount{{/crossLink}}\n * and hide wait screen if waitScreenCount is 0\n * @function hideWaitScreen\n * @param {boolean} forceClose set true to hide wait screen independent from the value of waitScreenCount.\n */\n function hideWaitScreen( forceClose )\n {\n\n // decrease overlay count\n waitScreenCount--;\n\n // hide if all instances of overlays has been closed\n // or if closing is forced by user\n if ( waitScreenCount <= 0 || !!forceClose )\n {\n waitScreenCount = 0;\n pm.partials.WaitScreen.hide( waitScreen );\n }\n return waitScreenCount;\n }\n\n } );\n}( jQuery, PlentyFramework ));\n/**\n * Factories provide static functions and can be injected into\n * {{#crossLinkModule \"Services\"}}services{{/crossLinkModule}}.
    \n * Factories also can inject other factories. Compared to services,\n * factories are not visible in instances of {{#crossLinkModule \"PlentyFramework\"}}PlentyFramework{{/crossLinkModule}}.\n *\n * @module Factories\n * @main Factories\n */\nObject.equals = function( a, b )\n{\n if ( a === b )\n {\n return true;\n }\n if ( !(a instanceof Object) || !(b instanceof Object) )\n {\n return false;\n }\n if ( a.constructor !== b.constructor )\n {\n return false;\n }\n\n for ( var key in a )\n {\n if ( !a.hasOwnProperty( key ) )\n {\n continue;\n }\n if ( !b.hasOwnProperty( key ) )\n {\n return false;\n }\n if ( a[key] === b[key] )\n {\n continue;\n }\n if ( typeof( a[key] ) !== \"object\" )\n {\n return false;\n }\n if ( !Object.equals( a[key], b[key] ) )\n {\n return false;\n }\n }\n\n for ( var key in b )\n {\n if ( b.hasOwnProperty( key ) && !a.hasOwnProperty( key ) )\n {\n return false;\n }\n }\n\n return true;\n\n};\nPlentyFramework.cssClasses = {\n\n active: \"active\"\n\n};\n(function( $, pm )\n{\n\n pm.partials.Error = {\n\n /**\n * Will be called, after the error popup was created and injected in DOM.\n * @param {HTMLElement} popup The injected element of the popup\n */\n init: function( popup )\n {\n $( popup ).find( '.close' ).click( function()\n {\n pm.partials.Error.hideAll();\n } );\n },\n\n /**\n * Will be called for each thrown error. Has to be injected in DOM manually.\n * @param {HTMLElement} popup The error popup element\n * @param {HTMLElement} error The error message element\n */\n addError: function( popup, error )\n {\n var errorCode = $( error ).attr( 'data-plenty-error-code' );\n\n if ( $( popup ).find( '[data-plenty-error-code=\"' + errorCode + '\"]' ).length <= 0 )\n {\n $( popup ).find( '.plentyErrorBoxInner' ).append( error );\n }\n },\n\n /**\n * Will be called, after initialization and injection of all errors\n * @param {HTMLElement} popup The error popup element\n */\n show: function( popup )\n {\n $( popup ).show();\n },\n\n hideAll: function() {\n $( '#CheckoutErrorPane' ).hide();\n $( '#CheckoutErrorPane' ).find( '.plentyErrorBoxInner' ).html( '' );\n }\n\n }\n\n})( jQuery, PlentyFramework );\n(function( $, pm )\n{\n\n pm.partials.Modal = {\n\n /**\n * Will be called after a new modal was created and injected into DOM\n * @param {HTMLElement} element The injected modal element\n * @param {Modal} modal The instance of the current modal\n */\n init: function( element, modal )\n {\n element.on( 'hidden.bs.modal', function()\n {\n modal.hide();\n if( !modal.selector )\n {\n //Do not remove static modals\n element.remove();\n }\n } );\n\n if ( modal.timeout > 0 )\n {\n element.on( 'hide.bs.modal', modal.stopTimeout );\n element.find( '.modal-content' ).hover( function()\n {\n modal.pauseTimeout();\n }, function()\n {\n if ( element.is( '.in' ) )\n {\n modal.continueTimeout();\n }\n } );\n }\n },\n\n /**\n * Will be called if a Modal requests to show.\n * @param {HTMLElement} element The injected modal element\n */\n show: function( element )\n {\n element.modal( 'show' );\n },\n\n /**\n * Will be called if a Modal requests to hide.\n * @param {HTMLElement} element The injected modal element\n */\n hide: function( element )\n {\n element.modal( 'hide' );\n },\n\n /**\n * Detect if a given HTML string contains a modal\n * @param {HTMLElement} html the element to search a modal in.\n * @returns {boolean} true if a modal was found\n */\n isModal: function( html )\n {\n return $( html ).filter( '.modal' ).length + $( html ).find( '.modal' ).length > 0;\n },\n\n /**\n * Filter a modal from a given HTML string\n * @param {HTMLElement} html the element to get a modal from.\n * @returns {HTMLElement} the filtered modal element\n */\n getModal: function( html )\n {\n var modal = $( html );\n if ( modal.length > 1 )\n {\n modal = $( html ).filter( '.modal' ) || $( html ).find( '.modal' );\n }\n\n return modal;\n }\n\n };\n\n}( jQuery, PlentyFramework ));\n(function( $ )\n{\n\n $( document ).on( 'initPartials', function( e, root )\n {\n\n $( root ).find( '[data-toggle=\"tooltip\"]' ).tooltip( {\n container: 'body'\n } );\n\n } );\n\n})( jQuery );\n(function( $, pm )\n{\n\n pm.partials.WaitScreen = {\n\n /**\n * Will be called if the wait screen should be shown\n * @param {HTMLElement} element The wait screen element\n */\n show: function( element )\n {\n element.addClass( 'in' );\n },\n\n /**\n * Will be called if the wait screen should be hidden\n * @param {HTMLElement} element The wait screen element\n */\n hide: function( element )\n {\n element.removeClass( 'in' );\n }\n\n };\n\n})( jQuery, PlentyFramework );\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n(function( $, pm )\n{\n pm.service( 'AddressDoctorService', function( API )\n {\n return {\n validateAddress: validateAddress\n };\n\n function validateAddress( addressForms )\n {\n var addressIsValid = true;\n addressForms = addressForms || '[data-plenty-address-doctor]';\n $( addressForms ).filter( '[data-plenty-address-doctor]:visible' ).each( function( i, form )\n {\n var addressDoctor = new AddressDoctor( form );\n var requiredFields = $( form ).attr( 'data-plenty-address-doctor' ).replace( /\\s/g, '' ).split( ',' );\n if ( !addressDoctor.isValid( requiredFields ) )\n {\n addressIsValid = false;\n }\n\n } );\n\n return addressIsValid;\n }\n\n function AddressDoctor( form )\n {\n var $form = $( form );\n var $inputs = {\n Street : $form.find( 'input[name=\"Street\"]' ),\n ZIP : $form.find( 'input[name=\"ZIP\"]' ),\n City : $form.find( 'input[name=\"City\"]' ),\n HouseNo: $form.find( 'input[name=\"HouseNo\"]' )\n };\n var $suggestionContainer = {};\n\n var suggestions;\n var requiredFields;\n\n return {\n isValid: isValid\n };\n\n function isValid( fields )\n {\n\n if ( isPackstation() )\n {\n return true;\n }\n\n suggestions = new AddressList( $form.getFormValues() );\n requiredFields = fields;\n\n refreshView();\n\n return suggestions.getAddresses().length == 1;\n }\n\n function refreshView()\n {\n $( '.suggestion-list' ).remove();\n\n var suggestionListVisible = false;\n for ( var i = 0; i < requiredFields.length; i++ )\n {\n if ( !validateInput( requiredFields[i], suggestionListVisible ) )\n {\n $form.trigger( 'validationFailed' );\n suggestionListVisible = true;\n }\n }\n\n if ( suggestions.houseNoAllowed( $inputs.HouseNo.val() ) || suggestions.getAddresses().length == 1 )\n {\n $inputs.HouseNo.removeClass( 'has-error' );\n $form.find( 'label[for=\"' + $inputs.HouseNo.attr( 'id' ) + '\"]' ).removeClass( 'has-error' );\n\n $inputs.HouseNo.addClass( 'has-success' );\n $form.find( 'label[for=\"' + $inputs.HouseNo.attr( 'id' ) + '\"]' ).addClass( 'has-success' );\n }\n else\n {\n $inputs.HouseNo.removeClass( 'has-success' );\n $form.find( 'label[for=\"' + $inputs.HouseNo.attr( 'id' ) + '\"]' ).removeClass( 'has-success' );\n\n $inputs.HouseNo.addClass( 'has-error' );\n $form.find( 'label[for=\"' + $inputs.HouseNo.attr( 'id' ) + '\"]' ).addClass( 'has-error' );\n }\n }\n\n function validateInput( key, suggestionListVisible )\n {\n var valueList = suggestions.getList( key );\n\n if ( !!$suggestionContainer[key] )\n {\n $suggestionContainer[key].remove();\n }\n\n if ( !$inputs[key] )\n {\n return true;\n }\n\n if ( valueList.length == 1 )\n {\n $inputs[key].val( valueList[0] );\n\n $inputs[key].removeClass( 'has-error' );\n $form.find( 'label[for=\"' + $inputs[key].attr( 'id' ) + '\"]' ).removeClass( 'has-error' );\n\n $inputs[key].addClass( 'has-success' );\n $form.find( 'label[for=\"' + $inputs[key].attr( 'id' ) + '\"]' ).addClass( 'has-success' );\n return true;\n }\n else\n {\n $inputs[key].removeClass( 'has-success' );\n $form.find( 'label[for=\"' + $inputs[key].attr( 'id' ) + '\"]' ).removeClass( 'has-success' );\n\n $inputs[key].addClass( 'has-error' );\n $form.find( 'label[for=\"' + $inputs[key].attr( 'id' ) + '\"]' ).addClass( 'has-error' );\n\n if ( !suggestionListVisible )\n {\n buildSuggestionList( $inputs[key], valueList );\n }\n $inputs[key].off( 'focus' );\n $inputs[key].focus();\n return false;\n\n }\n }\n\n function positionSuggestionList( $parent, suggestionKey )\n {\n $suggestionContainer[suggestionKey].css( {\n 'width': $parent.outerWidth( true ),\n 'left' : $parent.position().left,\n 'top' : $parent.position().top + $parent.outerHeight( true )\n } );\n }\n\n function buildSuggestionList( $parent, values )\n {\n var suggestionKey = $parent.attr( 'name' );\n\n // render html content\n $suggestionContainer[suggestionKey] = $( pm.compileTemplate( 'addressSuggestions/addressDoctor.html', {values: values} ) );\n\n positionSuggestionList( $parent, suggestionKey );\n\n $( window ).on( 'sizeChange', function()\n {\n positionSuggestionList( $parent, suggestionKey );\n } );\n\n // bind click event to list elements\n $suggestionContainer[suggestionKey].find( '[data-address-value]' ).each( function( i, elem )\n {\n\n var $elem = $( elem );\n var value = $elem.attr( 'data-address-value' );\n\n $elem.click( function()\n {\n // insert clicked value in input\n $parent.val( value );\n\n // filter addresses and show remaining suggestions\n var filterAddress = {};\n filterAddress[$parent.attr( 'name' )] = value;\n suggestions.filter( filterAddress );\n\n // refresh suggestion lists\n refreshView();\n\n } );\n\n } );\n\n // inject html\n $parent.parent().append( $suggestionContainer[suggestionKey] );\n }\n\n function isPackstation()\n {\n return ( $inputs.Street.val().toUpperCase() == \"PACKSTATION\" || $inputs.Street.val().toUpperCase() == \"POSTFILIALE\" );\n }\n\n }\n\n function AddressList( addressInput )\n {\n var addresses = [];\n\n init();\n\n return {\n getAddresses : getAddresses,\n getList : getList,\n filter : filter,\n houseNoAllowed: houseNoAllowed\n };\n\n function init()\n {\n API.get( '/rest/checkout/addresssuggestionresultslist/', {\n suggestionType: \"addressdoctor\",\n street : addressInput.Street,\n ZIP : addressInput.ZIP,\n city : addressInput.City,\n houseNo : addressInput.HouseNo,\n country : addressInput.CountryID\n }, false, false, true ).done( function( response )\n {\n\n var responseLength = response.data.length;\n\n for ( var i = 0; i < responseLength; i++ )\n {\n var currentResponse = response.data[i];\n\n var address = getAddress( currentResponse )\n if ( !address )\n {\n currentResponse.HouseNo = [currentResponse.HouseNo];\n addresses.push( currentResponse );\n }\n else\n {\n address.HouseNo.push( currentResponse.HouseNo );\n }\n\n }\n\n } );\n }\n\n function getAddress( suggestion )\n {\n var addressCount = addresses.length;\n\n for ( var j = 0; j < addressCount; j++ )\n {\n if ( suggestion.Street == addresses[j].Street && addresses.ZIP == addresses[j].ZIP && suggestion.City == addresses[j].City )\n {\n return addresses[j];\n }\n }\n\n return null;\n\n }\n\n function getAddresses()\n {\n return addresses;\n }\n\n function getList( key )\n {\n var results = [];\n var addressCount = addresses.length;\n\n for ( var i = 0; i < addressCount; i++ )\n {\n var address = addresses[i];\n if ( $.inArray( address[key], results ) < 0 )\n {\n results.push( address[key] );\n }\n }\n\n return results;\n }\n\n function filter( filterAddress )\n {\n var filteredAddresses = [];\n var addressCount = addresses.length;\n\n for ( var i = 0; i < addressCount; i++ )\n {\n var address = addresses[i];\n if ( (!!filterAddress.Street && filterAddress.Street == address.Street)\n || (!!filterAddress.ZIP && filterAddress.ZIP == address.ZIP)\n || (!!filterAddress.City && filterAddress.City == address.City) )\n {\n filteredAddresses.push( address );\n }\n }\n\n addresses = filteredAddresses;\n }\n\n function houseNoAllowed( houseNo )\n {\n houseNo = parseInt( houseNo );\n\n var addressCount = addresses.length;\n\n for ( var i = 0; i < addressCount; i++ )\n {\n var address = addresses[i];\n\n for ( var j = 0; j < address.HouseNo.length; j++ )\n {\n var range = address.HouseNo[j].split( '-' );\n if ( ( range.length == 1 && houseNo == range[0] )\n || range.length == 2 && houseNo >= range[0] && houseNo <= range[1] )\n {\n return true;\n }\n }\n }\n\n return false;\n }\n }\n\n }, ['APIFactory'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Providing methods for logging in and out and registering new customers.
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CheckoutFactory\"}}CheckoutFactory{{/crossLink}}
    • \n *
    \n * @class AuthenticationService\n * @static\n */\n pm.service( 'AuthenticationService', function( API, Checkout, UI )\n {\n\n return {\n resetPassword : resetPassword,\n customerLogin : customerLogin,\n setInvoiceAddress: setInvoiceAddress,\n registerCustomer : registerCustomer\n };\n\n /**\n * Reading E-Mail from form marked with data-plenty-checkout=\"lostPasswordForm\"\n * and sends request to provide a new password to the entered E-Mail-Address.\n *\n * @function resetPasswort\n * @return {object} jQuery deferred\n * Object\n */\n function resetPassword()\n {\n\n var form = $( '[data-plenty-checkout=\"lostPasswordForm\"]' );\n\n if ( form.validateForm() )\n {\n\n var values = form.getFormValues();\n\n var params = {\n Email: values.Email\n };\n\n return API.post( \"/rest/checkout/lostpassword/\", params )\n .done( function( response )\n {\n if ( response.data.IsMailSend == true )\n {\n $( '[data-plenty-checkout=\"lostPasswordTextContainer\"]' ).hide();\n $( '[data-plenty-checkout=\"lostPasswordSuccessMessage\"]' ).show();\n }\n } );\n\n }\n }\n\n /**\n * Try to login in with credentials read from given <form> - element.\n * On success redirect to forms 'action' attribute.\n *\n * @function customerLogin\n * @param {object} form The jQuery-wrapped form-element to read the credentials from\n * @return {object} jQuery deferred\n * Object\n */\n function customerLogin( form )\n {\n if ( form.validateForm() )\n {\n var values = form.getFormValues();\n\n var params = {\n Email : values.loginMail,\n Password: values.loginPassword\n };\n\n UI.showWaitScreen();\n return API.post( \"/rest/checkout/login/\", params )\n .done( function()\n {\n // successful login -> go to form's target referenced by action-attribute\n window.location.assign( form.attr( 'action' ) );\n\n } );\n }\n }\n\n /**\n * Setting the invoice address of a newly registered customer or a guest.\n *\n * @function setInvoiceAddress\n * @param {object} invoiceAddress containing address-data sent to server\n * @return {object} jQuery deferred\n * Object\n */\n function setInvoiceAddress( invoiceAddress )\n {\n\n return API.post( \"/rest/checkout/customerinvoiceaddress/\", invoiceAddress )\n .done( function( response )\n {\n Checkout.getCheckout().CustomerInvoiceAddress = response.data;\n } );\n }\n\n /**\n * Prepare address-data to register new customer. Read the address-data from a <form> marked with\n * data-plenty-checkout-form=\"customerRegistration\"
    \n * On success, redirect to forms target referenced by action-attribute\n *\n * @function registerCustomer\n * @return {object} jQuery deferred\n * Object\n */\n function registerCustomer()\n {\n var form = $( '[data-plenty-checkout-form=\"customerRegistration\"]' );\n\n if ( form.validateForm() && pm.getInstance().AddressDoctorService.validateAddress() )\n {\n var values = form.getFormValues();\n values.LoginType = 2;\n\n if ( values.checkout\n && values.checkout.customerInvoiceAddress\n && values.checkout.customerInvoiceAddress.CustomerProperty )\n {\n var tmpProperties = values.checkout.customerInvoiceAddress.CustomerProperty;\n values.CustomerPropertiesList = values.CustomerPropertiesList || [];\n\n for ( var property in tmpProperties )\n {\n if ( tmpProperties[property] )\n {\n values.CustomerPropertiesList.push( {\n PropertyID : property,\n PropertyValue: tmpProperties[property]\n } );\n }\n }\n }\n\n return setInvoiceAddress( values )\n .done( function()\n {\n window.location.assign( form.attr( 'action' ) );\n } );\n }\n }\n }, ['APIFactory', 'CheckoutFactory', 'UIFactory'] );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Providing methods for adding, editing or removing basket items and coupon codes
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"UIFactory\"}}UIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CMSFactory\"}}CMSFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CheckoutFactory\"}}CheckoutFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"ModalFactory\"}}ModalFactory{{/crossLink}}
    • \n *
    \n * @class BasketService\n * @static\n */\n pm.service( 'BasketService', function( API, UI, CMS, Checkout, Modal )\n {\n\n return {\n addItem : addBasketItem,\n removeItem : removeBasketItem,\n getItem : getBasketItem,\n setItemQuantity : setItemQuantity,\n editItemAttributes: editItemAttributes,\n editOrderParams : editOrderParams,\n addCoupon : addCoupon,\n removeCoupon : removeCoupon\n };\n\n /**\n * Add item to basket. Will fail and show a popup if item has order params\n * @function addBasketItem\n * @param {Array} article Array containing the item to add\n * @param {boolean} [isUpdate=false] Indicating if item's OrderParams are updated\n * @return {object} jQuery deferred\n * Object\n */\n function addBasketItem( article )\n {\n\n if ( !!article )\n {\n\n API.get( '/rest/checkout/container_' + 'CheckoutOrderParamsList'.toLowerCase() + '/',\n {\n itemID : article[0].BasketItemItemID,\n quantity: article[0].BasketItemQuantity\n }, false, true ).done( function( resp )\n {\n // checking for order params!\n if ( resp.data[0].indexOf( \"form-group\" ) > 0 )\n {\n Modal.prepare()\n .setContent( resp.data[0] )\n .setTitle( pm.translate( \"Select order parameters\" ) )\n .setLabelConfirm( pm.translate( \"Save\" ) )\n .onConfirm( function()\n {\n // validate form\n if ( $( '[data-plenty-checkout-form=\"OrderParamsForm\"]' ).validateForm() )\n {\n // save order params\n addArticle( saveOrderParams( article ) );\n\n // close modal after saving order params\n return true;\n }\n else\n {\n return false;\n }\n } )\n .show();\n }\n else\n {\n addArticle( article );\n }\n } );\n }\n }\n\n /**\n * Read OrderParams from <form> marked with data-plenty-checkout-form=\"OrderParamsForm\" and inject\n * read values in 'addBasketList'. Update item by calling addBasketItem() again\n * @function saveOrderParams\n * @private\n * @param {Array} articleWithParams Containing the current item to add. Read OrderParams will be injected\n */\n function saveOrderParams( articleWithParams )\n {\n //TODO use $(\"[data-plenty-checkout-form='OrderParamsForm']\").serializeArray() to get order params\n var orderParamsForm = $( '[data-plenty-checkout-form=\"OrderParamsForm\"]' );\n var $self = {};\n var attrType = \"\";\n var match;\n\n //Groups\n orderParamsForm.find( '[name^=\"ParamGroup\"]' ).each( function()\n {\n match = this.name.match( /^ParamGroup\\[(\\d+)]\\[(\\d+)]$/ );\n articleWithParams = addOrderParamValue( articleWithParams, match[1], $( this ).val(), $( this ).val() );\n } );\n\n //Values\n orderParamsForm.find( '[name^=\"ParamValue\"]' ).each( function()\n {\n $self = $( this );\n attrType = $self.attr( 'type' );\n\n if ( ((attrType == 'checkbox' && $self.is( ':checked' )) ||\n (attrType == 'radio' && $self.is( ':checked' )) ||\n (attrType != 'radio' && attrType != 'checkbox')) && attrType != 'file' && attrType != 'hidden' )\n {\n\n var match = $self[0].name.match( /^ParamValue\\[(\\d+)]\\[(\\d+)]$/ );\n articleWithParams = addOrderParamValue( articleWithParams, match[1], match[2], $self.val() );\n\n }\n else if ( attrType == 'file' )\n {\n if ( $self[0].files && $self[0].files.length > 0 )\n {\n articleWithParams = orderParamFileUpload( $self, articleWithParams );\n }\n else\n {\n var match = $self[0].name.match( /^ParamValueFile\\[(\\d+)]\\[(\\d+)]$/ );\n var paramValue = $( 'input[type=\"hidden\"][name=\"ParamValue[' + match[1] + '][' + match[2] + ']\"]' ).val();\n articleWithParams = addOrderParamValue( articleWithParams, match[1], match[2], paramValue );\n }\n }\n } );\n\n return articleWithParams;\n }\n\n function addArticle( article )\n {\n API.post( '/rest/checkout/basketitemslist/', article, true )\n .done( function()\n {\n // Item has no OrderParams -> Refresh Checkout & BasketPreview\n Checkout.loadCheckout()\n .done( function()\n {\n var $artAttr = $( \"[name^=ArticleAttribute]\" );\n var $unitCombinationId = article[0].BasketItemPriceID;\n var requestData = {ArticleID: article[0].BasketItemItemID};\n\n if ( $artAttr.val() > 0 )\n {\n $artAttr.each( function( i, value )\n {\n value = $( value );\n requestData[value.attr( \"name\" )] = value.val();\n } );\n }\n else if ( $unitCombinationId && $unitCombinationId > 0 )\n {\n requestData[\"UnitCombinationId\"] = $unitCombinationId;\n }\n\n refreshBasketPreview();\n\n // Show confirmation popup\n CMS.getContainer( 'ItemViewItemToBasketConfirmationOverlay', requestData ).from( 'ItemView' )\n .done( function( response )\n {\n var timeout = pm.getGlobal( 'TimeoutItemToBasketOverlay', 5000 );\n var modal = Modal.prepare().setContent( response.data[0] );\n\n if ( timeout > 0 )\n {\n modal.setTimeout( timeout );\n }\n\n modal.show();\n } );\n } );\n } ).fail( function( jqXHR )\n {\n // some other error occured\n UI.printErrors( JSON.parse( jqXHR.responseText ).error.error_stack );\n } );\n }\n\n function updateArticle( article )\n {\n API.put( '/rest/checkout/basketitemslist/', article )\n .done( function()\n {\n // Item has no OrderParams -> Refresh Checkout & BasketPreview\n Checkout.reloadCatContent( pm.getGlobal( 'basketCatID' ) );\n Checkout.loadCheckout()\n .done( function()\n {\n refreshBasketPreview();\n } );\n } )\n }\n\n function orderParamFileUpload( $input, articleWithParams )\n {\n var key = $input[0].id;\n var orderParamUploadFiles = {};\n var orderParamFileIdStack = [];\n var formData;\n var fileData;\n var params = {\n type : 'POST',\n data : {},\n isFile : true,\n cache : false,\n dataType : 'json',\n processData: false,\n contentType: false\n };\n\n orderParamUploadFiles[key] = $input[0].files;\n\n // if input not pushed before.\n if ( orderParamFileIdStack.indexOf( key ) == -1 )\n {\n orderParamFileIdStack.push( key );\n }\n\n for ( var i = 0, length = orderParamFileIdStack.length; i < length; ++i )\n {\n formData = new FormData();\n fileData = orderParamUploadFiles[orderParamFileIdStack[i]];\n formData.append( \"0\", fileData[0], fileData[0].name );\n\n params.data = formData;\n\n API.post( \"/rest/checkout/orderparamfile/\", params );\n }\n\n var match = $input[0].name.match( /^ParamValueFile\\[(\\d+)]\\[(\\d+)]$/ );\n\n return addOrderParamValue( articleWithParams, match[1], match[2], orderParamUploadFiles[key][0]['name'] );\n }\n\n /**\n * Inject an OrderParam.\n * @function addOrderParamValue\n * @private\n * @param {Array} basketList The target to inject the value in.\n * @param {number} position Position where to inject the value\n * @param {number} paramId The ID of the OrderParam to inject\n * @param {string|number} paramValue the value of the OrderParam to inject\n * @returns {Array} Containing the item and the injected OrderParam\n */\n function addOrderParamValue( basketList, position, paramId, paramValue )\n {\n if ( position > 0 && basketList[position] == undefined )\n {\n basketList[position] = $.extend( true, {}, basketList[0] );\n basketList[position].BasketItemOrderParamsList = [];\n }\n\n if ( basketList[position] != undefined )\n {\n basketList[position].BasketItemQuantity = 1;\n if ( basketList[position].BasketItemOrderParamsList == undefined )\n {\n basketList[position].BasketItemOrderParamsList = [];\n }\n if ( paramValue )\n {\n basketList[position].BasketItemOrderParamsList.push( {\n BasketItemOrderParamID : paramId,\n BasketItemOrderParamValue: paramValue\n } );\n }\n }\n\n return basketList;\n }\n\n function editItemAttributes( BasketItemID )\n {\n var modal = $( '[data-plenty-basket-item=\"' + BasketItemID + '\"]' );\n modal.modal( 'show' );\n modal.find( '[data-plenty-modal=\"confirm\"]' ).on( 'click', function()\n {\n var basketItem = getBasketItem( BasketItemID );\n var attributesList = [];\n\n // check for select or list of images\n modal.find( 'select, .PlentyFormContainer.AttrImage > input[type=\"hidden\"]' ).each( function( i, attributeSelect )\n {\n var match = attributeSelect.name.match( /^ArticleAttribute\\[\\d+]\\[\\d+]\\[(\\d+)]$/ );\n if ( match && match[1] )\n {\n attributesList.push( {\n BasketItemAttributeID : match[1],\n BasketItemAttributeValueID: $( attributeSelect ).val()\n } );\n }\n\n } );\n\n if ( attributesList.length != 0 )\n {\n basketItem.BasketItemAttributesList = attributesList;\n }\n //update basketItem and refresh previewLists\n updateArticle( [basketItem] );\n\n } );\n }\n\n function editOrderParams( BasketItemID )\n {\n\n var basketItem = getBasketItem( BasketItemID );\n // FIX: unset old order params\n\n basketItem.BasketItemOrderParamsList = [];\n\n API.get( '/rest/checkout/container_' + 'CheckoutOrderParamsList'.toLowerCase() + '/', {\n itemID : basketItem.BasketItemItemID,\n quantity : basketItem.BasketItemQuantity,\n basketItemID: BasketItemID\n } ).done( function( resp )\n {\n // checking for order params!\n Modal.prepare()\n .setContent( resp.data[0] )\n .setTitle( pm.translate( \"Edit order parameters\" ) )\n .setLabelConfirm( pm.translate( \"Save\" ) )\n .onConfirm( function()\n {\n // validate form\n if ( $( '[data-plenty-checkout-form=\"OrderParamsForm\"]' ).validateForm() )\n {\n // save order params\n updateArticle( saveOrderParams( [basketItem] ) );\n\n // close modal after saving order params\n return true;\n }\n else\n {\n return false;\n }\n } )\n .show();\n } );\n }\n\n function getBasketItem( BasketItemID )\n {\n var basketItems = Checkout.getCheckout().BasketItemsList;\n for ( var i = 0; i < basketItems.length; i++ )\n {\n if ( basketItems[i].BasketItemID == BasketItemID )\n {\n return basketItems[i];\n }\n }\n\n return null;\n }\n\n /**\n * Remove item from basket. Will show a confirmation popup at first.\n * @function removeBasketItem\n * @param {number} BasketItemID The ID of the basket item to remove\n * @param {boolean} [forceDelete=false] Set true to remove the basket item without showing a confirmation popup\n * @return Promise\n */\n function removeBasketItem( BasketItemID, forceDelete )\n {\n\n var deferred = $.Deferred();\n\n // get item name\n var itemName = getBasketItem( BasketItemID ).BasketItemNameMap[1];\n\n // calling the delete request\n function doDelete()\n {\n API.delete( '/rest/checkout/basketitemslist/?basketItemIdsList[0]=' + BasketItemID )\n .done( function()\n {\n Checkout.loadCheckout().done( function()\n {\n //$( '[data-basket-item-id=\"' + BasketItemID + '\"]' ).remove();\n\n if ( !Checkout.getCheckout().BasketItemsList || Checkout.getCheckout().BasketItemsList.length <= 0 )\n {\n Checkout.reloadCatContent( pm.getGlobal( 'basketCatID' ) );\n }\n else\n {\n // FALLBACK if design not support selector\n // [data-plenty-checkout-template=\"BasketItemsList\"]\n if ( $( '[data-plenty-checkout-template=\"BasketItemsList\"]' ).length >= 0 )\n {\n API.get( \"/rest/checkout/container_checkoutbasketitemslist/\" ).done( function( response )\n {\n var $oldBasketList = $( '[data-basket-item-id]' ).parents( \"ul\" );\n var $basketListContainer = $oldBasketList.parents( \".panel-body\" );\n $oldBasketList.fadeOut( function()\n {\n $( this ).siblings( \":not('[data-plenty-checkout-template]')\" ).remove();\n $( this ).remove();\n $basketListContainer.prepend( $( response.data[0] ) ).hide().fadeIn( function()\n {\n pm.getInstance().bindDirectives( $basketListContainer );\n } );\n } );\n } );\n }\n else\n {\n Checkout.reloadContainer( 'BasketItemsList' );\n }\n Checkout.reloadContainer( 'Totals' );\n }\n\n refreshBasketPreview();\n\n deferred.resolve();\n } );\n } );\n }\n\n if ( !forceDelete )\n {\n // show confirmation popup\n Modal.prepare()\n .setTitle( pm.translate( 'Please confirm' ) )\n .setContent( '

    ' + pm.translate( \"Do you really want to remove \\\"{{item}}\\\" from your basket?\", {item: itemName} ) + '

    ' )\n .onDismiss( function()\n {\n //$('[data-basket-item-id=\"' + BasketItemID +\n // '\"]').find('[data-plenty=\"quantityInput\"]').val(originalItemQuantity);\n deferred.reject();\n } )\n .onConfirm( function()\n {\n doDelete();\n } )\n .setLabelConfirm( pm.translate( \"Delete\" ) )\n .show();\n }\n else\n {\n doDelete();\n }\n\n return deferred;\n }\n\n /**\n * Set a new quantity for the given BasketItem. If quantity is set to 0,\n * remove the item.\n * @function setItemQuantity\n * @param {number} BasketItemID The ID of the basket item to change the quantity of\n * @param {number} BasketItemQuantity The new quantity to set or 0 to remove the item\n */\n function setItemQuantity( BasketItemID, BasketItemQuantity )\n {\n // delete item if quantity is 0\n if ( BasketItemQuantity <= 0 )\n {\n return removeBasketItem( BasketItemID );\n }\n\n var deferred = $.Deferred();\n var params = Checkout.getCheckout().BasketItemsList;\n var basketItem;\n var basketItemIndex;\n\n for ( var i = 0; i < params.length; i++ )\n {\n if ( params[i].BasketItemID == BasketItemID )\n {\n basketItemIndex = i;\n basketItem = params[i];\n break;\n\n }\n }\n\n if ( !!basketItem && basketItem.BasketItemQuantity != BasketItemQuantity )\n {\n params[basketItemIndex].BasketItemQuantity = parseInt( BasketItemQuantity );\n\n API.post( \"/rest/checkout/basketitemslist/\", params )\n .done( function()\n {\n Checkout.setCheckout().done( function()\n {\n Checkout.reloadCatContent( pm.getGlobal( 'basketCatID' ) );\n refreshBasketPreview();\n deferred.resolve();\n } );\n } );\n }\n\n return deferred;\n }\n\n /**\n * Reload BasketPreview-Template and update basket totals\n * @function refreshBasketPreview\n * @private\n */\n function refreshBasketPreview()\n {\n\n Checkout.reloadItemContainer( 'BasketPreviewList' )\n .done( function()\n {\n\n $( '[data-plenty-basket-empty]' ).each( function( i, elem )\n {\n var toggleClass = $( elem ).attr( 'data-plenty-basket-empty' );\n if ( Checkout.getCheckout().BasketItemsList.length <= 0 )\n {\n $( elem ).addClass( toggleClass );\n }\n else\n {\n $( elem ).removeClass( toggleClass );\n }\n } );\n\n } );\n\n //update quantity\n var itemQuantityTotal = 0;\n $.each( Checkout.getCheckout().BasketItemsList, function( i, basketItem )\n {\n itemQuantityTotal += basketItem.BasketItemQuantity;\n } );\n\n $( '[data-plenty-basket-preview=\"itemQuantityTotal\"]' ).text( itemQuantityTotal );\n $( '[data-plenty-basket-preview=\"totalsItemSum\"]' ).text( Checkout.getCheckout().Totals.TotalsItemSum );\n }\n\n /**\n * Read the coupon code from an <input> element marked with data-plenty-checkout-form=\"couponCode\"\n * and try to add this coupon.\n * @function addCoupon\n * @return {object} jQuery deferred\n * Object\n */\n function addCoupon()\n {\n var params = {\n CouponActiveCouponCode: $( '[data-plenty-checkout-form=\"couponCode\"]' ).val()\n };\n\n return API.post( \"/rest/checkout/coupon/\", params )\n .done( function()\n {\n Checkout.setCheckout()\n .done( function()\n {\n\n updateContainer();\n } );\n } );\n }\n\n /**\n * Remove the currently added coupon\n * @function removeCoupon\n * @return {object} jQuery deferred\n * Object\n */\n function removeCoupon()\n {\n var params = {\n CouponActiveCouponCode: Checkout.getCheckout().Coupon.CouponActiveCouponCode\n };\n\n return API.delete( \"/rest/checkout/coupon/\", params )\n .done( function()\n {\n Checkout.setCheckout()\n .done( function()\n {\n delete Checkout.getCheckout().Coupon;\n\n updateContainer();\n } );\n } );\n }\n\n // update container\n function updateContainer()\n {\n Checkout.reloadContainer( 'Coupon' );\n // reload totals, if we are at basket\n if ( $( '[data-plenty-checkout-template=\"Totals\"]' ).length > 0 )\n {\n Checkout.reloadContainer( 'Totals' );\n }\n }\n\n }, ['APIFactory', 'UIFactory', 'CMSFactory', 'CheckoutFactory', 'ModalFactory'] );\n}( jQuery, PlentyFramework ));\n\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Providing methods for checkout process like setting shipping & payment information and placing the order.
    \n * Requires:\n *
      \n *
    • {{#crossLink \"APIFactory\"}}APIFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CMSFactory\"}}CMSFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"CheckoutFactory\"}}CheckoutFactory{{/crossLink}}
    • \n *
    • {{#crossLink \"ModalFactory\"}}ModalFactory{{/crossLink}}
    • \n *
    \n * @class CheckoutService\n * @static\n */\n pm.service( 'CheckoutService', function( API, UI, CMS, Checkout, Modal )\n {\n\n return {\n init : init,\n setCustomerSignAndInfo: setCustomerSignAndInfo,\n registerGuest : registerGuest,\n setShippingProfile : setShippingProfile,\n saveShippingAddress : saveShippingAddress,\n loadAddressSuggestion : loadAddressSuggestion,\n preparePayment : preparePayment,\n setMethodOfPayment : setMethodOfPayment,\n confirmAtrigaPaymax : confirmAtrigaPaymax,\n editBankDetails : editBankDetails,\n editCreditCard : editCreditCard,\n placeOrder : placeOrder\n };\n\n /**\n * Load checkout data initially on page load\n * @function init\n */\n function init()\n {\n Checkout.loadCheckout( true );\n }\n\n /**\n * Read customer sign and order information text from <form> marked with\n * data-plenty-checkout-form=\"details\" and update checkout.\n * @function setCustomerSignAndInfo\n * @return {object} jQuery deferred\n * Object\n */\n function setCustomerSignAndInfo()\n {\n var form = $( '[data-plenty-checkout-form=\"details\"]' );\n var values = form.getFormValues();\n\n // initialize CustomerSign & InfoText to avoid updating empty values\n if ( !Checkout.getCheckout().CheckoutCustomerSign )\n {\n Checkout.getCheckout().CheckoutCustomerSign = \"\";\n }\n if ( !Checkout.getCheckout().CheckoutOrderInfoText )\n {\n Checkout.getCheckout().CheckoutOrderInfoText = \"\";\n }\n\n if ( ( Checkout.getCheckout().CheckoutCustomerSign !== values.CustomerSign && $( form ).find( '[name=\"CustomerSign\"]' ).length > 0 )\n || ( Checkout.getCheckout().CheckoutOrderInfoText !== values.OrderInfoText && $( form ).find( '[name=\"OrderInfoText\"]' ).length > 0 ) )\n {\n\n Checkout.getCheckout().CheckoutCustomerSign = values.CustomerSign;\n Checkout.getCheckout().CheckoutOrderInfoText = values.OrderInfoText;\n\n return Checkout.setCheckout();\n\n }\n else\n {\n // No changes detected -> Do nothing\n return API.idle();\n }\n }\n\n /**\n * Read address data from <form> marked with data-plenty-checkout-form=\"shippingAddress\".\n * Create new shipping address or update the shipping address ID.\n * @function saveShippingAddress\n * @param {boolean} [validateForm = false] validate form before processing requests\n * @return {object} jQuery deferred\n * Object\n */\n function saveShippingAddress( validateForm )\n {\n var form = $( '[data-plenty-checkout-form=\"shippingAddress\"]' );\n\n if ( !validateForm && !form.validateForm() )\n {\n return false;\n }\n\n if ( !validateForm && !pm.getInstance().AddressDoctorService.validateAddress( form ) )\n {\n return false;\n }\n\n var values = form.getFormValues();\n var shippingAddressID = $( '[name=\"shippingAddressID\"]:checked' ).val();\n\n if ( shippingAddressID < 0 )\n {\n // save separate\n var shippingAddress = values;\n\n if ( !addressesAreEqual( shippingAddress, Checkout.getCheckout().CustomerShippingAddress ) )\n {\n if ( shippingAddress.Street == \"PACKSTATION\" )\n {\n shippingAddress.IsPackstation = 1;\n shippingAddress.PackstationNo = shippingAddress.HouseNo;\n }\n else if ( shippingAddress.Street == \"POSTFILIALE\" )\n {\n shippingAddress.IsPostfiliale = 1;\n shippingAddress.PostfilialNo = shippingAddress.HouseNo;\n }\n\n // new shipping address\n return API.post( \"/rest/checkout/customershippingaddress/\", shippingAddress )\n .done( function( response )\n {\n\n Checkout.getCheckout().CheckoutCustomerShippingAddressID = response.data.ID;\n Checkout.getCheckout().CheckoutShippingCountryID = response.data.CountryID;\n\n updatePaymentAndShippingDependencies();\n } );\n }\n else\n {\n // no changes detected\n return API.idle();\n }\n\n }\n else\n {\n if ( shippingAddressID != Checkout.getCheckout().CheckoutCustomerShippingAddressID )\n {\n // change shipping address id\n Checkout.getCheckout().CheckoutCustomerShippingAddressID = shippingAddressID;\n\n updatePaymentAndShippingDependencies();\n }\n else\n {\n return API.idle();\n }\n }\n }\n\n function updatePaymentAndShippingDependencies()\n {\n delete Checkout.getCheckout().CheckoutMethodOfPaymentID;\n delete Checkout.getCheckout().CheckoutShippingProfileID;\n\n return Checkout.setCheckout().done( function()\n {\n Checkout.reloadContainer( \"MethodsOfPaymentList\" );\n Checkout.reloadContainer( \"ShippingProfilesList\" );\n\n if ( Checkout.getCheckout().CustomerInvoiceAddress.LoginType == 2 )\n {\n Checkout.reloadContainer( 'CustomerShippingAddress' );\n }\n $( '#shippingAdressSelect' ).modal( 'hide' );\n\n // don't hit me. Ugly hack: this is to force quit/remove everything from modal.\n if ( $( \".modal-backdrop\" ) )\n {\n $( \".modal-backdrop\" ).remove();\n }\n } );\n }\n\n /**\n * Prepare address-data to register a guest. Reads the address-data from a <form> marked with\n * data-plenty-checkout-form=\"guestRegistration\"\n * @function registerGuest\n * @return {object} jQuery deferred\n * Object\n */\n function registerGuest()\n {\n var form = $( '[data-plenty-checkout-form=\"guestRegistration\"]' );\n\n var invoiceAddress = form.getFormValues();\n invoiceAddress.LoginType = 1;\n\n // add custom properties if necessary.\n if ( invoiceAddress.checkout\n && invoiceAddress.checkout.customerInvoiceAddress\n && invoiceAddress.checkout.customerInvoiceAddress.CustomerProperty )\n {\n var tmpProperties = invoiceAddress.checkout.customerInvoiceAddress.CustomerProperty;\n invoiceAddress.CustomerPropertiesList = invoiceAddress.CustomerPropertiesList || [];\n\n for ( var property in tmpProperties )\n {\n if ( tmpProperties[property] )\n {\n invoiceAddress.CustomerPropertiesList.push( {\n PropertyID : property,\n PropertyValue: tmpProperties[property]\n } );\n }\n }\n }\n\n if ( !addressesAreEqual( invoiceAddress, Checkout.getCheckout().CustomerInvoiceAddress ) )\n {\n return API.post( \"/rest/checkout/customerinvoiceaddress/\", invoiceAddress )\n .done( function( response )\n {\n saveShippingAddress().done( Checkout.loadCheckout );\n } );\n }\n else\n {\n return saveShippingAddress();\n }\n }\n\n /**\n * Check if values of addresses are equal\n * @function addressesAreEqual\n * @private\n * @param {object} address1\n * @param {object} address2\n * @returns {boolean}\n */\n function addressesAreEqual( address1, address2 )\n {\n for ( var key in address1 )\n {\n if ( address1[key] + '' !== address2[key] + '' && key !== 'EmailRepeat' )\n {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Set the shipping profile used for this order and update checkout. Selected shipping profile will be\n * read from <form> marked with data-plenty-checkout-form=\"shippingProfileSelect\"\n * @function setShippingProfile\n * @return {object} jQuery deferred\n * Object\n */\n function setShippingProfile()\n {\n\n var values = $( '[data-plenty-checkout-form=\"shippingProfileSelect\"]' ).getFormValues();\n\n Checkout.getCheckout().CheckoutShippingProfileID = values.ShippingProfileID;\n delete Checkout.getCheckout().CheckoutCustomerShippingAddressID;\n delete Checkout.getCheckout().CheckoutMethodOfPaymentID;\n\n return Checkout.setCheckout()\n .done( function()\n {\n Checkout.reloadContainer( 'MethodsOfPaymentList' );\n } );\n\n }\n\n /**\n * Prepare method of payment to check if external checkout is used or addition content should be displayed\n * @function preparePayment\n * @return {object} jQuery deferred\n * Object\n */\n function preparePayment()\n {\n var paymentID = Checkout.getCheckout().CheckoutMethodOfPaymentID;\n var paymentData = $( 'input[type=\"radio\"][name=\"MethodOfPaymentID\"][value=\"' + paymentID + '\"]' ).parent().getFormValues();\n return API.post( \"/rest/checkout/preparepayment/\", paymentData, true )\n .done( function( response )\n {\n if ( response.data.CheckoutMethodOfPaymentRedirectURL != '' )\n {\n\n document.location.assign( response.data.CheckoutMethodOfPaymentRedirectURL );\n\n }\n else if ( !!response.data.CheckoutMethodOfPaymentAdditionalContent )\n {\n\n var isBankDetails = $( response.data.CheckoutMethodOfPaymentAdditionalContent ).find( '[data-plenty-checkout-form=\"bankDetails\"]' ).length > 0;\n Modal.prepare()\n .setContent( response.data.CheckoutMethodOfPaymentAdditionalContent )\n .onConfirm( function()\n {\n if ( isBankDetails )\n {\n return saveBankDetails();\n }\n else\n {\n return saveCreditCard();\n }\n } )\n .show();\n }\n } )\n .fail( function( jqXHR )\n {\n try\n {\n var response = $.parseJSON( jqXHR.responseText );\n\n var errorStack = [];\n for ( var i = 0; i < response.error.error_stack.length; i++ )\n {\n if ( response.error.error_stack[i].code == 651 )\n {\n // notify atriga validation errors\n Checkout.reloadContainer( 'MethodsOfPaymentList' ).done( function()\n {\n $( document ).trigger( 'plenty.AtrigaValidationFailed' );\n } );\n }\n else\n {\n errorStack.push( response.error.error_stack[i] );\n }\n }\n\n // display remaining errors\n if ( errorStack.length > 0 )\n {\n UI.printErrors( errorStack );\n }\n }\n catch ( e )\n {\n UI.throwError( jqXHR.status, jqXHR.statusText );\n }\n } );\n\n }\n\n /**\n * Set the method of payment used for this order.\n * @function setMethodOfPayment\n * @param {number|undefined} paymentID ID of the method of payment to use. Read from <form> marked with\n * data-plenty-checkout-form=\"methodOfPayment\" if unset.\n * @return {object} jQuery deferred\n * Object\n */\n function setMethodOfPayment( paymentID )\n {\n /*\n var methodsOfPaymentList = Checkout.getCheckout().MethodsOfPaymentList;\n var methodOfPayment;\n for( var i = 0; i < methodsOfPaymentList.length; i++ )\n {\n if( methodsOfPaymentList[i].MethodOfPaymentID == paymentID )\n {\n methodOfPayment = methodsOfPaymentList[i];\n break;\n }\n }\n */\n\n if ( !paymentID )\n {\n // FIX for older callisto layouts (< 3.3): get payment id from input field\n paymentID = $( 'input[name=\"MethodOfPaymentID\"]:checked' ).val();\n }\n\n Checkout.getCheckout().CheckoutMethodOfPaymentID = paymentID;\n\n if ( !pm.getGlobal( 'Checkout.AtrigaRequireUserConfirmation' ) )\n {\n Checkout.getCheckout().CheckoutAtrigapaymaxChecked = true;\n }\n\n delete Checkout.getCheckout().CheckoutCustomerShippingAddressID;\n delete Checkout.getCheckout().CheckoutShippingProfileID;\n\n return Checkout.setCheckout()\n .done( function()\n {\n Checkout.reloadContainer( 'ShippingProfilesList' );\n } );\n }\n\n function confirmAtrigaPaymax( atrigaPaymaxChecked )\n {\n Checkout.getCheckout().CheckoutAtrigapaymaxChecked = !!atrigaPaymaxChecked;\n return API.put( '/rest/checkout', {\n CheckoutAtrigapaymaxChecked: !!atrigaPaymaxChecked\n } );\n //return Checkout.setCheckout();\n }\n\n /**\n * Display the popup to enter or edit customers bank details\n * @function editBankDetails\n */\n function editBankDetails()\n {\n\n CMS.getContainer( 'CheckoutPaymentInformationBankDetails' ).from( 'Checkout' )\n .done( function( response )\n {\n Modal.prepare()\n .setContent( response.data[0] )\n .onDismiss( function()\n {\n $( 'input[name=\"MethodOfPaymentID\"]' ).each( function( i, radio )\n {\n if ( $( radio ).val() == Checkout.getCheckout().CheckoutMethodOfPaymentID )\n {\n $( radio ).attr( 'checked', 'checked' );\n }\n else\n {\n $( radio ).removeAttr( 'checked' );\n }\n } );\n } ).onConfirm( function()\n {\n return saveBankDetails();\n } )\n .show();\n } );\n\n }\n\n /**\n * Read entered bank details from data-plenty-checkout-form=\"bankDetails\" and update checkout.\n * @function saveBankDetails\n * @private\n * @return {boolean} the result of form validation\n */\n function saveBankDetails()\n {\n var form = $( '[data-plenty-checkout-form=\"bankDetails\"]' );\n\n if ( form.validateForm() )\n {\n var values = form.getFormValues().checkout.customerBankDetails;\n\n var bankDetails = {\n CustomerBankName : values.bankName,\n CustomerBLZ : values.blz,\n CustomerAccountNumber: values.accountNo,\n CustomerAccountOwner : values.accountOwner,\n CustomerIBAN : values.iban,\n CustomerBIC : values.bic\n };\n\n API.post( \"/rest/checkout/paymentinformationbankdetails/\", bankDetails )\n .done( function()\n {\n Checkout.loadCheckout().done( function()\n {\n setMethodOfPayment( 3 );\n Checkout.reloadContainer( 'MethodsOfPaymentList' );\n } );\n } );\n return true;\n }\n else\n {\n return false;\n }\n }\n\n /**\n * Display a popup containing credit card form\n * @function editCreditCard\n */\n function editCreditCard()\n {\n\n CMS.getContainer( 'CheckoutPaymentInformationCreditCard' ).from( 'Checkout' )\n .done( function( response )\n {\n Modal.prepare()\n .setContent( response.data[0] )\n .onDismiss( function()\n {\n $( 'input[name=\"MethodOfPaymentID\"]' ).each( function( i, radio )\n {\n if ( $( radio ).val() == Checkout.getCheckout().CheckoutMethodOfPaymentID )\n {\n $( radio ).attr( 'checked', 'checked' );\n }\n else\n {\n $( radio ).removeAttr( 'checked' );\n }\n } );\n } ).onConfirm( function()\n {\n return saveCreditCard();\n } )\n .show();\n } );\n }\n\n /**\n * Read values from <form> marked with data-plenty-checkout-form=\"creditCard\" and update checkout.\n * @function saveCreditCard\n * @private\n * @return {boolean} the result of form validation\n */\n function saveCreditCard()\n {\n var form = $( '[data-plenty-checkout-form=\"creditCard\"]' );\n\n if ( form.validateForm() )\n {\n\n var values = form.getFormValues().checkout.paymentInformationCC;\n\n var creditCard = {\n Owner : values.owner,\n Cvv2 : values.cvv2,\n Number : values.number,\n Year : values.year,\n Month : values.month,\n Provider: values.provider\n };\n\n API.post( '/rest/checkout/paymentinformationcreditcard/', creditCard )\n .done( function()\n {\n Checkout.loadCheckout();\n } );\n return true;\n }\n else\n {\n return false;\n }\n }\n\n /**\n * Display a popup containing address suggestions\n * @param {string} type\n */\n function loadAddressSuggestion( type )\n {\n\n //check login type\n if ( Checkout.getCheckout().CustomerInvoiceAddress.LoginType == 2 )\n {\n var values = $( '[data-plenty-checkout-form=\"shippingAddress\"]' ).getFormValues();\n }\n else\n {\n var values = $( '[data-plenty-checkout-form=\"guestRegistration\"]' ).getFormValues();\n }\n\n var params = {\n street : values.Street,\n houseNo : values.HouseNo,\n ZIP : values.ZIP,\n city : values.City,\n postnummer : values.Postnummer,\n suggestionType: 'postfinder'\n };\n\n CMS.getContainer( 'CheckoutAddressSuggestionResultsList', params ).from( 'Checkout' )\n .done( function( response )\n {\n Modal.prepare()\n .setContent( response.data[0] )\n .show();\n } );\n }\n\n /**\n * Place the order prepared before and finish the checkout process.
    \n * Validate required checkboxes in data-plenty-checkout-form=\"placeOrder\"\n * @function placeOrder\n * @return {object} jQuery deferred\n * Object\n */\n function placeOrder()\n {\n var form = $( '[data-plenty-checkout-form=\"placeOrder\"]' );\n if ( form.validateForm() )\n {\n\n var values = form.getFormValues();\n\n // if not shown in layout set default 1 for mandatory fields\n var params = {\n TermsAndConditionsCheck : values.termsAndConditionsCheck || 0,\n WithdrawalCheck : values.withdrawalCheck || 0,\n PrivacyPolicyCheck : values.privacyPolicyCheck || 0,\n AgeRestrictionCheck : values.ageRestrictionCheck || 0,\n NewsletterCheck : values.newsletterCheck || 0,\n KlarnaTermsAndConditionsCheck: values.klarnaTermsAndConditionsCheck || 0,\n PayoneDirectDebitMandateCheck: values.payoneDirectDebitMandateCheck || 0,\n PayoneInvoiceCheck : values.payoneInvoiceCheck || 0\n };\n\n return API.post( \"/rest/checkout/placeorder/\", params )\n .done( function( response )\n {\n if ( response.data.MethodOfPaymentRedirectURL != '' )\n {\n\n window.location.assign( response.data.MethodOfPaymentRedirectURL );\n\n }\n else if ( response.data.MethodOfPaymentAdditionalContent != '' )\n {\n\n Modal.prepare()\n .setContent( response.data.MethodOfPaymentAdditionalContent )\n .setLabelDismiss( '' )\n .onDismiss( function()\n {\n window.location.assign( form.attr( 'action' ) );\n } ).onConfirm( function()\n {\n window.location.assign( form.attr( 'action' ) );\n } ).show();\n\n }\n else\n {\n\n window.location.assign( form.attr( 'action' ) );\n\n }\n } );\n }\n }\n\n }, ['APIFactory', 'UIFactory', 'CMSFactory', 'CheckoutFactory', 'ModalFactory'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n pm.service( 'FeedbackService', function( API )\n {\n\n return {\n getFeedbacks : getFeedbacks,\n addFeedback : addFeedback,\n ArticleTypes : articleTypes(),\n FeedbackTypes: feedbackTypes()\n };\n\n /*\n FeedbackService\n .getFeedbacks().between('2014-12-03', '2015-07-01')\n .for( FeedbackService.ArticleTypes.ITEM, 2732, FeedbackService.FeedbackTypes.COMMENTS_ONLY );\n */\n function getFeedbacks()\n {\n var feedbackInterval = {\n dateStart: null,\n dateEnd : null\n };\n\n return {\n between: setFeedbackInterval,\n for : listFeedbacks\n };\n\n function setFeedbackInterval( start, end )\n {\n feedbackInterval.dateStart = start;\n feedbackInterval.dateEnd = end;\n return this;\n }\n\n function listFeedbacks( articleType, referenceId, feedbackType )\n {\n\n var params = {\n ReferenceId : referenceId,\n FromDate : feedbackInterval.dateStart,\n ToDate : feedbackInterval.dateEnd,\n FeedbackType: feedbackType || feedbackTypes().COMMENTS_AND_RATINGS\n };\n return API.get( '/rest/feedback/' + articleType + '/', params );\n\n }\n }\n\n /*\n FeedbackService\n .addFeedback()\n .withRating( 5 )\n .withComment( 'Hallo' )\n .withAuthor( 'Felix', 'felix.dausch@plentymarkets.com', 123456 )\n .to( FeedbackService.ArticleTypes.ITEM, 2732 );\n */\n function addFeedback()\n {\n\n var params = {\n Rating : 1.0,\n Text : '',\n Author : '',\n Email : '',\n CustomerId: 0\n };\n\n return {\n withRating : withRating,\n withComment: withComment,\n withAuthor : withAuthor,\n to : sendFeedback\n };\n\n function withRating( rating )\n {\n params.Rating = rating;\n return this;\n }\n\n function withComment( comment )\n {\n params.Text = comment;\n return this;\n }\n\n function withAuthor( author, mail, customerID )\n {\n params.Author = author;\n if ( !!mail )\n {\n params.Email = mail;\n }\n if ( !!customerID )\n {\n params.CustomerId = customerID;\n }\n return this;\n }\n\n function sendFeedback( articleType, referenceId )\n {\n return API.post( '/rest/feedback/' + articleType + '/', params );\n\n }\n\n }\n\n function feedbackTypes()\n {\n return {\n COMMENTS_ONLY : 'comments_only',\n RATINGS_ONLY : 'ratings_only',\n COMMENTS_AND_RATINGS: 'comments_with_ratings'\n }\n }\n\n function articleTypes()\n {\n return {\n ITEM : 'item',\n CATEGORY: 'category',\n BLOG : 'blog'\n }\n }\n\n }, ['APIFactory'] );\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Listens to window's size and trigger 'sizeChange' event if the Bootstrap interval changes.\n * @class MediaSizeService\n * @static\n * @example\n * $(window).on('sizeChange', function(newValue, oldValue) {\n * console.log('The interval changed from ' + oldValue + ' to ' + newValue.');\n * });\n */\n pm.service( 'MediaSizeService', function()\n {\n\n var bsInterval;\n\n // recalculation of the current interval on window resize\n $( window ).resize( calculateMediaSize );\n\n // initially calculation of the interval\n $( document ).ready( calculateMediaSize );\n\n return {\n interval : getInterval,\n isInterval: isInterval\n };\n\n /**\n * Get the currently used Bootstrap interval\n * @function getInterval\n * @return {\"xs\"|\"sm\"|\"md\"|\"lg\"}\n */\n function getInterval()\n {\n if ( !!bsInterval )\n {\n calculateMediaSize();\n }\n\n return bsInterval;\n }\n\n /**\n * Calculate the currently used Bootstrap interval\n * @function calculateMediaSize\n * @private\n */\n function calculateMediaSize()\n {\n var size;\n if ( !!window.matchMedia )\n { // FIX IE support\n if ( window.matchMedia( '(min-width:1200px)' ).matches )\n {\n size = 'lg';\n }\n else if ( window.matchMedia( '(min-width:992px)' ).matches )\n {\n size = 'md';\n }\n else if ( window.matchMedia( '(min-width:768px)' ).matches )\n {\n size = 'sm';\n }\n else\n {\n size = 'xs';\n }\n }\n else\n {\n if ( $( window ).width() >= 1200 )\n {\n size = 'lg';\n }\n else if ( $( window ).width() >= 992 )\n {\n size = 'md';\n }\n else if ( $( window ).width() >= 768 )\n {\n size = 'sm';\n }\n else\n {\n size = 'xs';\n }\n }\n if ( size != bsInterval || size === 'xs' )\n {\n var oldValue = bsInterval;\n bsInterval = size;\n $( window ).trigger( 'sizeChange', [bsInterval, oldValue] );\n }\n }\n\n function isInterval( interval )\n {\n var intervalList = interval.replace( /\\s/g, '' ).split( ',' );\n for ( var i = 0; i < intervalList.length; i++ )\n {\n if ( intervalList[i] == bsInterval )\n {\n return true;\n }\n }\n return false;\n }\n\n } );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Handling navigation while checkout processes\n * @class NavigatorService\n * @static\n *\n */\n pm.service( 'NavigatorService', function( CMS, Checkout )\n {\n var navigation = [];\t\t// contains navigation list elements\n var container = [];\t\t// content containers\n var current = -1;\t\t// index of currently shown content container\n var buttonPrev = {};\t\t// navigation buttons\n var buttonNext = {};\n var interceptors = {\n beforeChange: [],\n afterChange : []\n };\n var checkoutStates = [];\n\n return {\n init : init,\n getCurrentContainer: getCurrentContainer,\n goTo : goTo,\n beforeChange : beforeChange,\n afterChange : afterChange,\n continueChange : continueChange,\n next : next,\n previous : previous,\n goToID : goToID,\n fillNavigation : fillNavigation\n };\n\n /**\n * Initialize checkout navigation. Shows first container.\n * @function init\n * @example\n * ```html\n * \n *
      \n *
    • Checkout Step 1
    • \n *
    • Checkout Step 2
    • \n *
    • ...
    • \n *
    \n * \n *\n *
    \n *
    \n * Checkout Step 1 Content\n *
    \n *
    \n * Checkout Step 2 Content\n *
    \n *
    ...
    \n *
    \n * ```\n */\n function init()\n {\n\n // get elements from DOM\n navigation = $( '[data-plenty-checkout=\"navigation\"] > li' );\n container = $( '[data-plenty-checkout=\"container\"] > div' );\n buttonNext = $( '[data-plenty-checkout=\"next\"]' );\n buttonPrev = $( '[data-plenty-checkout=\"prev\"]' );\n\n if ( navigation.length == container.length && container.length > 0 )\n {\n var checkout = Checkout.getCheckout();\n\n container.hide();\n\n // initialize navigation\n navigation.each( function( i, elem )\n {\n $( elem ).addClass( 'disabled' );\n // handle navigation click events\n $( elem ).click( function()\n {\n if ( !$( this ).is( '.disabled' ) )\n {\n goTo( i );\n }\n } );\n } );\n\n buttonNext.attr( \"disabled\", \"disabled\" );\n buttonNext.click( function()\n {\n next();\n } );\n\n buttonPrev.attr( \"disabled\", \"disabled\" );\n buttonPrev.click( function()\n {\n previous();\n } );\n\n window.addEventListener( 'hashchange', function()\n {\n if ( window.location.hash.length > 0 )\n {\n goToID( window.location.hash );\n }\n else\n {\n goTo( 0 );\n }\n }, false );\n\n // initialize GUI\n // check url param for jumping to tab\n $.urlParam = function( name )\n {\n var results = new RegExp( '[\\?&]' + name + '=([^&#]*)' ).exec( window.location.href );\n if ( results == null )\n {\n return null;\n }\n else\n {\n return results[1] || 0;\n }\n };\n\n var param = $.urlParam( 'gototab' );\n // jump to hash from url param 'gototab'\n if ( window.location.hash.length == 0 && !!param && $( '[data-plenty-checkout-id=\"' + param + '\"]' ).length > 0 )\n {\n window.location.hash = param;\n }\n // jump to hash\n else if ( !goToID( window.location.hash ) && current >= 0 )\n {\n goTo( current );\n }\n else\n {\n goTo( 0 );\n }\n\n fillNavigation();\n $( window ).on( 'sizeChange', fillNavigation );\n $( window ).resize( function()\n {\n if ( pm.getInstance().MediaSizeService.interval() == 'xs' )\n {\n fillNavigation();\n }\n } );\n\n }\n }\n\n /**\n * Get the currently active checkout container.\n * @function getCurrentContainer\n * @return {{id: string, index: number}}\n */\n function getCurrentContainer()\n {\n if ( current >= 0 )\n {\n return {\n id : $( container[current] ).attr( 'data-plenty-checkout-id' ),\n index: current\n };\n }\n else\n {\n return null;\n }\n }\n\n /**\n * Register an interceptor called before each tab change.\n * Tabchange will break if any interceptor returns false.\n * @param {function} interceptor The interceptor callback to register\n * @chainable\n * @returns {NavigatorService}\n * @example\n * plenty.NavigatorService.beforeChange( function(targetContainer) {\n * if( targetContainer.id === 'details' ) {\n * // stop tabchange if user tries to access checkout container with id \"details\"\n * return false;\n * }\n * return true;\n * });\n */\n function beforeChange( interceptor )\n {\n interceptors.beforeChange.push( interceptor );\n return pm.getInstance().NavigatorService;\n }\n\n /**\n * Register an interceptor called after each tab change.\n * @param {function} interceptor The interceptor callback to register\n * @chainable\n * @returns {NavigatorService}\n */\n function afterChange( interceptor )\n {\n interceptors.afterChange.push( interceptor );\n return pm.getInstance().NavigatorService;\n }\n\n /**\n * Call registered interceptors. Break if any interceptor returns false.\n * Do not call beforeChange-interceptors on initially tabchange\n * @function resolveInterceptors\n * @private\n * @param {\"beforeChange\"|\"afterChange\"} identifier Describe which interceptors should be called\n * @param {number} index the index of the target container\n * @returns {boolean} Conjunction of all interceptor return values\n */\n function resolveInterceptors( identifier, index )\n {\n var continueTabChange = true;\n\n if ( current >= 0 || identifier === 'afterChange' )\n {\n\n var currentContainer = getCurrentContainer();\n var targetContainer = {\n index: index,\n id : $( container[index] ).attr( 'data-plenty-checkout-id' )\n };\n\n $.each( interceptors[identifier], function( i, interceptor )\n {\n if ( interceptor( currentContainer, targetContainer ) === false )\n {\n continueTabChange = false;\n return false;\n }\n } );\n }\n\n return continueTabChange;\n }\n\n /**\n * Show checkout tab given by index\n * @function goTo\n * @param {number} index Index of target tab, starting at 0\n * @param {boolean} [ignoreInterceptors=false] Set true to not call registered interceptors and force changing\n * tab\n */\n function goTo( index, ignoreInterceptors )\n {\n\n var contentChanged = current !== index;\n\n if ( contentChanged && !ignoreInterceptors )\n {\n if ( !resolveInterceptors( \"beforeChange\", index ) )\n {\n return;\n }\n }\n\n current = index;\n\n if ( !Object.equals( checkoutStates[current], Checkout.getCheckout( true ) ) && contentChanged && !!$( container[current] ).attr( 'data-plenty-checkout-content' ) )\n {\n checkoutStates[current] = Checkout.getCheckout( true );\n // reload tab content\n CMS.getCategoryContent( $( container[current] ).attr( 'data-plenty-checkout-content' ) )\n .done( function( response )\n {\n $( container[current] ).html( response.data[0] );\n // continue tab change\n proceedTabChange( contentChanged );\n pm.getInstance().bindDirectives( container[current] );\n $( window ).trigger( 'contentChanged' );\n } );\n }\n else\n {\n // continue tab change without reloading tab content\n proceedTabChange( contentChanged );\n //pm.getInstance().bindDirectives();\n }\n\n }\n\n function proceedTabChange( contentChanged )\n {\n\n // hide content containers\n $( container ).hide();\n\n // refresh navigation elements\n var $elem;\n $( navigation ).each( function( i, elem )\n {\n $elem = $( elem );\n $elem.removeClass( 'disabled active' );\n\n $elem.find( '[role=\"tab\"]' ).attr( 'aria-selected', 'false' );\n\n if ( i < current )\n {\n // set current element as active\n $elem.addClass( 'visited' );\n }\n else\n {\n if ( i == current )\n {\n $elem.addClass( 'active visited' );\n $elem.find( '[role=\"tab\"]' ).attr( 'aria-selected', 'true' );\n }\n else\n {\n if ( i > current && !$elem.is( '.visited' ) )\n {\n // disable elements behind active\n $elem.addClass( 'disabled' );\n }\n }\n }\n } );\n fillNavigation();\n\n // hide \"previous\"-button if first content container is shown\n if ( current <= 0 )\n {\n buttonPrev.attr( \"disabled\", \"disabled\" );\n }\n else\n {\n buttonPrev.removeAttr( \"disabled\" );\n }\n\n // hide \"next\"-button if last content container is shown\n if ( current + 1 == navigation.length )\n {\n buttonNext.attr( \"disabled\", \"disabled\" );\n }\n else\n {\n buttonNext.removeAttr( \"disabled\" );\n }\n\n // show current content container\n $( container[current] ).show();\n\n // set location hash\n if ( current > 0 )\n {\n window.location.hash = $( container[current] ).attr( 'data-plenty-checkout-id' );\n }\n else\n {\n if ( window.location.hash.length > 0 )\n {\n window.location.hash = '';\n }\n }\n\n if ( contentChanged )\n {\n resolveInterceptors( \"afterChange\", current );\n }\n }\n\n /**\n * Continue interrupted tabchange. Shorthand for: goTo(targetContainer.index, true)\n * @function continueChange\n * @param targetContainer The tab-object received from an interceptor\n */\n function continueChange( targetContainer )\n {\n goTo( targetContainer.index, true );\n }\n\n /**\n * Show next checkout tab if available. Shorthand for\n * \n * if (current < navigation.length - 1) {\n * goTo(current + 1);\n * }\n * \n * @function next\n */\n function next()\n {\n if ( current < navigation.length - 1 )\n {\n goTo( current + 1 );\n }\n }\n\n /**\n * Show previous checkout tab if available\n * @function next\n */\n function previous()\n {\n if ( current > 0 )\n {\n goTo( current - 1 );\n }\n }\n\n /**\n * Show checkout tab given by ID\n * @function goToID\n * @param {string} containerID ID of tab to show. Target tab must be marked with\n * data-plenty-checkout-id=\"#...\"\n */\n function goToID( containerID )\n {\n if ( containerID == 'next' )\n {\n next();\n return true;\n }\n else if ( containerID == 'prev' )\n {\n previous();\n return true;\n }\n else\n {\n containerID = containerID.replace( '#', '' );\n $( container ).each( function( i, elem )\n {\n if ( $( elem ).attr( 'data-plenty-checkout-id' ) == containerID )\n {\n goTo( i );\n return true;\n }\n } );\n }\n\n return false;\n }\n\n /**\n * Calculate navigation's width to match its parent element\n * by increasing its items padding.\n * @function fillNavigation\n */\n function fillNavigation()\n {\n // break if manager has not been initialized\n var navigationCount = navigation.length;\n if ( navigationCount <= 0 )\n {\n return;\n }\n\n // reset inline styles\n $( navigation ).removeAttr( 'style' );\n $( navigation ).children( 'span' ).removeAttr( 'style' );\n $( buttonNext ).removeAttr( 'style' );\n $( buttonPrev ).removeAttr( 'style' );\n\n var buttonWidth = ($( buttonPrev ).outerWidth() < $( buttonNext ).outerWidth()) ? $( buttonNext ).outerWidth( true ) + 1 : $( buttonPrev ).outerWidth( true ) + 1;\n $( buttonNext ).css( {width: buttonWidth + 'px'} );\n $( buttonPrev ).css( {width: buttonWidth + 'px'} );\n\n // calculate width to fill\n var width = $( navigation ).parent().parent().outerWidth( true ) - ( 2 * buttonWidth);\n width -= parseInt( $( navigation ).parent().css( 'marginLeft' ) ) + parseInt( $( navigation ).parent().css( 'marginRight' ) );\n\n var padding = width;\n var tabWidth = [];\n\n $( navigation ).each( function( i, elem )\n {\n padding -= parseInt( $( elem ).css( 'marginLeft' ) );\n padding -= parseInt( $( elem ).css( 'marginRight' ) );\n\n tabWidth[i] = $( elem ).children( 'span' ).width();\n padding -= tabWidth[i];\n\n padding -= parseInt( $( elem ).children( 'span' ).css( 'marginLeft' ) );\n padding -= parseInt( $( elem ).children( 'span' ).css( 'marginRight' ) );\n } );\n\n var paddingEachItem = parseInt( padding / navigationCount );\n\n var paddingLeft, paddingRight;\n if ( paddingEachItem % 2 == 1 )\n {\n paddingLeft = ( paddingEachItem / 2 ) + 0.5;\n paddingRight = ( paddingEachItem / 2 ) - 0.5;\n }\n else\n {\n paddingLeft = paddingEachItem / 2;\n paddingRight = paddingEachItem / 2;\n }\n\n var paddingLastItem = parseInt( padding - ( ( navigationCount - 1 ) * ( paddingLeft + paddingRight ) ) );\n var paddingLastLeft, paddingLastRight;\n if ( paddingLastItem % 2 == 1 )\n {\n paddingLastLeft = ( paddingLastItem / 2 ) + 0.5;\n paddingLastRight = ( paddingLastItem / 2) - 0.5;\n }\n else\n {\n paddingLastLeft = paddingLastItem / 2;\n paddingLastRight = paddingLastItem / 2;\n }\n\n var diff = width;\n $( navigation ).each( function( i, elem )\n {\n if ( i < navigationCount - 1 )\n {\n $( elem ).children( 'span' ).css( {'paddingLeft': paddingLeft + 'px', 'paddingRight': paddingRight + 'px'} ); //.parent().css({ width: ( tabWidth[i] + paddingLeft + paddingRight + parseInt( $(elem).children('span').css('marginLeft') ) + parseInt( $(elem).children('span').css('marginRight') ) )+'px' });\n }\n else\n {\n $( elem ).children( 'span' ).css( {'paddingLeft': paddingLastLeft + 'px', 'paddingRight': paddingLastRight + 'px'} ); //.parent().css({ width: ( tabWidth[i] + paddingLastLeft + paddingLastRight + parseInt( $(elem).children('span').css('marginLeft') ) + parseInt( $(elem).children('span').css('marginRight') ) )+'px' });\n }\n } );\n\n //$(navigation).parent().css('marginRight', 0);\n }\n\n }, ['CMSFactory', 'CheckoutFactory'] );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Magnus Martin \n * =====================================================================================\n */\n\n\n(function( $, pm )\n{\n pm.service( 'PostfinderService', function( API, Modal, UIFactory )\n {\n var packstationID = '';\n var shippingFields = {};\n var numberOfResults = {};\n var result = {};\n\n return {\n openPostfinderModal: openPostfinderModal,\n isPackstation : isPackstation\n };\n\n function isPackstation()\n {\n var street = $( 'input[name=\"Street\"]' ).val();\n return ( street.toUpperCase() == \"PACKSTATION\" || street.toUpperCase() == \"POSTFILIALE\" );\n }\n\n function openPostfinderModal()\n {\n shippingFields = {\n PostfinderItemStreet : $( 'input[name=\"Street\"]', '[data-plenty-checkout-form=\"shippingAddress\"]' ),\n PostfinderItemZIP : $( 'input[name=\"ZIP\"]', '[data-plenty-checkout-form=\"shippingAddress\"]' ),\n PostfinderItemCity : $( 'input[name=\"City\"]', '[data-plenty-checkout-form=\"shippingAddress\"]' ),\n PostfinderItemHouseNo: $( 'input[name=\"HouseNo\"]', '[data-plenty-checkout-form=\"shippingAddress\"]' )\n\n };\n\n shippingFields.PostfinderItemStreet.val( '' );\n\n if ( (shippingFields.PostfinderItemZIP.val().length > 2 || shippingFields.PostfinderItemCity.val().length > 2) )\n {\n\n API.get( '/rest/checkout/shippingaddresspostfinderlist/',\n {\n suggestionType: \"postfinder\",\n zip : shippingFields.PostfinderItemZIP.val(),\n city : shippingFields.PostfinderItemCity.val()\n } )\n\n .done( function( response )\n {\n result = response.data;\n numberOfResults = result.length;\n\n if ( numberOfResults == 0 )\n {\n showErrorMessage();\n }\n\n var params = {\n addresses: []\n };\n\n for ( var i = 0; i < numberOfResults; i++ )\n {\n var dimension = 'km';\n var distInMeters = result[i].PostfinderItemDistance;\n var distInKilometers = distInMeters / 1000;\n distInKilometers = ((Math.round( distInKilometers * 100 ) / 100).toFixed( 2 )).replace( '.', ',' );\n\n if ( distInMeters < 1000 )\n {\n distInKilometers = distInMeters;\n dimension = 'm';\n }\n\n params.addresses.push( {\n index : i,\n dimension: dimension,\n type : result[i].PostfinderItemIsPackstation ? 'Packstation' : 'Postfiliale',\n number : result[i].PostfinderItemIsPackstation ? result[i].PostfinderItemPackstationNo : result[i].PostfinderItemPostfilialNo,\n street : result[i].PostfinderItemStreet,\n houseNo : result[i].PostfinderItemHouseNo,\n zip : result[i].PostfinderItemZIP,\n city : result[i].PostfinderItemCity,\n district : result[i].PostfinderItemDistrict,\n distance : distInKilometers,\n remark : result[i].PostfinderItemRemark\n } );\n }\n\n var html = pm.compileTemplate( 'addressSuggestions/postFinder.html', params );\n\n Modal.prepare()\n .setTitle( pm.translate( 'Packstations and post offices in your area' ) )\n .setContent( html )\n .setClass( 'checkout' )\n .onConfirm( function()\n {\n shippingFields.PostfinderItemCity.removeClass( 'has-error' ).addClass( 'has-success' );\n $( 'label[for=\"' + shippingFields.PostfinderItemCity.attr( 'id' ) + '\"]' ).removeClass( 'has-error' ).addClass( 'has-success' );\n\n shippingFields.PostfinderItemZIP.removeClass( 'has-error' ).addClass( 'has-success' );\n $( 'label[for=\"' + shippingFields.PostfinderItemZIP.attr( 'id' ) + '\"]' ).removeClass( 'has-error' ).addClass( 'has-success' );\n\n shippingFields.PostfinderItemStreet.removeClass( 'has-error' ).addClass( 'has-success' );\n $( 'label[for=\"' + shippingFields.PostfinderItemStreet.attr( 'id' ) + '\"]' ).removeClass( 'has-error' ).addClass( 'has-success' );\n\n shippingFields.PostfinderItemHouseNo.removeClass( 'has-error' ).addClass( 'has-success' );\n $( 'label[for=\"' + shippingFields.PostfinderItemHouseNo.attr( 'id' ) + '\"]' ).removeClass( 'has-error' ).addClass( 'has-success' );\n\n packstationID = $( 'input[type=\"radio\"][name=\"postfinder\"]:checked' ).val();\n\n if ( result[packstationID].PostfinderItemIsPackstation )\n {\n $( shippingFields.PostfinderItemStreet ).val( 'PACKSTATION' );\n $( shippingFields.PostfinderItemHouseNo ).val( result[packstationID].PostfinderItemPackstationNo );\n }\n else\n {\n $( shippingFields.PostfinderItemStreet ).val( 'POSTFILIALE' );\n $( shippingFields.PostfinderItemHouseNo ).val( result[packstationID].PostfinderItemPostfilialNo );\n }\n $( shippingFields.PostfinderItemStreet ).trigger( 'change' );\n\n $( shippingFields.PostfinderItemCity ).val( result[packstationID].PostfinderItemCity );\n $( shippingFields.PostfinderItemZIP ).val( result[packstationID].PostfinderItemZIP );\n return true;\n } )\n .show()\n } );\n }\n else\n {\n showErrorMessage();\n }\n\n }\n\n function showErrorMessage()\n {\n UIFactory.throwError( 0, pm.translate( 'Please enter a ZIP code and/or a city.' ) );\n\n shippingFields.PostfinderItemCity.removeClass( 'has-success' ).addClass( 'has-error' );\n $( 'label[for=\"' + shippingFields.PostfinderItemCity.attr( 'id' ) + '\"]' ).removeClass( 'has-success' ).addClass( 'has-error' );\n\n shippingFields.PostfinderItemZIP.removeClass( 'has-success' ).addClass( 'has-error' );\n $( 'label[for=\"' + shippingFields.PostfinderItemZIP.attr( 'id' ) + '\"]' ).removeClass( 'has-success' ).addClass( 'has-error' );\n\n shippingFields.PostfinderItemCity.focus( function()\n {\n $( this ).removeClass( 'has-error' );\n var inputId = $( this ).attr( 'id' );\n $( this ).closest( '.form-group' ).find( '[for=\"' + inputId + '\"]' ).removeClass( 'has-error' );\n } );\n\n shippingFields.PostfinderItemZIP.focus( function()\n {\n $( this ).removeClass( 'has-error' );\n var inputId = $( this ).attr( 'id' );\n $( this ).closest( '.form-group' ).find( '[for=\"' + inputId + '\"]' ).removeClass( 'has-error' );\n } );\n }\n }, ['APIFactory', 'ModalFactory', 'UIFactory'] );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Provide templates for social share providers to inject them dynamically.\n * @class SocialShareService\n * @static\n */\n pm.service( 'SocialShareService', function()\n {\n\n //TODO: move to global variables\n if ( typeof(socialLangLocale) == 'undefined' )\n {\n socialLangLocale = 'en_US';\n }\n if ( typeof(socialLang) == 'undefined' )\n {\n socialLang = 'en';\n }\n\n return {\n getSocialService: getService\n };\n\n /**\n * Get the template for social media provider\n * @function getService\n * @param {string} identifier name of the social media provider to get the template for\n * @returns {string} the template to inject in DOM\n */\n function getService( identifier )\n {\n var services = {\n 'facebook-like': '',\n\n 'facebook-recommend': '',\n\n 'twitter': '',\n\n 'google-plus': '
    '\n + '',\n };\n\n return services[identifier];\n }\n\n /**\n * get the canonical URL if defined\n * @function getURL\n * @private\n * @return {string} The Canonical URL if defined or the current URI\n */\n function getURI()\n {\n var uri = document.location.href;\n var canonical = $( \"link[rel=canonical]\" ).attr( \"href\" );\n\n if ( canonical && canonical.length > 0 )\n {\n if ( canonical.indexOf( \"http\" ) < 0 )\n {\n canonical = document.location.protocol + \"//\" + document.location.host + canonical;\n }\n uri = canonical;\n }\n\n return uri;\n }\n\n /**\n * returns content of <meta name=\"\" content=\"\"> tags or '' if empty/non existant\n * @function getMeta\n * @private\n * @param {string} name The meta name to get the value of;\n */\n function getMeta( name )\n {\n var metaContent = $( 'meta[name=\"' + name + '\"]' ).attr( 'content' );\n return metaContent || '';\n }\n\n /**\n * create tweet text from content of <meta name=\"DC.title\"> and <meta name=\"DC.creator\">\n * fallback to content of <title> tag\n * @function getTweetText\n * @private\n */\n function getTweetText()\n {\n var title = getMeta( 'DC.title' );\n var creator = getMeta( 'DC.creator' );\n\n if ( title.length > 0 && creator.length > 0 )\n {\n title += ' - ' + creator;\n }\n else\n {\n title = $( 'title' ).text();\n }\n\n return encodeURIComponent( title );\n }\n\n } );\n\n}( jQuery, PlentyFramework ));\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\n/**\n * @module Services\n */\n(function( $, pm )\n{\n\n /**\n * Provide methods for client-side form validation.\n * @class ValidationService\n * @static\n */\n pm.service( 'ValidationService', function()\n {\n\n return {\n validate: validate\n };\n\n /**\n * Check if element is a form element (input, select, textarea) or search for child form elements\n * @function getFormControl\n * @private\n * @param {object} element the element to get the form element from\n * @return {object} a valid form element (input, select, textarea)\n */\n function getFormControl( element )\n {\n element = $( element );\n if ( element.is( 'input' ) || element.is( 'select' ) || element.is( 'textarea' ) )\n {\n return element;\n }\n else\n {\n if ( element.find( 'input' ).length > 0 )\n {\n return element.find( 'input' );\n }\n\n else if ( element.find( 'select' ).length > 0 )\n {\n return element.find( 'select' );\n }\n\n else if ( element.find( 'textarea' ).length > 0 )\n {\n return element.find( 'textarea' );\n }\n\n else\n {\n return null;\n }\n }\n\n }\n\n /**\n * Check given element has any value\n * @function validateText\n * @private\n * @param {object} formControl the form element to validate\n * @return {boolean}\n */\n function validateText( formControl )\n {\n // check if formControl is no checkbox or radio\n if ( formControl.is( 'input' ) || formControl.is( 'select' ) || formControl.is( 'textarea' ) )\n {\n // check if length of trimmed value is greater then zero\n return $.trim( formControl.val() ).length > 0;\n\n }\n else\n {\n console.error( 'Validation Error: Cannot validate Text for <' + formControl.prop( \"tagName\" ) + '>' );\n return false;\n }\n }\n\n /**\n * Check given element's value is a valid email-address\n * @function validateMail\n * @private\n * @param {object} formControl the form element to validate\n * @return {boolean}\n */\n function validateMail( formControl )\n {\n var mailRegExp = /[a-zA-Z0-9!#$%&'*+\\/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?/;\n if ( validateText( formControl ) )\n {\n return mailRegExp.test( $.trim( formControl.val() ) );\n }\n else\n {\n return false;\n }\n }\n\n /**\n * Check given element's value is a valid number\n * @function validateNumber\n * @private\n * @param {object} formControl the form element to validate\n * @return {boolean}\n */\n function validateNumber( formControl )\n {\n if ( validateText( formControl ) )\n {\n return $.isNumeric( $.trim( formControl.val() ) );\n }\n else\n {\n return false;\n }\n }\n\n /**\n * Check given element's value is equal to a references value\n * @function compareValues\n * @private\n * @param {object} formControl the form element to validate\n * @param {string} reference the required value\n * @param {boolean} caseSensitive direct compare, without convert to lowerCase\n * @return {boolean}\n */\n function compareValues( formControl, reference, caseSensitive )\n {\n formControl = $.trim( formControl.val() );\n reference = $.trim(\n $( reference ).length > 0\n ? $( reference ).val()\n : reference );\n\n if ( caseSensitive )\n {\n return formControl == reference;\n }\n return formControl.toLowerCase() == reference.toLowerCase();\n }\n\n function isNotVisibleOrEnabled( formControl )\n {\n return (!formControl.is( ':visible' ) || !formControl.is( ':enabled' ));\n }\n\n /**\n * Validate a form. Triggers event 'validationFailed' if any element has an invalid value\n * @function validate\n * @param {object} form The form element to validate\n * @returns {boolean}\n * @example\n * ```html\n * \n *
    \n * \n * \n *\n * \n * \n *\n * \n * \n *\n * \n * \n *\n * \n * \n * \n *\n * \n * \n * \n * \n *\n * \n * \n * \n * \n *\n * \n *
    \n * \n * \n *
    \n *\n *
    \n * ```\n *\n * @example\n * $(form).on('validationFailed', function(missingFields) {\n * // handle missing fields\n * });\n */\n function validate( form, errorClass )\n {\n var $formControl, formControls, validationKey, currentHasError, group, checked, checkedMin, checkedMax, attrValidate, validationKeys, formControlAttrType;\n var $form = $( form );\n errorClass = errorClass || 'has-error';\n var missingFields = [];\n var hasError = false;\n\n // check every required input inside form\n $form.find( '[data-plenty-validate], :required' ).each( function( i, elem )\n {\n attrValidate = $( elem ).attr( 'data-plenty-validate' );\n formControls = getFormControl( elem );\n // validate text inputs\n validationKeys = !!attrValidate ? attrValidate : 'text';\n validationKeys = validationKeys.split( ',' );\n\n for ( var i = 0, length = formControls.length; i < length; i++ )\n {\n $formControl = $( formControls[i] );\n formControlAttrType = $formControl.attr( 'type' );\n\n // skip validation, if input is invisible or disabled\n if ( isNotVisibleOrEnabled( $formControl ) )\n {\n return;\n }\n\n validationKey = validationKeys[i].trim() || validationKeys[0].trim();\n currentHasError = false;\n\n // formControl is textfield (text, mail, password) or textarea\n if ( ($formControl.is( 'input' )\n && formControlAttrType != 'radio'\n && formControlAttrType != 'checkbox')\n || $formControl.is( 'textarea' ) )\n {\n switch ( validationKey )\n {\n\n case 'text':\n currentHasError = !validateText( $formControl );\n break;\n\n case 'mail':\n currentHasError = !validateMail( $formControl );\n break;\n\n case 'number':\n currentHasError = !validateNumber( $formControl );\n break;\n\n case 'value':\n currentHasError = !compareValues( $formControl, $( elem ).attr( 'data-plenty-validation-value' ), ($formControl.context.type === \"password\") );\n break;\n\n case 'none':\n // do not validate\n break;\n\n default:\n console.error( 'Form validation error: unknown validate property: \"' + attrValidate + '\"' );\n break;\n }\n }\n else if ( $formControl.is( 'input' )\n && (formControlAttrType == 'radio'\n || formControlAttrType == 'checkbox') )\n {\n // validate radio buttons\n group = $formControl.attr( 'name' );\n checked = $form.find( 'input[name=\"' + group + '\"]:checked' ).length;\n\n if ( formControlAttrType == 'radio' )\n {\n checkedMin = 1;\n checkedMax = 1;\n }\n else\n {\n var minMax = (new Function( \"return \" + attrValidate ))() || {min: 1, max: 1};\n checkedMin = minMax.min;\n checkedMax = minMax.max;\n }\n\n currentHasError = ( checked < checkedMin || checked > checkedMax );\n\n }\n else if ( $formControl.is( 'select' ) )\n {\n // validate selects\n currentHasError = ( $formControl.val() == '' || $formControl.val() == '-1' );\n }\n else\n {\n console.error( 'Form validation error: ' + $( elem ).prop( \"tagName\" ) + ' does not contain an form element' );\n return;\n }\n\n if ( currentHasError )\n {\n hasError = true;\n missingFields.push( $formControl );\n\n if ( formControls.length > 1 )\n {\n $formControl.addClass( errorClass );\n $form.find( 'label[for=\"' + $formControl.attr( 'id' ) + '\"]' ).addClass( errorClass );\n }\n else\n {\n $( elem ).addClass( errorClass );\n }\n }\n }\n\n } );\n\n // scroll to element on 'validationFailed'\n $form.on( 'validationFailed', function()\n {\n var distanceTop = 50;\n var $error = $form.find( '.' + errorClass ).first();\n var errorOffset = $error.offset().top;\n var $scrollTarget = $( 'html, body' );\n\n // if form is inside of modal, scroll modal instead of body\n if ( $form.parents( '.modal' ).length > 0 )\n {\n $scrollTarget = $form.parents( '.modal' ).find( '.modal-body' );\n errorOffset = $scrollTarget.scrollTop() - ( $scrollTarget.offset().top - $error.offset().top );\n\n }\n else if ( $form.is( '.modal' ) )\n {\n $scrollTarget = $form.find( '.modal-body' );\n errorOffset = $scrollTarget.scrollTop() - ( $scrollTarget.offset().top - $error.offset().top );\n }\n\n // only scroll if error is outside of viewport\n if ( errorOffset - distanceTop < window.pageYOffset || errorOffset > (window.pageYOffset + window.innerHeight) )\n {\n $scrollTarget.animate( {\n scrollTop: errorOffset - distanceTop\n } );\n }\n } );\n\n if ( hasError )\n {\n // remove error class on focus\n $form.find( '.' + errorClass ).each( function( i, elem )\n {\n $formControl = $( getFormControl( elem ) );\n $formControl.on( 'focus click', function()\n {\n var $errorElement = $( elem );\n $errorElement.removeClass( errorClass );\n $form.find( 'label[for=\"' + $( this ).attr( 'id' ) + '\"]' ).removeClass( errorClass );\n } );\n } );\n\n $form.trigger( 'validationFailed', [missingFields] );\n }\n\n var callback = $form.attr( 'data-plenty-callback' );\n\n if ( !hasError && !!callback && callback != \"submit\" && typeof window[callback] == \"function\" )\n {\n\n var fields = {};\n $form.find( 'input, textarea, select' ).each( function()\n {\n if ( $( this ).attr( 'type' ) == 'checkbox' )\n {\n fields[$( this ).attr( 'name' )] = $( this ).is( ':checked' );\n }\n else\n {\n fields[$( this ).attr( 'name' )] = $( this ).val();\n }\n } );\n\n window[callback]( fields );\n return false;\n }\n else\n {\n return !hasError;\n }\n }\n } );\n\n /**\n * jQuery-Plugin to calling {{#crossLink \"ValidationService/validate\"}}ValidationService.validate{{/crossLink}}\n * on jQuery wrapped elements.\n * @return {boolean}\n */\n $.fn.validateForm = function()\n {\n return pm.getInstance().ValidationService.validate( this );\n };\n\n /**\n * jQuery-Plugin to get the values of contained form elements.\n * @return {object}\n */\n $.fn.getFormValues = function()\n {\n\n var form = this;\n var values = {};\n\n function inject( position, value )\n {\n var match = position.match( /^([^\\[]+)(.*)/ );\n\n if ( !!match[2] )\n {\n var exp = /\\[([^\\]]+)]/g;\n var child;\n var children = [];\n children[0] = match[1];\n while ( (child = exp.exec( match[2] )) !== null )\n {\n children.push( child[1] );\n }\n\n for ( var i = children.length - 1; i >= 0; i-- )\n {\n var val = {};\n val[children[i]] = value;\n value = val;\n }\n values = $.extend( true, values, value );\n }\n else\n {\n values[match[1]] = value;\n }\n }\n\n form.find( 'input, select, textarea' ).each( function( i, elem )\n {\n if ( !!$( elem ).attr( 'name' ) )\n {\n if ( $( elem ).attr( 'type' ) == \"checkbox\" )\n {\n // get checkbox group\n var groupValues = [];\n $( form ).find( '[name=\"' + $( elem ).attr( 'name' ) + '\"]:checked' ).each( function( j, checkbox )\n {\n groupValues.push( $( checkbox ).val() );\n } );\n inject( $( elem ).attr( 'name' ), groupValues );\n }\n else if ( $( elem ).attr( 'type' ) == 'radio' )\n {\n if ( $( elem ).is( ':checked' ) )\n {\n inject( $( elem ).attr( 'name' ), $( elem ).val() );\n }\n }\n else\n {\n inject( $( elem ).attr( 'name' ), $( elem ).val() );\n }\n }\n\n } );\n return values;\n }\n}( jQuery, PlentyFramework ));\n/**\n * Services provide functions to be called from the instanced PlentyFramework.
    \n * Services can inject Factories and can be injected into Directives. The are also\n * available from the global instance of PlentyFramework\n * @module Services\n * @main Services\n * @example\n * PlentyFramework.service('ServiceName', serviceFunctions() {\n * return {\n * functionInService: function() {}\n * }\n * });\n * //...\n * plenty.ServiceName.functionInService/();\n */\n/**\n * Licensed under AGPL v3\n * (https://github.com/plentymarkets/plenty-cms-library/blob/master/LICENSE)\n * =====================================================================================\n * @copyright Copyright (c) 2015, plentymarkets GmbH (http://www.plentymarkets.com)\n * @author Felix Dausch \n * =====================================================================================\n */\n\nPlentyFramework.compile();\n\n// Create global instance of PlentyFramework for usage in Webshop-Layouts\nvar plenty = PlentyFramework.getInstance();\n\n/*\n * initially bind all registered directives\n *\n * will not be tested. reasons:\n * http://stackoverflow.com/questions/29153733/how-to-unit-test-a-document-ready-function-using-jasmine\n */\njQuery( document ).ready( function()\n{\n plenty.bindDirectives();\n} );" + ] +} \ No newline at end of file diff --git a/dist/plentymarketsCMStools-libs-1.0.11.min.js b/dist/plentymarketsCMStools-libs-1.0.12.min.js similarity index 100% rename from dist/plentymarketsCMStools-libs-1.0.11.min.js rename to dist/plentymarketsCMStools-libs-1.0.12.min.js diff --git a/package.json b/package.json index 1cb48be..cd30ea6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "plentymarketsCMStools", "license": "AGPL-3.0", - "version": "1.0.11", + "version": "1.0.12", "repository": "https://github.com/plentymarkets/plenty-cms-library.git", "devDependencies": { "grunt": "^0.4.5", diff --git a/src/directives/Basket.js b/src/directives/Basket.js index b8d18a3..eb504b1 100644 --- a/src/directives/Basket.js +++ b/src/directives/Basket.js @@ -16,15 +16,18 @@ var basketItemsList = {}; var $elem = $( elem ); var parentForm = $elem.parents( 'form' ); + var $p_id = parentForm.find( '[name="P_ID"]:checked' ); basketItemsList.BasketItemItemID = parentForm.find( '[name="ArticleID"]' ).val(); basketItemsList.BasketItemPriceID = parentForm.find( '[name="SYS_P_ID"]' ).val(); basketItemsList.BasketItemQuantity = parentForm.find( '[name="ArticleQuantity"]' ).val(); basketItemsList.BasketItemBranchID = parentForm.find( '[name="source_category"]' ).val(); - if ( parentForm.find( '[name="P_ID"]' ) ) + // look for occurrences of unit combination and take price id of combination, if available. + if ( $p_id.length > 0 + && $p_id.val() > 0 ) { - basketItemsList.BasketItemPriceID = parentForm.find( '[name="P_ID"]:checked' ).val(); + basketItemsList.BasketItemPriceID = $p_id.val(); } //attributes diff --git a/src/services/BasketService.js b/src/services/BasketService.js index 212f3a9..83fbdbe 100644 --- a/src/services/BasketService.js +++ b/src/services/BasketService.js @@ -158,7 +158,7 @@ .done( function() { var $artAttr = $( "[name^=ArticleAttribute]" ); - var $unitCombinationId = $( "[name^=P_ID]:checked" ); + var $unitCombinationId = article[0].BasketItemPriceID; var requestData = {ArticleID: article[0].BasketItemItemID}; if ( $artAttr.val() > 0 ) @@ -169,9 +169,9 @@ requestData[value.attr( "name" )] = value.val(); } ); } - else if ( $unitCombinationId && $unitCombinationId.val() > 0 ) + else if ( $unitCombinationId && $unitCombinationId > 0 ) { - requestData["UnitCombinationId"] = $unitCombinationId.val(); + requestData["UnitCombinationId"] = $unitCombinationId; } refreshBasketPreview();