1(function () { 2 function getCookie(key, defaultValue = null) { 3 const cookies = document.cookie.split('; ').reduce((acc, cookie) => { 4 const [cookieKey, cookieValue] = cookie.split('='); 5 acc[decodeURIComponent(cookieKey)] = decodeURIComponent(cookieValue); 6 return acc; 7 }, {}); 8 9 return cookies.hasOwnProperty(key) ? cookies[key] : defaultValue; 10 } 11 12 function setCookie(key, value, expirationInSeconds, path = '/') { 13 const expires = new Date(Date.now() + expirationInSeconds * 1000).toUTCString(); 14 document.cookie = `${encodeURIComponent(key)}=${encodeURIComponent(value)}; expires=${expires}; path=${path}`; 15 } 16 17 function clearCookie(key, path = '/') { 18 document.cookie = `${encodeURIComponent(key)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}`; 19 } 20 21 function hasValidAffiliateOverwrite(value) { 22 return value != null && value !== '' && value !== 'undefined' && value !== 'null'; 23 } 24 25 function encodeAffiliateParams(affiliate, entryUrl, affiliateOverwrite, affiliateSource) { 26 return { 27 aff: window.btoa(affiliate), 28 entryUrl: window.btoa(entryUrl), 29 affiliateOverwrite: hasValidAffiliateOverwrite(affiliateOverwrite) ? window.btoa(affiliateOverwrite) : null, 30 affSource: affiliateSource != null && affiliateSource !== '' ? window.btoa(affiliateSource) : null, 31 }; 32 } 33 34 function isValidUrl(url) { 35 return ( 36 typeof url === 'string' && 37 url.includes(location.hostname) && 38 !url.includes('legal') && 39 !url.includes('wp-login') && 40 !url.includes('wp-admin') 41 ); 42 } 43 44 function appendAffiliateParams(url, { aff, entryUrl, affiliateOverwrite, affSource }) { 45 const originalUrl = url; 46 const parsedUrl = new URL(url, location.origin); 47 const isRelativeUrl = !/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(originalUrl); 48 49 if (!parsedUrl.searchParams.has('aff')) { 50 parsedUrl.searchParams.set('aff', aff); 51 } 52 53 if (!parsedUrl.searchParams.has('entryUrl')) { 54 parsedUrl.searchParams.set('entryUrl', entryUrl); 55 } 56 57 if (!parsedUrl.searchParams.has('affOverwrite') && hasValidAffiliateOverwrite(affiliateOverwrite)) { 58 parsedUrl.searchParams.set('affOverwrite', affiliateOverwrite); 59 } else if (!parsedUrl.searchParams.has('affOverwrite')) { 60 parsedUrl.searchParams.delete('affOverwrite'); 61 } 62 63 if (affSource != null && affSource !== '' && !parsedUrl.searchParams.has('affSource')) { 64 parsedUrl.searchParams.set('affSource', affSource); 65 } 66 67 if (isRelativeUrl) { 68 return `${parsedUrl.pathname}${parsedUrl.search}${parsedUrl.hash}`; 69 } 70 71 return parsedUrl.toString(); 72 } 73 74 function addAffiliateParamToLinks() { 75 if (!window.affiliate) return; 76 77 const links = [...document.getElementsByTagName('a')]; 78 const encodedAffiliate = encodeAffiliateParams( 79 window.affiliate, 80 window.entry_url, 81 window.affiliateOverwrite, 82 window.affiliateSource 83 ); 84 85 links.forEach((link) => { 86 let url = link.getAttribute('href')?.trim(); 87 88 if (!isValidUrl(url)) return; 89 90 link.setAttribute('href', appendAffiliateParams(url, encodedAffiliate)); 91 }); 92 } 93 94 function decodeQueryParam(param) { 95 const value = new URLSearchParams(location.search).get(param); 96 97 if (!value) { 98 return null; 99 } 100 101 let decoded = value; 102 try { 103 decoded = window.atob(decodeURIComponent(value)); 104 } catch (e) { 105 return null; // not base64 106 } 107 108 try { 109 return decodeURIComponent(decoded); 110 } catch (e) { 111 return decoded; 112 } 113 } 114 115 function initEntryUrl() { 116 const entryUrlFromCookie = getCookie('entrypoint_url');
117 const entryUrlFromParams = decodeQueryParam('entryUrl'); 118 119 window.entry_url = entryUrlFromCookie || entryUrlFromParams || location.pathname; 120 121 if (!entryUrlFromCookie) { 122 setCookie('entrypoint_url', window.entry_url, 60 * 25); // 25 minutes 123 } 124 } 125 126 function initAffiliateTag() { 127 const { direct, productPack } = info; 128 129 const currentAffCookie = getCookie('affiliate_tag'); 130 const affFromParams = decodeQueryParam('aff'); 131 const affiliateOverwrite = decodeQueryParam('affOverwrite') ?? null; 132 window.affiliate = productPack || affFromParams || currentAffCookie || direct; 133 134 if (productPack !== affFromParams && !affiliateOverwrite) { 135 window.affiliateOverwrite = affFromParams; 136 setCookie('affiliate_overwrite', window.affiliateOverwrite, 86400 * 30); 137 } 138 139 if (affiliateOverwrite !== null) { 140 window.affiliateOverwrite = affiliateOverwrite; 141 setCookie('affiliate_overwrite', window.affiliateOverwrite, 86400 * 30); 142 } 143 144 setCookie('affiliate_tag', window.affiliate, 86400 * 30); // 30 days 145 146 const affSourceFromParams = decodeQueryParam('affSource'); 147 if (affSourceFromParams) { 148 window.affiliateSource = affSourceFromParams; 149 setCookie('affiliate_source', window.affiliateSource, 86400 * 30); 150 } else { 151 window.affiliateSource = ''; 152 clearCookie('affiliate_source'); 153 } 154 } 155 156 function runAffiliateTagging() { 157 initEntryUrl(); 158 initAffiliateTag(); 159 addAffiliateParamToLinks(); 160 } 161 162 if (!window.deferAffiliateAutoRun) { 163 if (document.readyState === 'complete' || document.readyState === 'interactive') { 164 runAffiliateTagging(); 165 } else { 166 document.addEventListener('DOMContentLoaded', runAffiliateTagging); 167 } 168 } 169 170 window.runAffiliateTagging = runAffiliateTagging; 171})();
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.