1function gtag() 2{ 3 if(GMGA4.tagIds && !document.cookie.includes('_gm_no_track=_gm_no_track')) 4 dataLayer.push(arguments); 5 else 6 console.log(arguments); 7}; 8 9function facebookPixelEvent(eventName, params, eventID) 10{ 11 if (typeof fbq === 'undefined') 12 console.error("Error posting "+eventName+": fbq is undefined"); 13 else 14 fbq('track', eventName, params, {eventID: eventID}); 15}; 16 17function tiktokPixelEvent(eventName, identifyData, params, eventID) 18{ 19 if (typeof ttq === 'undefined') 20 console.error("Error posting "+eventName+": ttq is undefined"); 21 else { 22 ttq.identify(identifyData); 23 ttq.track(eventName, params, {event_id: eventID}); 24 } 25}; 26 27function redditPixelEvent(eventName, params) 28{ 29 if (typeof rdt === 'undefined') 30 console.error("Error posting Reddit Pixel event "+eventName+": rdt is undefined"); 31 else 32 rdt('track', eventName, params); 33} 34 35window.dataLayer = window.dataLayer || []; 36gtag('js', new Date()); 37for(const tagId of GMGA4.tagIds) 38 gtag('config', tagId); 39 40jQuery(document).ready(function($){ 41 function getValue(items) 42 { 43 var value = 0.0; 44 for(let i=0; i<items.length; i++) 45 value += items[i].price; 46 return value; 47 } 48 49 function getCart() 50 { 51 var cart = localStorage.getItem('GMGA4Cart'); 52 if(cart) 53 { 54 try 55 { 56 cart = JSON.parse(cart); 57 if(!( 58 'items' in cart && Array.isArray(cart['items']) && 59 'currency' in cart)) 60 { 61 localStorage.removeItem('GMGA4Cart'); 62 console.log("GMGA4Cart badly formed"); 63 } 64 } 65 catch(err) 66 { 67 localStorage.removeItem('GMGA4Cart'); 68 console.log("GMGA4Cart is invalid JSON"); 69 } 70 } 71 return cart; 72 } 73 74 // Handle item add/remove from cart 75 if(typeof GMGA4_IGNORE_CART === 'undefined') $('body').on( 76 'removed_from_cart added_to_cart updated_checkout', 77 function(event, fragments, hash) 78 { 79 var oldCurrency; 80 var oldCart = getCart(); 81 if(oldCart) 82 { 83 oldCurrency = oldCart.currency; 84 oldCart = oldCart.items; 85 } 86 else 87 oldCart = []; 88 89 if(event.type == 'updated_checkout') 90 fragments = fragments.fragments; 91 92 var newCart = fragments.GMGA4.items; 93 const newCurrency = fragments.GMGA4.currency; 94 localStorage.setItem('GMGA4Cart', JSON.stringify(fragments.GMGA4)); 95 96 // Filter out exact cart matches between new and old 97 var match = true; 98 while(match) 99 { 100 match = false; 101 for(let i=0; i<oldCart.length; i++) 102 { 103 for(let j=0; j<newCart.length; ++j) 104 if( 105 oldCart[i].item_id == newCart[j].item_id && 106 oldCart[i].price == newCart[j].price && 107 oldCart[i].coupon == newCart[j].coupon && 108 oldCart[i].discount == newCart[j].discount) 109 { 110 oldCart.splice(i, 1); 111 newCart.splice(j, 1); 112 match = true; 113 break 114 } 115 if(match) 116 break; 117 } 118 } 119 // Now filter out any soft cart matches between new and old 120 match = true; 121 while(match) 122 { 123 match = false; 124 for(let i=0; i<oldCart.length; i++) 125 { 126 for(let j=0; j<newCart.length; ++j) 127 if(oldCart[i].item_id == newCart[j].item_id) 128 { 129 oldCart.splice(i, 1); 130 newCart.splice(j, 1); 131 match = true; 132 break 133 } 134 if(match) 135 break; 136 } 137 } 138 139 // Anything left in the old cart was removed 140 if(oldCart.length>0) 141 gtag( 142 'event', 143 'remove_from_cart', 144 { 145 'currency': oldCurrency, 146 'value': getValue(oldCart), 147 'items': oldCart}); 148 149 // Anything left in the new cart was added 150 if(newCart.length>0) 151 gtag( 152 'event', 153 'add_to_cart', 154 { 155 'currency': newCurrency, 156 'value': getValue(newCart), 157 'items': newCart}); 158 } 159 ); 160 161 // Checkout steps 162 $('.next-step').click( 163 function() 164 { 165 var cart = getCart(); 166 if(!cart) 167 { 168 console.log("Doing checkout on empty cart!"); 169 return; 170 } 171 cart.value = getValue(cart.items); 172 173 switch(this.dataset.nextStep) 174 { 175 case 'delivery-content': 176 gtag('event', 'begin_checkout', cart); 177 break; 178 179 case 'payment-content': 180 cart.shipping_tier = 181 $("input.shipping_method[type=radio]:checked").val().split(':')[0]; 182 gtag('event', 'add_shipping_info', cart); 183 break; 184 185 case 'review-content': 186 cart.payment_type = 187 $("input[name=payment_method][type=radio]:checked").val(); 188 gtag('event', 'add_payment_info', cart); 189 break; 190 191 default: 192 console.log("Got invalid next step in checkout!"); 193 } 194 } 195 ); 196});
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.