PageSourceSearch

https://www.nutrimuscle.com/cdn/shop/t/909/assets/kaching-tracking.js?v=67445985407997060781786608075

js nutrimuscle.com collected 2026-09-28 13:29:09 UTC 5,062 bytes, 2 lines download raw bytes

1class KachingTracking extends HTMLElement{#selectors={bundlesBlock:"kaching-bundles-block",bundlesBlockAlt:"kaching-bundle",bundleBar:".kaching-bundles__bar",price:".kaching-bundles__bar-price",compareAtPrice:".kaching-bundles__bar-full-price, .kaching-bundles__bar-compare-at-price",form:'form[action*="/cart/add"]'};#properties={discount:"__kaching_discount",percent:"__kaching_percent",uniqueId:"__kaching_unique_id"};#bundlesBlock=null;#form=null;#abortController=null;#renderObserver=null;#renderRaf=null;constructor(){super()}connectedCallback(){this.#init()}disconnectedCallback(){this.#cleanup()}#init(){if(this.#cacheElements(),!this.#isValidSetup()){this.#observerKaching();return}this.#setupEventListeners()}#cacheElements(){this.#bundlesBlock=document.querySelector(this.#selectors.bundlesBlock)||document.querySelector(this.#selectors.bundlesBlockAlt),this.#form=this.closest("form")||document.querySelector(this.#selectors.form)}#isValidSetup(){return!!(this.#bundlesBlock&&this.#form)}#observerKaching(){const observer=new MutationObserver(()=>{this.#cacheElements(),this.#isValidSetup()&&(this.#setupEventListeners(),observer.disconnect())});observer.observe(document.body,{childList:!0,subtree:!0})}#setupEventListeners(){this.#abortController&&this.#abortController.abort(),this.#abortController=new AbortController;const{signal}=this.#abortController;this.#bundlesBlock.addEventListener("variants-changed",e=>{requestAnimationFrame(()=>this.#handleUpdate(e.detail))},{signal}),this.#bundlesBlock.addEventListener("deal-bar-selected",e=>{requestAnimationFrame(()=>this.#handleUpdate(e.detail))},{signal}),this.#form.addEventListener("submit",()=>{setTimeout(()=>this.#handleUpdate(),100)},{signal}),this.#handleUpdate(),this.#renderObserver=new MutationObserver(()=>{this.#renderRaf||(this.#renderRaf=requestAnimationFrame(()=>{this.#renderRaf=null,this.#handleUpdate()}))}),this.#renderObserver.observe(this.#bundlesBlock,{childList:!0,subtree:!0})}#handleUpdate(detail={}){let prices=null;if(detail.pricing){const fullPriceObj=detail.pricing.fullPrice||detail.pricing.totalBeforeDiscount,discountedPriceObj=detail.pricing.discountedPrice||detail.pricing.totalAfterDiscount,getAmount=obj=>{if(typeof obj=="number")return obj/100;if(obj&&typeof obj=="object"){const val=obj.amount!==void 0?obj.amount:obj.value;return typeof val=="number"?val/100:parseFloat(val)/100}return NaN},compareAt=getAmount(fullPriceObj),price=getAmount(discountedPriceObj);!isNaN(price)&&!isNaN(compareAt)&&(prices={price,compareAt})}if(!prices){const selectedBar=this.#getSelectedBar();selectedBar&&(prices=this.#extractPrices(selectedBar))}if(!prices){this.#removeTrackingInputs();return}const discount=prices.compareAt-prices.price;if(discount<=0){this.#removeTrackingInputs();return}const percentage=discount/prices.compareAt*100;this.#updateTrackingInputs(discount,percentage)}#generateUniqueId(){return`${Date.now()}-${Math.random().toString(36).substr(2,9)}`}#getSelectedBar(){const bar=this.#selectors.bundleBar,directSelectors=[`${bar}--selected`,`${bar}.selected`,`${bar}.is-selected`,`${bar}[aria-checked="true"]`,`${bar}[data-selected]`,`${bar}[data-selected="true"]`];for(const sel of directSelectors){const el=this.#bundlesBlock.querySelector(sel);if(el)return el}const checkedInput=this.#bundlesBlock.querySelector(`${bar} input[type="radio"]:checked`);return checkedInput?checkedInput.closest(bar):null}#extractPrices(bar){const priceEl=bar.querySelector(this.#selectors.price),compareAtEl=bar.querySelector(this.#selectors.compareAtPrice);if(!priceEl)return null;const price=this.#parsePrice(priceEl.textContent),compareAt=compareAtEl?this.#parsePrice(compareAtEl.textContent):price;return isNaN(price)||isNaN(compareAt)?null:{price,compareAt}}#parsePrice(priceString){if(!priceString)return NaN;const cleaned=priceString.replace(/[^0-9,.]/g,"").replace(",",".");return parseFloat(cleaned)}#updateTrackingInputs(discount,percentage){this.#ensureInput(this.#properties.discount,discount.toFixed(2)),this.#ensureInput(this.#properties.percent,percentage.toFixed(2)),this.#ensureInput(this.#properties.uniqueId,this.#generateUniqueId())}#ensureInput(name,value){const inputName=`properties[${name}]`;let input=this.#form.querySelector(`input[name="${inputName}"]`);input||(input=document.createElement("input"),input.type="hidden",input.name=inputName,this.#form.appendChild(input)),input.value=value}
1#removeTrackingInputs(){Object.values(this.#properties).forEach(name=>{const input=this.#form.querySelector(`input[name="properties[${name}]"]`);input&&input.remove()})}#cleanup(){this.#abortController&&(this.#abortController.abort(),this.#abortController=null),this.#renderObserver&&(this.#renderObserver.disconnect(),this.#renderObserver=null),this.#renderRaf&&(cancelAnimationFrame(this.#renderRaf),this.#renderRaf=null),this.#removeTrackingInputs()}}customElements.get("kaching-tracking")||customElements.define("kaching-tracking",KachingTracking);
2//# sourceMappingURL=/cdn/shop/t/909/assets/kaching-tracking.js.map?v=67445985407997060781786608075

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.