1function extractMoneyNumbers(text) { 2 const matches = text.match(/\d[\d,]*\.?\d*/g); 3 return matches ? matches.map(num => parseFloat(num.replace(/,/g, ''))) : []; 4} 5 6function ccDisPerPpV2() { 7 let lastSaleText = ''; 8 let lastSaveText = ''; 9 10 function updateDiscount() { 11 const $target = $('.productView-priceShareWrapper .productView-price'); 12 if (!$target.length) return; 13 14 const saleText = $($('[data-product-price-with-tax]')[0]).text().trim(); 15 const saveText = $($('[data-product-price-saved]')[0]).text().trim(); 16 const oriText = $('[data-product-rrp-price-with-tax]').first().text().trim(); 17 18 if (saleText === lastSaleText && saveText === lastSaveText) return; 19 20 lastSaleText = saleText; 21 lastSaveText = saveText; 22 23 const saleNums = extractMoneyNumbers(saleText); 24 const saveNums = extractMoneyNumbers(saveText); 25 26 let discountHtml = ''; 27 28 if (saleNums.length === 1 && saveNums.length === 1) { 29 const sale = saleNums[0]; 30 const save = saveNums[0]; 31 const original = sale + save; 32 33 $('[data-product-rrp-price-with-tax]').text(`$${original.toFixed(2)}`); 34 35 if (original > sale) { 36 const percent = Math.round((save / original) * 100); 37 38 discountHtml += ` 39 <div class="cc-discount-pp--24587577"> 40 You Save <b>$${save.toFixed(2)}</b> <div>${percent}%</div> 41 </div> 42 `; 43 } 44 45 } else if (saleNums.length >= 1 && oriText) { 46 const oriNums = extractMoneyNumbers(oriText); 47 const pairs = []; 48 49 if (saleNums.length === 1 && oriNums.length === 1) { 50 pairs.push({ 51 sale: saleNums[0], 52 original: oriNums[0] 53 }); 54 } else if (saleNums.length >= 2 && oriNums.length >= 2) { 55 pairs.push( 56 { 57 sale: saleNums[0], 58 original: oriNums[0] 59 }, 60 { 61 sale: saleNums[saleNums.length - 1], 62 original: oriNums[oriNums.length - 1] 63 } 64 ); 65 } 66 67 const saves = []; 68 let percent = 0; 69 70 pairs.forEach(({ sale, original }) => { 71 if (original > sale) { 72 saves.push(original - sale); 73 percent = Math.max( 74 percent, 75 Math.round(((original - sale) / original) * 100) 76 ); 77 } 78 }); 79 80 if (saves.length) { 81 const minSave = Math.min(...saves).toFixed(2); 82 const maxSave = Math.max(...saves).toFixed(2); 83 84 discountHtml = ` 85 <div class="cc-discount-pp--24587577"> 86 You Save <b>$${minSave}${minSave !== maxSave ? ` - $${maxSave}` : ''}</b> <div>${percent}%</div> 87 </div> 88 `; 89 } 90 } 91 92 $target.find('.cc-discount-pp--24587577').remove(); 93 94 if (discountHtml) { 95 $target.css('display', 'block').append(discountHtml); 96 } 97 } 98 99 updateDiscount(); 100 setInterval(updateDiscount, 2000); 101} 102 103if ( 104 $('.productView-priceShareWrapper [data-product-rrp-price-with-tax]').length || 105 $('.productView-priceShareWrapper [data-product-rrp-with-tax]').length 106) { 107 const priceSection = $('.price-section.price-section--withTax.rrp-price--withTax'); 108 109 if (priceSection.css('display') !== 'none') { 110 $('.productView-priceShareWrapper').addClass('ccCustomCss7577'); 111 ccDisPerPpV2(); 112 } 113} 114 115function ccDisPerCpV2() { 116 $('#product-listing-container .productGrid .product').each(function () { 117 const thisProduct = $(this); 118 119 if (thisProduct.find('.cc-discount-cp--24587577').length) return; 120 121 const ccSalePriceEl = thisProduct.find('[data-product-price-with-tax]'); 122 const ccOriPriceEl = thisProduct.find('[data-product-rrp-with-tax], [data-product-rrp-price-with-tax]'); 123 124 if (!ccSalePriceEl.length || !ccOriPriceEl.length) return; 125 126 const ccSaleText = ccSalePriceEl.text().trim(); 127 const ccOriText = ccOriPriceEl.text().trim(); 128 129 const saleNumbers = extractMoneyNumbers(ccSaleText); 130 const oriNumbers = extractMoneyNumbers(ccOriText); 131 132 if (!saleNumbers.length || !oriNumbers.length) return; 133 134 let discountHtml = ''; 135 const pairs = []; 136 137 if (saleNumbers.length === 1 && oriNumbers.length === 1) { 138 pairs.push({
139 sale: saleNumbers[0], 140 original: oriNumbers[0] 141 }); 142 } else if (saleNumbers.length >= 2 && oriNumbers.length >= 2) { 143 pairs.push( 144 { 145 sale: Math.min(...saleNumbers), 146 original: Math.min(...oriNumbers) 147 }, 148 { 149 sale: Math.max(...saleNumbers), 150 original: Math.max(...oriNumbers) 151 } 152 ); 153 } 154 155 const saves = []; 156 let percent = 0; 157 158 pairs.forEach(({ sale, original }) => { 159 if (original > sale) { 160 saves.push(original - sale); 161 percent = Math.max( 162 percent, 163 Math.round(((original - sale) / original) * 100) 164 ); 165 } 166 }); 167 168 if (saves.length) { 169 const minSave = Math.min(...saves).toFixed(2); 170 const maxSave = Math.max(...saves).toFixed(2); 171 172 discountHtml = ` 173 <div class="cc-discount-cp--24587577"> 174 You Save <b>$${minSave}${minSave !== maxSave ? ` - $${maxSave}` : ''}</b> <div>${percent}%</div> 175 </div> 176 `; 177 } 178 179 if (discountHtml) { 180 thisProduct.find('.card-body div.card-text').after(discountHtml); 181 } 182 }); 183} 184 185setInterval(() => { 186 ccDisPerCpV2(); 187}, 1000); 188 189if ($('.page-type-product').length) { 190 const $allRewardCtas = $('div[onclick*="zrl_mi.dashboard_clicked"]'); 191 192 if ($allRewardCtas.length) { 193 const $rewardCta = $allRewardCtas.first().detach(); 194 195 $allRewardCtas.slice(1).remove(); 196 197 $('.productView-priceShareWrapper .price-section--main div[onclick*="zrl_mi.dashboard_clicked"]').remove(); 198 $('.productView-priceShareWrapper .price-section--main').append($rewardCta); 199 } 200}
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.