{"version":3,"file":"main.js","mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,UAAU;AACV;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,kDAAe,WAAW,EAAC;;;AC1F3B;AACA;AACA;AACA;AACA,qDAAqD,wCAAwC;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,yCAAyC,2BAA2B,IAAI,gBAAgB;AACxF;AACA;AACA;AACA,mDAAe,YAAY;;;ACjB3B;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,UAAU,GAAG,YAAY;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA,8CAA8C,UAAU;AACxD;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA,mCAAmC,YAAY;AAC/C,8CAA8C,UAAU;AACxD;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,SAAS;AAC5D;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,WAAW;AACX;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,EAAE;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,QAAQ;AACR;AACA;AACA,sCAAsC,oCAAoC;AAC1E;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE,IAAI,KAAK,IAAI,KAAK,IAAI;AAC5F;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,oEAAoE,IAAI,KAAK,IAAI;AACjF;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,oEAAoE,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,qEAAqE,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,4EAA4E,IAAI,KAAK,IAAI,KAAK,IAAI;AAClG;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;;ACjfmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,YAAY,WAAW;AACvB,IAAI,QAAQ;AACZ,IAAI,QAAQ;AACZ,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,MAAM;AACN;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,YAAY,UAAU;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP,GAAG;AACH;AACA;AACA,iDAAe,UAAU,EAAC;;;ACpH1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL,GAAG;AACH;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,6CAAe,MAAM,EAAC;;;ACjBtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,OAAO;AACP;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA,6CAAe,MAAM,EAAC;;;AC5EoB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,UAAU;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA,OAAO,IAAI,YAAY;AACvB;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,YAAY,UAAU;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD,+DAA+D;AAC/D;AACA,mCAAmC,EAAE,sBAAsB;AAC3D,mCAAmC,EAAE,sBAAsB;AAC3D,mCAAmC,EAAE,KAAK,IAAI,eAAe;AAC7D;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,sEAAsE,IAAI,KAAK,IAAI,KAAK,IAAI;AAC5F;AACA,OAAO;AACP;AACA,GAAG;AACH;AACA;AACA,uEAAuE,wCAAwC;AAC/G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,QAAQ;AACZ,GAAG;AACH;AACA;AACA;AACA,YAAY,UAAU;AACtB;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,eAAe;AACxD;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,YAAY,mBAAmB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAe,gBAAgB,EAAC;;;ACnO8B;AACc;AAC5E;AACA;AACA;AACA,qBAAqB,cAAc;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE;AAChE,WAAW;AACX;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,UAAU;AACV;AACA;AACA;AACA,wEAAwE,gBAAgB;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE;AAChE,WAAW;AACX,gBAAgB,iBAAiB;AACjC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,2FAA2F,gBAAgB;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,+CAAe,QAAQ,EAAC;;;ACjOe;AACvC;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAmB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,KAAK;AACL;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,cAAc,WAAW;AACzB,MAAM,QAAQ;AACd,MAAM,QAAQ;AACd;AACA,GAAG;AACH;AACA;AACA,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,OAAO;AACP;AACA,oCAAoC,kDAAkD;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,QAAQ;AACR;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,QAAQ;AACR;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;;;AC3J+C;AACK;AACP;AACR;AACA;AACI;AACuB;AACF;AACE;AAChE;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB,oCAAoC,kBAAkB;AAC1F;AACA;AACA;AACA,EAAE,MAAM;AACR,EAAE,WAAW;AACb,EAAE,YAAY;AACd,EAAE,cAAc;AAChB,EAAE,UAAU;AACZ,EAAE,MAAM;AACR,EAAE,QAAQ;AACV,EAAE,gBAAgB;AAClB,EAAE,SAAS;AACX,EAAE,SAAS;AACX,CAAC","sources":["webpack://build/../ilcasalingo/assets/javascripts/common/lazyLoading.js","webpack://build/../ilcasalingo/assets/javascripts/common/loadPurchase.js","webpack://build/../ilcasalingo/assets/javascripts/components/utilities.js","webpack://build/../ilcasalingo/assets/javascripts/common/cartDrawer.js","webpack://build/../ilcasalingo/assets/javascripts/common/footer.js","webpack://build/../ilcasalingo/assets/javascripts/common/header.js","webpack://build/../ilcasalingo/assets/javascripts/components/customNewsletter.js","webpack://build/../ilcasalingo/assets/javascripts/common/webforms.js","webpack://build/../ilcasalingo/assets/javascripts/components/vndaComponents.js","webpack://build/../ilcasalingo/assets/javascripts/main.js"],"sourcesContent":["const LazyLoading = {\r\n threshold: window.innerWidth < 768 ? 150 : 300,\r\n nativeImageSupport: 'loading' in HTMLImageElement.prototype,\r\n nativeIframeSupport: 'loading' in HTMLIFrameElement.prototype,\r\n\r\n setForNativeLazy: function (element) {\r\n if (element.hasAttribute('src') || element.hasAttribute('srcset')) {\r\n // console.warn('Elemento já está com lazy load nativo configurado', element)\r\n return;\r\n }\r\n\r\n if (element.hasAttribute('data-src')) {\r\n element.setAttribute('src', element.getAttribute('data-src'));\r\n }\r\n\r\n if (element.hasAttribute('data-srcset')) {\r\n element.setAttribute('srcset', element.getAttribute('data-srcset'));\r\n }\r\n\r\n if (element.hasAttribute('data-sizes')) {\r\n element.setAttribute('sizes', element.getAttribute('data-sizes'));\r\n }\r\n\r\n element.setAttribute('data-lazy-loaded', true);\r\n\r\n return true;\r\n },\r\n\r\n update: function () {\r\n if (!this.nativeImageSupport || !this.nativeIframeSupport) {\r\n window.lazyLoadInstance.update();\r\n }\r\n\r\n return LazyLoading.init();\r\n },\r\n\r\n init: function () {\r\n const lazyImages = document.querySelectorAll('img.lazy');\r\n const lazyIframes = document.querySelectorAll('iframe.lazy');\r\n\r\n if (LazyLoading.nativeImageSupport) {\r\n lazyImages.forEach((image) => {\r\n LazyLoading.setForNativeLazy(image);\r\n });\r\n }\r\n\r\n if (LazyLoading.nativeIframeSupport) {\r\n lazyIframes.forEach((iframe) => {\r\n LazyLoading.setForNativeLazy(iframe);\r\n });\r\n }\r\n\r\n // Caso tenha o suporte em um, mas não tenha no outro\r\n if (LazyLoading.nativeImageSupport && !LazyLoading.nativeIframeSupport) {\r\n lazyImages.forEach((image) => {\r\n image.classList.remove('lazy');\r\n });\r\n }\r\n\r\n if (!LazyLoading.nativeImageSupport && LazyLoading.nativeIframeSupport) {\r\n lazyIframes.forEach((iframe) => {\r\n iframe.classList.remove('lazy');\r\n });\r\n }\r\n\r\n // Adiciona vanilla lazy load caso não tenha suporte nativo para algum dos elementos\r\n if (!LazyLoading.nativeImageSupport || !LazyLoading.nativeIframeSupport) {\r\n const script = document.createElement('script');\r\n script.setAttribute('async', true);\r\n script.src = '/javascripts/lazyload.min.js';\r\n document.body.appendChild(script);\r\n\r\n window.lazyLoadOptions = {\r\n elements_selector: '.lazy',\r\n threshold: LazyLoading.threshold,\r\n };\r\n\r\n window.addEventListener(\r\n 'LazyLoad::Initialized',\r\n (event) => {\r\n window.lazyLoadInstance = event.detail.instance;\r\n },\r\n { passive: true }\r\n );\r\n }\r\n\r\n return (window.lazyLoad = LazyLoading);\r\n },\r\n};\r\n\r\nexport default LazyLoading;\r\n","const LoadPurchase = {\r\n init: function() {\r\n const products = document.querySelectorAll('[data-product-box]:not([data-product-unique-id])')\r\n const observer = new IntersectionObserver(entries => {\r\n const intersecting = entries.filter(entry => { if (entry.isIntersecting) return entry })\r\n if (intersecting.length > 0) {\r\n const scriptEl = document.createElement('script')\r\n scriptEl.src = window.purchaseScript\r\n document.body.appendChild(scriptEl)\r\n observer.disconnect()\r\n }\r\n })\r\n\r\n return products.forEach(product => { observer.observe(product) }, { threshold: 0.1 })\r\n }\r\n}\r\n\r\nexport default LoadPurchase\r\n","// ===============================================================\r\n// ADIÇÃO MANUAL DE ASSET\r\n// ===============================================================\r\n// Usado para incluir assets no código de forma manual, conforme a necessidade\r\nexport function addAsset(source, onloadCallback) {\r\n if (!source || source === '') return console.error(`addAsset: caminho não definido.`);\r\n\r\n if (source.includes('.js')) {\r\n const scriptTag = document.createElement('script');\r\n scriptTag.setAttribute('src', source);\r\n\r\n if (onloadCallback && typeof onloadCallback === 'function') {\r\n scriptTag.onload = onloadCallback;\r\n }\r\n\r\n return document.body.appendChild(scriptTag);\r\n } else if (source.includes('.css')) {\r\n const linkTag = document.createElement('link');\r\n linkTag.setAttribute('rel', 'stylesheet');\r\n linkTag.setAttribute('type', 'text/css');\r\n linkTag.setAttribute('href', source);\r\n return document.head.appendChild(linkTag);\r\n } else {\r\n const error = `addAsset: Erro ao criar o asset. Tipo de script não definido, ou não possui tratamento para este tipo de asset.`;\r\n return console.error(error, source);\r\n }\r\n}\r\n\r\n// ===============================================================\r\n// BUSCA O CARRINHO ATIVO\r\n// ===============================================================\r\nexport async function getCart() {\r\n try {\r\n const response = await fetch('/carrinho', {\r\n headers: {\r\n Accept: 'application/json',\r\n },\r\n });\r\n\r\n return await response.json();\r\n } catch (error) {\r\n console.error('Erro ao buscar os dados do carrinho');\r\n console.error(error);\r\n return false;\r\n }\r\n}\r\n\r\n// ===============================================================\r\n// SERIALIZE ARRAY\r\n// ===============================================================\r\nexport function serializeArray(form) {\r\n const formData = new FormData(form);\r\n const data = {};\r\n\r\n for (const [name, value] of formData) {\r\n data[name] = value;\r\n }\r\n\r\n const formBody = [];\r\n\r\n for (const key in data) {\r\n const encodeKey = encodeURIComponent(key);\r\n const encodeValue = encodeURIComponent(data[key]);\r\n formBody.push(`${encodeKey}=${encodeValue}`);\r\n }\r\n\r\n return formBody.join('&');\r\n}\r\n\r\n// ===============================================================\r\n// URL ENCODE FORM DATA\r\n// ===============================================================\r\nexport function urlencodeFormData(formData) {\r\n let string = '';\r\n\r\n function encode(s) {\r\n return encodeURIComponent(s).replace(/%20/g, '+');\r\n }\r\n\r\n for (const pair of formData.entries()) {\r\n if (typeof pair[1] == 'string') {\r\n string += (string ? '&' : '') + encode(pair[0]) + '=' + encode(pair[1]);\r\n }\r\n }\r\n return string;\r\n}\r\n\r\n// ===============================================================\r\n// SLIDE TOGGLE\r\n// ===============================================================\r\nexport function slideToggle(contentWrapper, content, duration = 500) {\r\n let initialHeight = window.getComputedStyle(contentWrapper).height;\r\n\r\n if (initialHeight == '0px') {\r\n return slideDown(contentWrapper, content, duration);\r\n } else {\r\n return slideUp(contentWrapper, duration);\r\n }\r\n}\r\n\r\n// ===============================================================\r\n// SLIDE UP\r\n// ===============================================================\r\nexport function slideUp(contentWrapper, duration = 500) {\r\n contentWrapper.style.height = '0px';\r\n contentWrapper.style.transition = `height ${duration} ease`;\r\n}\r\n\r\n// ===============================================================\r\n// SLIDE DOWN\r\n// ===============================================================\r\nexport function slideDown(contentWrapper, content, duration = 500) {\r\n let innerHeight = content.clientHeight;\r\n\r\n contentWrapper.style.height = `${innerHeight}px`;\r\n contentWrapper.style.transition = `height ${duration} ease`;\r\n}\r\n\r\n// ===============================================================\r\n// UPDATE DISCOUNT IN PRODUCT BLOCK\r\n// ===============================================================\r\nexport function updatePriceBlock() {\r\n const priceEls = document.querySelectorAll('[data-init-price]');\r\n\r\n if (priceEls == null) return;\r\n\r\n priceEls.forEach((priceEl) => {\r\n const discount = priceEl.dataset.discountPercent;\r\n\r\n priceEl.dispatchEvent(new Event('change'));\r\n\r\n // discount\r\n if (discount != '0') {\r\n priceEl.style.setProperty('--discount', `'-${discount}%'`);\r\n }\r\n });\r\n}\r\n\r\n// ===============================================================\r\n// PREÇO POR FETCH\r\n// ===============================================================\r\nexport function getPriceProd() {\r\n const selectors = document.querySelectorAll('[data-update-price]');\r\n const attr = 'data-update-price';\r\n\r\n if (selectors.length > 0) {\r\n selectors.forEach((selector) => {\r\n const prodId = selector.getAttribute(attr);\r\n const url = `/produto/preco/${prodId}`;\r\n\r\n if (prodId !== '' && prodId !== null) {\r\n fetch(url, {\r\n method: 'GET',\r\n })\r\n .then((response) => response.text())\r\n .then((resp) => {\r\n selector.innerHTML = resp;\r\n })\r\n .catch((error) => {\r\n console.error(error);\r\n });\r\n }\r\n });\r\n }\r\n}\r\n\r\n// ===============================================================\r\n// DEBOUNCE\r\n// ===============================================================\r\n/*\r\n Debounce retorna uma função que enquanto continuar sendo chamada não é executada\r\n A função só será executada quando para de ser chamada por N milisegundos\r\n Útil para melhorar a performance de códigos que são executados muitas vezes por segundo, como o $(window).resize()\r\n\r\n Ex:\r\n \r\n $(window).resize(debounce(function() {\r\n // código a ser executado\r\n }, 500))\r\n \r\n No exemplo acima a função só será executada 500ms depois do último resize\r\n Abra o link abaixo e redimensione a janela branca e acompanhe o output do console\r\n Exemplo codepen: https://codepen.io/valkervieira/pen/oNgqyWY\r\n\r\n Um caso comum de uso é em lojas onde a seleção de um filtro na página de tag recarrega automáticamente a página\r\n Com o debounce o usuário pode escolher vários filtros rapidamente e a página só recarrega quando parar de escolher\r\n*/\r\n\r\nexport function debounce(func, wait, immediate) {\r\n var timeout;\r\n immediate || (immediate = true);\r\n\r\n return function () {\r\n var context = this,\r\n args = arguments;\r\n\r\n var later = function () {\r\n timeout = null;\r\n if (!immediate) func.apply(context, args);\r\n };\r\n\r\n var callNow = immediate && !timeout;\r\n\r\n clearTimeout(timeout);\r\n\r\n timeout = setTimeout(later, wait);\r\n\r\n if (callNow) func.apply(context, args);\r\n };\r\n}\r\n\r\n// ===============================================================\r\n// THROTTLE\r\n// ===============================================================\r\n/*\r\n Throttle diminui a frequencia que uma função é executada\r\n Enquanto no debounce a função só é executada quando para de ser chamada, no throttle ela\r\n continua sendo executada só que em um intervalo mínimo de N milisegundos (default = 250)\r\n\r\n Ex:\r\n\r\n $(window).resize(throttle() {\r\n // código a ser executado\r\n }, 500)\r\n\r\n No exemplo acima a função resize é chamada várias vezes por segundo mas só é executada 1 vez a cada 500ms\r\n Abra o link abaixo, redimensione a janela branca e acompanhe o console\r\n Exemplo codepen: https://codepen.io/valkervieira/pen/yLyKEPW\r\n\r\n Um caso comum de uso é checar se o scroll passou de um determinado ponto, para fixar um header ou alterar algum elemento do DOM\r\n*/\r\nexport function throttle(fn, threshhold, scope) {\r\n threshhold || (threshhold = 250);\r\n var last, deferTimer;\r\n return function () {\r\n var context = scope || this;\r\n\r\n var now = +new Date(),\r\n args = arguments;\r\n if (last && now < last + threshhold) {\r\n // hold on to it\r\n clearTimeout(deferTimer);\r\n deferTimer = setTimeout(function () {\r\n last = now;\r\n fn.apply(context, args);\r\n }, threshhold);\r\n } else {\r\n last = now;\r\n fn.apply(context, args);\r\n }\r\n };\r\n}\r\n\r\n// ===============================================================\r\n// FORMAT MONEY\r\n// ===============================================================\r\nexport function formatMoney(value) {\r\n // FORMATA UM VALOR\r\n return (\r\n 'R$ ' +\r\n value\r\n .toFixed(2)\r\n .replace('.', ',')\r\n .replace(/(\\d)(?=(\\d{3})+\\,)/g, '$1.')\r\n );\r\n}\r\n\r\n// ===============================================================\r\n// FORMAT VALUE\r\n// ===============================================================\r\n\r\nexport const formatValue = function (value = '') {\r\n let parsedValue = value;\r\n if (typeof value === 'number') {\r\n parsedValue = value.toFixed(2).toString();\r\n }\r\n return parsedValue.replace('.', ',');\r\n};\r\n\r\n// ===============================================================\r\n// VALIDA QUANTIDADE\r\n// ===============================================================\r\nexport function validateQuantity(_val) {\r\n // VALIDA SE A QUANTIDADE INFORMADA É UM NÚMERO\r\n if (!isNaN(_val)) {\r\n if (parseInt(_val) > 0) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n// ===============================================================\r\n// CLEAR NUMBER\r\n// ===============================================================\r\nexport function getClearNumber(_val) {\r\n // RETORNA UM NÚMERO LIMPO COMO INT\r\n if (!isNaN(_val)) {\r\n var clearNumber = parseInt(_val);\r\n\r\n return clearNumber;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n// ===============================================================\r\n// BUSCA\r\n// ===============================================================\r\nexport function setSearch() {\r\n const toggleButton = document.querySelectorAll('[data-toggle-search]');\r\n const search = document.querySelector('[data-search-container]');\r\n const input = document.querySelector('[data-search-input]');\r\n const options = document.querySelector('[data-search-options]');\r\n\r\n toggleButton.length > 0 &&\r\n toggleButton.forEach((button) => {\r\n button.addEventListener('click', () => {\r\n if (search.classList.contains('open')) {\r\n search.classList.remove('open');\r\n } else {\r\n search.classList.add('open');\r\n setTimeout(() => {\r\n input.focus();\r\n }, 400);\r\n }\r\n });\r\n });\r\n \r\n if (input && options) {\r\n input.addEventListener('input', async () => {\r\n\r\n if (input.value && input.value != '') {\r\n if (options.innerHTML == '')\r\n try {\r\n const baseUrl = window.location.origin;\r\n const url = new URL(`/produto/quickview/4163`, baseUrl); // STG:5074 PROD:4163\r\n url.searchParams.set('search_value', input.value);\r\n url.searchParams.set('CC', Math.floor(Math.random() * 10000));\r\n \r\n const response = await fetch(url);\r\n const data = await response.text();\r\n const parser = new DOMParser();\r\n const doc = parser.parseFromString(data, 'text/html');\r\n const results = doc.querySelector('[data-search-results]');\r\n \r\n if (results && results.innerHTML)\r\n options.innerHTML = results.innerHTML;\r\n \r\n } catch (error) { console.error(error) }\r\n \r\n let anchors = options.querySelectorAll('.anchor');\r\n if (anchors.length > 0) {\r\n let count = 0;\r\n anchors.forEach(anchor => {\r\n anchor.classList.remove('-active');\r\n if (anchor.getAttribute('data-name').includes(input.value.toLowerCase()) && count < 10) {\r\n anchor.classList.add('-active');\r\n count++;\r\n }\r\n });\r\n }\r\n\r\n } else {\r\n let anchors = options.querySelectorAll('.anchor');\r\n if (anchors.length > 0)\r\n anchors.forEach(anchor => { anchor.classList.remove('-active') });\r\n }\r\n });\r\n }\r\n}\r\n\r\n// ===============================================================\r\n// BUSCA OS DADOS DO CLIENTE\r\n// ===============================================================\r\nexport async function getClient() {\r\n try {\r\n const response = await fetch('/conta/cliente', {\r\n headers: {\r\n accept: 'application/json',\r\n 'Content-Type': 'application/json',\r\n cache: 'no-store',\r\n },\r\n });\r\n const client = await response.json();\r\n const access = Object.keys(client).length > 0;\r\n\r\n if (access) {\r\n window.client = client;\r\n\r\n return client;\r\n } else {\r\n return null;\r\n }\r\n } catch (error) {\r\n console.error(`getClient error`, error);\r\n }\r\n}\r\n\r\n// ===============================================================\r\n// MÁSCARA PARA INPUTS\r\n// ===============================================================\r\nexport function formMasks() {\r\n const inputPhones = document.querySelectorAll('[data-phone-mask]'),\r\n inputCEPs = document.querySelectorAll('[data-cep-mask]'),\r\n inputCPFs = document.querySelectorAll('[data-cpf-mask]'),\r\n inputCNPJs = document.querySelectorAll('[data-cnpj-mask]'),\r\n inputDatesOfBirth = document.querySelectorAll('[data-birth-mask]');\r\n\r\n inputPhones.length > 0 &&\r\n inputPhones.forEach((input) => {\r\n input.addEventListener('input', (e) => {\r\n //(XX) XXXXX-XXXX\r\n var phoneValue = e.target.value.replace(/\\D/g, '').match(/(\\d{0,2})(\\d{0,5})(\\d{0,4})/);\r\n e.target.value = !phoneValue[2]\r\n ? phoneValue[1]\r\n : '(' + phoneValue[1] + ') ' + phoneValue[2] + (phoneValue[3] ? '-' + phoneValue[3] : '');\r\n });\r\n });\r\n\r\n inputCEPs.length > 0 &&\r\n inputCEPs.forEach((input) => {\r\n input.addEventListener('input', (e) => {\r\n //XXXXX-XX\r\n var cepValue = e.target.value.replace(/\\D/g, '').match(/(\\d{0,5})(\\d{0,3})/);\r\n e.target.value = !cepValue[2] ? cepValue[1] : cepValue[1] + '-' + cepValue[2];\r\n });\r\n });\r\n\r\n inputCPFs.length > 0 &&\r\n inputCPFs.forEach((input) => {\r\n input.addEventListener('input', (e) => {\r\n //XXX.XXX.XXX-XX\r\n var cpfValue = e.target.value.replace(/\\D/g, '').match(/(\\d{0,3})(\\d{0,3})(\\d{0,3})(\\d{0,2})/);\r\n e.target.value = !cpfValue[2]\r\n ? cpfValue[1]\r\n : cpfValue[1] +\r\n '.' +\r\n cpfValue[2] +\r\n (cpfValue[3] ? '.' + cpfValue[3] : '') +\r\n (cpfValue[4] ? '-' + cpfValue[4] : '');\r\n });\r\n });\r\n\r\n inputCNPJs.length > 0 &&\r\n inputCNPJs.forEach((input) => {\r\n input.addEventListener('input', (e) => {\r\n //XX.XXX.XXX/XXXX-XX\r\n var cnpjValue = e.target.value.replace(/\\D/g, '').match(/(\\d{0,2})(\\d{0,3})(\\d{0,3})(\\d{0,4})(\\d{0,2})/);\r\n e.target.value = !cnpjValue[2]\r\n ? cnpjValue[1]\r\n : cnpjValue[1] +\r\n '.' +\r\n cnpjValue[2] +\r\n (cnpjValue[3] ? '.' + cnpjValue[3] : '') +\r\n (cnpjValue[4] ? '/' + cnpjValue[4] : '') +\r\n (cnpjValue[5] ? '-' + cnpjValue[5] : '');\r\n });\r\n });\r\n\r\n inputDatesOfBirth.length > 0 &&\r\n inputDatesOfBirth.forEach((input) => {\r\n input.addEventListener('input', (e) => {\r\n // XXXX-XX-XX\r\n var dateOfBirthValue = e.target.value.replace(/\\D/g, '').match(/(\\d{0,2})(\\d{0,2})(\\d{0,4})/);\r\n e.target.value = !dateOfBirthValue[2]\r\n ? dateOfBirthValue[1]\r\n : dateOfBirthValue[1] + '/' + dateOfBirthValue[2] + (dateOfBirthValue[3] ? '/' + dateOfBirthValue[3] : '');\r\n });\r\n });\r\n}\r\n\r\nexport function videoLazy() {\r\n const videos = document.querySelectorAll('[data-video-banner]');\r\n\r\n if (videos.length > 0) {\r\n videos.forEach((video) => {\r\n const addSrcVideo = () => {\r\n const urlVideo = video.getAttribute('data-video-banner');\r\n const iframe = video.querySelector('iframe');\r\n\r\n if (iframe && urlVideo) {\r\n iframe.setAttribute('src', urlVideo);\r\n //console.log('Vídeo carregado:', urlVideo);\r\n\r\n // Remove os event listeners após carregar o vídeo\r\n window.removeEventListener('mousemove', addSrcVideo);\r\n window.removeEventListener('scroll', addSrcVideo);\r\n }\r\n };\r\n\r\n // Adiciona os event listeners\r\n window.addEventListener('mousemove', addSrcVideo);\r\n window.addEventListener('scroll', addSrcVideo);\r\n });\r\n }\r\n}\r\n","import { addAsset } from '../components/utilities';\r\n\r\nconst CartDrawer = {\r\n root: document.querySelector('#component-cart-drawer-root'),\r\n buttons: document.querySelectorAll('[data-toggle-cart]'),\r\n countWrapper: document.querySelector('[data-cart-count]'),\r\n settings: window.cartDrawerSettings || false,\r\n\r\n setCartDrawer: function () {\r\n const { settings, root } = CartDrawer;\r\n\r\n if (!root || !settings) return;\r\n\r\n // Define frete grátis\r\n const freeShipping = settings.freeShippingValue > 1 ? settings.freeShippingValue : 0;\r\n\r\n // Inicia o componente\r\n const componentCartDrawer = new Vnda.Component.CartDrawer({\r\n anchor: 'right',\r\n display: 'list',\r\n startOpen: false,\r\n titleCart: 'Carrinho de compras',\r\n titleSuggested: window.cartDrawerSettings.titleSuggested,\r\n suggestedProductsTag: 'sugestoes-carrinho',\r\n widthItemSuggested: 25,\r\n disableShippingCalculation: true,\r\n freeShipping,\r\n });\r\n\r\n // Renderiza o componente\r\n componentCartDrawer.render(root);\r\n\r\n // Salva instância para acesso global\r\n window.cartDrawerSettings.instance = componentCartDrawer;\r\n CartDrawer.settings = window.cartDrawerSettings;\r\n\r\n // dispara evento de carregamento, escutado por CartDrawer.show()\r\n root.dispatchEvent(new Event('vnda:cart-drawer-loaded'));\r\n },\r\n\r\n loadComponent: function () {\r\n const { settings } = CartDrawer;\r\n addAsset(settings.script, CartDrawer.setCartDrawer);\r\n addAsset(settings.styles);\r\n },\r\n\r\n handleCartButton: function (button) {\r\n // Evita múltiplos cliques caso o carrinho precisa ser instanciado primeiro\r\n if (button.classList.contains('-loading')) {\r\n return;\r\n }\r\n\r\n // Abre o cart drawer\r\n button.classList.add('-loading');\r\n CartDrawer.show(() => {\r\n button.classList.remove('-loading');\r\n });\r\n },\r\n\r\n show: function (callback) {\r\n const { root } = CartDrawer;\r\n\r\n // No mobile, fecha o menu primeiro\r\n if (window.mmenu) window.mmenu.close();\r\n\r\n // Instancia o componente, caso ainda não exista\r\n if (!CartDrawer.settings.instance) CartDrawer.loadComponent();\r\n\r\n // Observa criação da instância inicial, caso não tenha\r\n if (CartDrawer.settings.instance === false) {\r\n root.addEventListener('vnda:cart-drawer-loaded', () => {\r\n CartDrawer.settings.instance.open();\r\n if (typeof callback === 'function') callback();\r\n });\r\n } else {\r\n // Já possui cart drawer instanciado, retorna abertura\r\n CartDrawer.settings.instance.open();\r\n if (typeof callback === 'function') callback();\r\n }\r\n },\r\n\r\n getCartItens: async function () {\r\n try {\r\n const response = await fetch('/carrinho/itens');\r\n const itens = await response.json();\r\n return itens;\r\n } catch (error) {\r\n console.error('Erro ao buscar a quantidade de produtos do carrinho');\r\n console.error(error);\r\n return 0;\r\n }\r\n },\r\n\r\n updateCartCount: async function (_itemsCount = null) {\r\n let items = _itemsCount;\r\n if (_itemsCount == null) items = await CartDrawer.getCartItens();\r\n\r\n this.countWrapper.innerHTML = items;\r\n },\r\n\r\n init: function () {\r\n const _this = this;\r\n const { buttons } = _this;\r\n\r\n // Atualiza o contador de itens do carrinho\r\n _this.updateCartCount();\r\n\r\n if (buttons.length > 0)\r\n buttons.forEach((button) => {\r\n button.addEventListener('click', () => {\r\n _this.handleCartButton(button);\r\n });\r\n });\r\n },\r\n};\r\n\r\nexport default CartDrawer;\r\n","const Footer = {\r\n handleSubmenu: function () {\r\n const menus = document.querySelectorAll('[data-action=\"toggle-menu-footer\"]');\r\n\r\n menus.length > 0 && menus.forEach((menu) => {\r\n menu.addEventListener('click', () => {\r\n menu.classList.toggle('-open', !menu.classList.contains('-open'));\r\n });\r\n });\r\n },\r\n init: function () {\r\n const _this = this;\r\n\r\n _this.handleSubmenu();\r\n },\r\n};\r\n\r\nexport default Footer;\r\n","const Header = {\r\n lastScrollTop: -1,\r\n scrollTop: window.scrollY,\r\n header: document.querySelector('#header'),\r\n\r\n setScroll: function (scrollTop, lastScrollTop) {\r\n const _this = this;\r\n\r\n if (scrollTop <= 0) {\r\n _this.header.classList.add('scroll-up');\r\n _this.header.classList.remove('scroll-down');\r\n _this.header.classList.add('on-top');\r\n } else {\r\n if (_this.header.classList.contains('on-top')) {\r\n _this.header.classList.remove('on-top');\r\n }\r\n if (scrollTop > lastScrollTop) {\r\n _this.header.classList.add('scroll-down');\r\n _this.header.classList.remove('scroll-up');\r\n } else {\r\n _this.header.classList.add('scroll-up');\r\n _this.header.classList.remove('scroll-down');\r\n }\r\n }\r\n },\r\n\r\n searchButton: function () {\r\n const searchButton = document.querySelector('[data-action=\"show-form-search\"]');\r\n const searchButtonClose = document.querySelector('[data-action=\"hide-form-search\"]');\r\n const formSearch = document.querySelector('.header-search');\r\n const formSearchInput = document.querySelector('.header-search input');\r\n\r\n if (!formSearch) return;\r\n\r\n searchButton &&\r\n searchButton.addEventListener('click', () => {\r\n formSearch.classList.toggle('-active', !formSearch.classList.contains('-active'));\r\n\r\n formSearchInput && formSearchInput.focus();\r\n\r\n if (window.innerWidth > 768) {\r\n document.addEventListener('scroll', () => {\r\n formSearch.classList.remove('-active');\r\n });\r\n }\r\n });\r\n\r\n searchButtonClose &&\r\n searchButtonClose.addEventListener('click', () => {\r\n formSearch.classList.remove('-active');\r\n });\r\n\r\n // Desativa o popup de busca - quando necessário\r\n formSearch.addEventListener('click', (e) => {\r\n if (e.target.className == 'header-search -active') {\r\n formSearch.classList.remove('-active');\r\n }\r\n });\r\n },\r\n\r\n init: function () {\r\n const _this = this;\r\n\r\n _this.setScroll(_this.scrollTop, _this.lastScrollTop);\r\n _this.searchButton();\r\n\r\n // Atualiza o header quando a page recebe scroll\r\n window.addEventListener('scroll', function () {\r\n const newSt = window.scrollY;\r\n\r\n _this.setScroll(newSt, _this.lastScrollTop);\r\n _this.lastScrollTop = newSt;\r\n });\r\n },\r\n};\r\n\r\nexport default Header;\r\n","import Webforms from \"../common/webforms\";\r\n\r\nconst CustomNewsletter = {\r\n popupEl: document.querySelector('[data-popup-newsletter]'),\r\n instance: false,\r\n\r\n\r\n // Carrega e define as funcionalidades da newsletter\r\n loadNewsletter: function() {\r\n\r\n // Cria o container principal\r\n const { popupEl } = CustomNewsletter;\r\n // Evento para abrir a newsletter\r\n const eventType = (window.innerWidth <= 1024) ? 'scroll' : 'mousemove';\r\n\r\n\r\n if (popupEl) {\r\n\r\n // Mascaras de inputs\r\n CustomNewsletter.handleInputs(popupEl);\r\n\r\n // Evento para fechar\r\n const closeButtons = document.querySelectorAll('[data-close-newsletter]');\r\n closeButtons.length > 0 && closeButtons.forEach(el => {\r\n el.addEventListener('click', CustomNewsletter.close);\r\n })\r\n\r\n // Evento de abertura\r\n window.addEventListener(eventType, () => {\r\n CustomNewsletter.instance = popupEl.innerHTML;\r\n CustomNewsletter.open();\r\n }, { once: true });\r\n\r\n CustomNewsletter.setPopupCupom();\r\n\r\n }\r\n },\r\n\r\n setPopupCupom: function () {\r\n const { popupEl } = CustomNewsletter;\r\n\r\n const close = popupEl.querySelector('[data-close-newsletter]');\r\n const popup = document.querySelector('[data-popup-cupom]');\r\n\r\n if (!popup || !popupEl || popup.dataset.initialized) {\r\n return;\r\n }\r\n\r\n const activatePopup = () => {\r\n popup.classList.add('-active');\r\n CustomNewsletter.close();\r\n };\r\n\r\n const deactivatePopup = () => {\r\n popup.classList.remove('-active');\r\n popup.remove();\r\n CustomNewsletter.open();\r\n };\r\n\r\n const content = popup.querySelector('.close');\r\n if (content) {\r\n content.addEventListener('click', () => {\r\n deactivatePopup();\r\n });\r\n }\r\n\r\n if (close) {\r\n close.addEventListener('click', () => {\r\n console.log('Popup de cupom será ativado');\r\n setTimeout(activatePopup, 1000);\r\n });\r\n }\r\n\r\n popupEl.addEventListener('click', (e) => {\r\n if (e.target.hasAttribute('data-close-newsletter')) {\r\n activatePopup();\r\n }\r\n }); \r\n\r\n // Marca o popup como configurado\r\n popup.dataset.initialized = true;\r\n },\r\n\r\n // Mascara dos inputs de cpf e telefone\r\n handleInputs: function (selector) {\r\n const inputCpf = selector.querySelector('[name=\"cpf\"]');\r\n const inputPhone = selector.querySelector('[name=\"phone\"]')\r\n\r\n if (inputCpf) {\r\n inputCpf && inputCpf.addEventListener('input', function (e) {\r\n let value = e.target.value.replace(/\\D/g, \"\"); // Remove tudo que não é dígito\r\n if (value.length > 11) value = value.substring(0, 11); // Limita a 11 dígitos (CPF)\r\n \r\n value = value.replace(/(\\d{3})(\\d)/, \"$1.$2\"); // Adiciona ponto após os primeiros 3 dígitos\r\n value = value.replace(/(\\d{3})(\\d)/, \"$1.$2\"); // Adiciona ponto após os segundos 3 dígitos\r\n value = value.replace(/(\\d{3})(\\d{1,2})$/, \"$1-$2\"); // Adiciona traço antes dos últimos 2 dígitos\r\n \r\n e.target.value = value;\r\n });\r\n }\r\n\r\n if (inputPhone) {\r\n inputPhone && inputPhone.addEventListener('input', (e) => {\r\n //(XX) XXXXX-XXXX\r\n var phoneValue = e.target.value.replace(/\\D/g, '').match(/(\\d{0,2})(\\d{0,5})(\\d{0,4})/);\r\n e.target.value = !phoneValue[2] ? phoneValue[1] : '(' + phoneValue[1] + ') ' + phoneValue[2] + (phoneValue[3] ? '-' + phoneValue[3] : '');\r\n });\r\n }\r\n },\r\n\r\n // Faz a troca de elementos no DOM considerando o tempo de transição utilizado\r\n toggleContent: async function(contentWrapper, newHtml, initialHtml, {transitionTime = 400, switchTime = 3000}) {\r\n const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\n if (!contentWrapper || !newHtml || !initialHtml) return;\r\n\r\n contentWrapper.classList.add('-hide');\r\n await delay(transitionTime);\r\n\r\n contentWrapper.innerHTML = newHtml;\r\n contentWrapper.classList.remove('-hide');\r\n await delay(switchTime);\r\n\r\n contentWrapper.classList.add('-hide');\r\n await delay(transitionTime);\r\n \r\n contentWrapper.innerHTML = initialHtml;\r\n contentWrapper.classList.remove('-hide');\r\n\r\n Webforms.setWebForms();\r\n },\r\n\r\n // Exibe os elementos da mensagem de sucesso\r\n handleSuccessMessage: function(form) {\r\n const { popupEl } = CustomNewsletter;\r\n\r\n\r\n if (!popupEl || !window.successNewsletter) return;\r\n\r\n const transitionTime = '400'; // Deve ser em ms\r\n const switchTime = '3000';\r\n\r\n \r\n const contentWrapper = popupEl.querySelector('.content-wrapper') || null;\r\n contentWrapper.querySelector('.action').innerHTML = 'Enviar';\r\n\r\n form.classList.remove('sending');\r\n contentWrapper.style.transition = `${transitionTime}ms all ease`\r\n const initialHtml = contentWrapper ? contentWrapper.innerHTML : '';\r\n\r\n const newHtml = `\r\n
\r\n `\r\n\r\n form.reset();\r\n // Função que trata os timeOuts necessários para remover e exibir os elementos com trasição\r\n CustomNewsletter.toggleContent(contentWrapper, newHtml, initialHtml, transitionTime, switchTime);\r\n\r\n \r\n },\r\n\r\n // Exibe a newsletter de acordo com a frequencia desejada\r\n handleFrequency: function(numberOfDays = 7) {\r\n const currentDate = new Date().getTime();\r\n\r\n const lastActiveDate = localStorage.getItem('datePopupNewsletter');\r\n\r\n if (lastActiveDate) {\r\n const dateDiff = Math.abs((currentDate - Number(lastActiveDate)) / (1000 * 60 * 60 * 24));\r\n\r\n\r\n if (dateDiff >= numberOfDays) {\r\n CustomNewsletter.loadNewsletter();\r\n }\r\n } else {\r\n CustomNewsletter.loadNewsletter();\r\n }\r\n\r\n },\r\n \r\n // Coloca variavel de data de exibição no localStorage\r\n setLocalStorageDate: function () {\r\n const currentDate = new Date().getTime();\r\n\r\n localStorage.setItem('datePopupNewsletter', currentDate);\r\n },\r\n\r\n // Exibe o popup\r\n open: function() {\r\n const { popupEl,instance } = CustomNewsletter;\r\n\r\n\r\n if (instance && popupEl.innerHTML != instance) popupEl.innerHTML = instance;\r\n \r\n\r\n if(!popupEl.classList.contains('-active')) {\r\n popupEl.classList.add('-active')\r\n }\r\n\r\n },\r\n\r\n // Fecha a newsletter e executa função de colocar data no localStorage\r\n close: function() {\r\n const popupEl = document.querySelector('[data-popup-newsletter]');\r\n\r\n if(popupEl.classList.contains('-active')) {\r\n popupEl.classList.remove('-active')\r\n\r\n setTimeout(popupEl.innerHTML = \"\", 1000)\r\n }\r\n\r\n CustomNewsletter.setLocalStorageDate();\r\n },\r\n\r\n \r\n \r\n\r\n\r\n init: function() {\r\n const _this = this;\r\n _this.handleFrequency(7);\r\n\r\n }\r\n}\r\n\r\nexport default CustomNewsletter;\r\n","import CustomNewsletter from '../components/customNewsletter';\r\nimport { serializeArray, urlencodeFormData } from '../components/utilities';\r\n\r\nconst Webforms = {\r\n submitWebForm: async function (form, email) {\r\n const formData = serializeArray(form);\r\n const textBtnDefault = form.querySelector('.action').innerHTML;\r\n\r\n if (typeof email == 'undefined' || email == '') {\r\n email = form.querySelector('[name=\"email\"]').value;\r\n }\r\n\r\n form.querySelector('[name=\"reply_to\"]').value = email;\r\n\r\n if (!form.classList.contains('sending')) {\r\n\r\n form.classList.add('sending');\r\n form.classList.remove('error');\r\n form.querySelector('.action').innerHTML = 'Enviando';\r\n\r\n try {\r\n const response = await fetch('/webform', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\r\n },\r\n body: formData\r\n })\r\n\r\n if (response.ok) {\r\n\r\n if (form.hasAttribute('data-newsletter-popup-form') && window.successNewsletter) {\r\n console.info('Formulário enviado com sucesso');\r\n CustomNewsletter.handleSuccessMessage(form);\r\n\r\n } else {\r\n form.querySelector('.msg-success').classList.add('-visible');\r\n form.querySelector('.action').innerHTML = 'Enviado';\r\n \r\n setTimeout(function () {\r\n form.classList.remove('sent');\r\n form.querySelector('.msg-success').classList.remove('-visible');\r\n form.querySelector('.action').innerHTML = textBtnDefault;\r\n }, 3500);\r\n }\r\n } else {\r\n\r\n const text = await response.text();\r\n\r\n console.error(`Ocorreu um erro no envio do formulário. Erro ${response.status}`);\r\n console.error(text);\r\n\r\n form.classList.add('error');\r\n form.querySelector('.msg-error').classList.add('-visible');\r\n form.querySelector('.action').innerHTML = 'Falha ao enviar';\r\n\r\n setTimeout(function () {\r\n form.classList.remove('error');\r\n form.querySelector('.msg-error').classList.remove('-visible');\r\n form.querySelector('.action').innerHTML = textBtnDefault;\r\n }, 3500);\r\n\r\n }\r\n\r\n } catch (error) {\r\n console.error('Erro ao enviar o webform');\r\n console.error(error);\r\n\r\n form.classList.add('error');\r\n form.querySelector('.msg-error').classList.add('-visible');\r\n form.querySelector('.action').innerHTML = 'Falha ao enviar';\r\n\r\n setTimeout(function () {\r\n form.classList.remove('error');\r\n form.querySelector('.msg-error').classList.remove('-visible');\r\n form.querySelector('.action').innerHTML = textBtnDefault;\r\n }, 3500);\r\n }\r\n\r\n form.classList.remove('sending');\r\n }\r\n },\r\n submitNotify: async function (form) {\r\n const formData = new FormData(form);\r\n const btnTextDefault = form.querySelector('.action').innerHTML;\r\n\r\n // Manipula o campo de telefone\r\n const inputPhone = form.querySelector('#phone-notify-when-arrives');\r\n if (inputPhone) {\r\n const phoneNumber = inputPhone.value;\r\n const phoneArea = phoneNumber.substring(1, 3);\r\n const phone = phoneNumber.substring(5, 16).replace(/\\D/g, '');\r\n\r\n formData.append(\"phone_area\", phoneArea);\r\n formData.append(\"phone\", phone);\r\n formData.delete(\"phone_number\");\r\n }\r\n\r\n if (!form.classList.contains('sending')) {\r\n\r\n form.classList.remove('error');\r\n form.classList.add('sending');\r\n form.querySelector('.action').innerHTML = 'Enviando';\r\n\r\n try {\r\n\r\n const response = await fetch('/lista_de_espera', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',\r\n },\r\n body: urlencodeFormData(formData)\r\n })\r\n\r\n if (response.ok) {\r\n form.classList.remove('sending');\r\n \r\n // Envia um webform de aviso de cadastro\r\n console.log('Lista de espera enviada com sucesso');\r\n Webforms.submitWebForm(form);\r\n\r\n } else {\r\n const text = await response.text();\r\n console.error(`Ocorreu um erro ao enviar o formulário de Lista de Espera. Erro ${response.status}`)\r\n console.error(text);\r\n\r\n form.classList.add('error');\r\n form.querySelector('.msg-error').classList.add('-visible');\r\n form.querySelector('.action').innerHTML = 'Falha ao enviar';\r\n\r\n setTimeout(() => {\r\n form.classList.remove('error');\r\n form.querySelector('.msg-error').classList.remove('-visible');\r\n form.querySelector('.action').innerHTML = btnTextDefault;\r\n }, 3500);\r\n }\r\n\r\n } catch (error) {\r\n console.error('Falha ao enviar lista de espera. Verificar integração.');\r\n console.error(error);\r\n\r\n form.classList.add('error');\r\n form.querySelector('.msg-error').classList.add('-visible');\r\n form.querySelector('.action').innerHTML = 'Falha ao enviar';\r\n\r\n setTimeout(() => {\r\n form.classList.remove('error');\r\n form.querySelector('.msg-error').classList.remove('-visible');\r\n form.querySelector('.action').innerHTML = btnTextDefault;\r\n }, 3500);\r\n }\r\n\r\n form.classList.remove('sending');\r\n }\r\n },\r\n showMessage: function (input, form) {\r\n const alertMessage = form.querySelector('[data-msg]');\r\n\r\n alertMessage.classList.add('-visible');\r\n alertMessage.innerText = 'Preencha os campos obrigatórios';\r\n\r\n input.classList.add('-emphasis')\r\n\r\n setTimeout(() => {\r\n\r\n alertMessage.classList.remove('-visible');\r\n alertMessage.innerText = '';\r\n\r\n input.classList.remove('-emphasis')\r\n\r\n }, 2000)\r\n\r\n },\r\n validateForm: function (vndaInput, form) {\r\n let submitAllowed = true;\r\n\r\n // Permite o envio se o input vnda estiver vazio\r\n if (vndaInput.value == '') {\r\n vndaInput.setAttribute('required', false);\r\n\r\n // Valida se os campos obrigatórios estão preenchidos\r\n const requiredFields = form.querySelectorAll('[required]:not([required=false])');\r\n requiredFields.forEach(input => {\r\n\r\n if (input.value == '') {\r\n submitAllowed = false;\r\n Webforms.showMessage(input, form);\r\n }\r\n\r\n if (input.type == 'checkbox' && input.checked == false) {\r\n submitAllowed = false;\r\n Webforms.showMessage(input, form);\r\n }\r\n\r\n })\r\n\r\n if (submitAllowed) form.id == 'form-notify' ? Webforms.submitNotify(form) : Webforms.submitWebForm(form)\r\n }\r\n },\r\n setWebForms: function () {\r\n const webForms = document.querySelectorAll('[data-webform]');\r\n\r\n webForms.length > 0 && webForms.forEach(form => {\r\n\r\n const button = form.querySelector('button');\r\n const fieldset = form.querySelector('fieldset');\r\n\r\n // Desabilita os campos do formulário, através do fieldset, quando o input vnda recebe algum valor \r\n let vndaInput = form.querySelector('input[name=\"vnda\"]');\r\n vndaInput.addEventListener('input', () => fieldset.setAttribute('disabled', true))\r\n\r\n // Realiza o envio através do clique e da tecla enter sobre o botão do formulário\r\n button && button.addEventListener('click', () => Webforms.validateForm(vndaInput, form));\r\n button && button.addEventListener('keypress', (e) => {\r\n if (e.key === 'Enter') Webforms.validateForm(vndaInput, form);\r\n })\r\n\r\n })\r\n },\r\n init: function () {\r\n const _this = this;\r\n _this.setWebForms();\r\n },\r\n};\r\n\r\nexport default Webforms;\r\n","import { addAsset } from './utilities';\r\n\r\n// ===============================================================\r\n// NEWSLETTER POPUP\r\n// ===============================================================\r\nexport const NewsletterComponent = {\r\n root: document.querySelector('#component-popup-newsletter-root'),\r\n settings: window.popupNewsletterSettings || false,\r\n loaded: false,\r\n observer: null,\r\n\r\n setPopupNewsletter: function () {\r\n const { settings, root } = NewsletterComponent;\r\n\r\n const componentNewsletterPopup = new Vnda.Component.NewsletterPopup({\r\n maxWidth: settings.maxWidth,\r\n maxHeight: 500,\r\n imageUrl: settings.imageUrl,\r\n imagePosition: 'left',\r\n popupPosition: 'center',\r\n title: settings.title,\r\n description: settings.description,\r\n extraDescription: settings.extraDescription,\r\n textBtnSubmit: 'Enviar',\r\n classBtnSubmit: 'button-newsletter',\r\n formKey: `${settings.subdomain}-newsletter`,\r\n hasNameField: false,\r\n hasLastNameField: false,\r\n hasDateOfBirthField: false,\r\n hasPhoneField: false,\r\n successMessage: settings.success,\r\n delay: 500,\r\n frequency: '7',\r\n language: 'pt-BR',\r\n placeholders: {\r\n email: 'Digite seu e-mail',\r\n },\r\n });\r\n\r\n componentNewsletterPopup.render(root);\r\n NewsletterComponent.loaded = true;\r\n },\r\n\r\n setPopupCupom: function (root) {\r\n const section = root.querySelector('.cmp-newsletter-popup-section');\r\n const close = root.querySelector('.close-button');\r\n const popup = document.querySelector('[data-popup-cupom]');\r\n\r\n if (!popup || !section || popup.dataset.initialized) {\r\n return;\r\n }\r\n\r\n const activatePopup = () => {\r\n popup.classList.add('-active');\r\n section.classList.remove('-active');\r\n };\r\n\r\n const deactivatePopup = () => {\r\n popup.classList.remove('-active');\r\n section.classList.add('-active');\r\n };\r\n\r\n const content = popup.querySelector('.text');\r\n if (content) {\r\n content.addEventListener('click', deactivatePopup);\r\n }\r\n\r\n if (close) {\r\n close.addEventListener('click', () => {\r\n console.log('Popup de cupom será ativado');\r\n setTimeout(activatePopup, 1000);\r\n });\r\n }\r\n\r\n section.addEventListener('click', (e) => {\r\n if (e.target.classList.contains('cmp-newsletter-popup-section') || e.target.classList.contains('close-button')) {\r\n activatePopup();\r\n }\r\n });\r\n\r\n // Marca o popup como configurado\r\n popup.dataset.initialized = true;\r\n },\r\n\r\n loadPopupNewsletter: function () {\r\n if (!NewsletterComponent.loaded) {\r\n const { settings } = NewsletterComponent;\r\n addAsset(settings.script, NewsletterComponent.setPopupNewsletter);\r\n addAsset(settings.styles);\r\n }\r\n },\r\n\r\n init: function () {\r\n const { root, settings } = this;\r\n\r\n if (!root || !settings) return;\r\n\r\n if (!this.observer) {\r\n this.observer = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === 'childList' || mutation.type === 'attributes') {\r\n this.setPopupCupom(root);\r\n }\r\n });\r\n });\r\n\r\n this.observer.observe(root, { attributes: true, childList: true, subtree: true });\r\n }\r\n\r\n const eventType = window.innerWidth <= 1024 ? 'scroll' : 'mousemove';\r\n window.addEventListener(\r\n eventType,\r\n () => {\r\n this.loadPopupNewsletter();\r\n },\r\n { once: true }\r\n );\r\n },\r\n};\r\n\r\n// ===============================================================\r\n// PREÇO\r\n// ===============================================================\r\n// Carrega o componente de preço quando um product-block ou product-infos entra em tela\r\nexport const PriceComponent = {\r\n script: window.priceComponent || false,\r\n loaded: false,\r\n\r\n init: function () {\r\n if (!PriceComponent.script) return;\r\n\r\n const productContainers = document.querySelectorAll('[data-product-box]');\r\n\r\n if (productContainers.length === 0) return;\r\n\r\n const observer = new IntersectionObserver(\r\n (entries) => {\r\n for (const entry of entries) {\r\n if (entry.isIntersecting) {\r\n if (!PriceComponent.loaded) {\r\n addAsset(PriceComponent.script);\r\n PriceComponent.loaded = true;\r\n }\r\n observer.disconnect();\r\n break;\r\n }\r\n }\r\n },\r\n { threshold: 0.1 }\r\n );\r\n\r\n productContainers.forEach((product) => {\r\n observer.observe(product);\r\n });\r\n },\r\n};\r\n","import LazyLoading from './common/lazyLoading';\r\nimport LoadPurchase from './common/loadPurchase.js';\r\nimport CartDrawer from './common/cartDrawer';\r\nimport Footer from './common/footer';\r\nimport Header from './common/header';\r\nimport Webforms from './common/webforms';\r\nimport { PriceComponent } from './components/vndaComponents.js';\r\nimport { setSearch, videoLazy } from './components/utilities';\r\nimport CustomNewsletter from './components/customNewsletter.js';\r\n\r\n// ==========================================\r\n// Inicialização\r\n// ==========================================\r\nconsole.log(\r\n '%cOlist - Soluções de vendas online e Serviços de E-commerce',\r\n 'color: #0a4ee4; font-size: 14px; font-family: \"Verdana\", sans-serif; font-weight: bold;'\r\n);\r\n\r\nwindow.addEventListener('DOMContentLoaded', () => {\r\n Header.init();\r\n LazyLoading.init();\r\n LoadPurchase.init();\r\n PriceComponent.init();\r\n CartDrawer.init();\r\n Footer.init();\r\n Webforms.init();\r\n CustomNewsletter.init();\r\n setSearch();\r\n videoLazy();\r\n});\r\n"],"names":[],"sourceRoot":""}