1// Buy crypto menu on home page 2// Make functions globally available 3window.handleBuyButtonClick = function(coin, shouldScroll = false) { 4 updateCoinSelection(coin); 5 if (shouldScroll) { 6 document.getElementById('getting-started').scrollIntoView({ behavior: 'smooth' }); 7 } 8}; 9 10window.scrollToWidget = function() { 11 document.getElementById('getting-started').scrollIntoView({ behavior: 'smooth' }); 12}; 13 14// Crypto name mapping 15// Split multi-word crypto names on line 85 below 16const currencyNames = { 17 btc: 'Bitcoin (BTC)', 18 bch: 'Bitcoin Cash (BCH)', 19 eth: 'Ethereum (ETH)', 20 sol: 'Solana (SOL)', 21 usdt: 'Tether (USDT)', 22 usdc: 'USD Coin (USDC)', 23 ltc: 'Litecoin (LTC)', 24 doge: 'Dogecoin (DOGE)', 25 shib: 'Shiba Inu (SHIBA)', 26 pepe: 'Pepe (PEPE)', 27 ada: 'Cardano (ADA)', 28 pol: 'Polygon (POL)', 29 sui: 'Sui (SUI)', 30 wlfi: 'WLFI (WLFI)', 31 bnb: 'BNB (BNB)', 32 xrp: 'XRP (XRP)', 33}; 34 35function getUrlParameter(name) { 36 name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]'); 37 var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'); 38 var results = regex.exec(location.search); 39 return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' ')); 40} 41 42function updateGeminiUrl(coin, amount) { 43 const continueBtn = document.getElementById('continue-btn'); 44 if (continueBtn) { 45 const cleanAmount = parseFloat(amount.replace(/[^0-9.]/g, '')).toFixed(2); 46 const baseUrl = 'https://exchange.gemini.com/register'; 47 const params = new URLSearchParams({ 48 referral: 'fEU0MR', 49 type: 'referral', 50 symbol: coin, 51 amount: cleanAmount 52 }); 53 continueBtn.href = `${baseUrl}?${params.toString()}`; 54 } 55} 56 57function updateCoinSelection(coin) { 58 const coinSelect = document.getElementById('coin-select'); 59 if (coinSelect) { 60 coinSelect.value = coin; 61 62 const customSelect = document.querySelector('.custom-select'); 63 if (customSelect) { 64 const selectSelected = customSelect.querySelector('.select-selected'); 65 const selectItems = customSelect.querySelector('.select-items'); 66 67 const option = selectItems.querySelector(`div[data-value="${coin}"]`); 68 if (option) { 69 const text = option.querySelector('span').textContent; 70 const img = option.querySelector('img').src; 71 72 selectSelected.querySelector('img').src = img; 73 selectSelected.querySelector('span').textContent = text; 74 } 75 } 76 77 const continueBtn = document.getElementById('continue-btn'); 78 if (continueBtn) { 79 continueBtn.textContent = `Continue & Earn $50 Free`; 80 } 81 82 const amountDisplay = document.querySelector('.amount-display h1'); 83 if (amountDisplay) { 84 updateGeminiUrl(coin, amountDisplay.textContent); 85 } 86 87 // Split multi-word cryptocurrency names properly 88 let displayName; 89 switch(coin) { 90 case 'bch': 91 displayName = 'Bitcoin Cash'; 92 break; 93 case 'shib': 94 displayName = 'Shiba Inu'; 95 break; 96 case 'usdc': 97 displayName = 'USD Coin'; 98 break; 99 default: 100 displayName = coin === 'currency' ? 'Crypto' : (currencyNames[coin] || coin.toUpperCase()).split(' ')[0]; 101 } 102 document.querySelectorAll('.selected-coin-display').forEach(element => { 103 element.innerText = displayName; 104 }); 105 106 if (coin !== 'currency' && document.readyState === 'complete') { 107 const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}?crypto=${coin}`; 108 window.history.pushState({ path: newUrl }, '', newUrl); 109 } else if (coin === 'currency' && window.location.search.includes('crypto=')) { 110 const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}`; 111 window.history.pushState({ path: newUrl }, '', newUrl); 112 } 113 } 114} 115 116function setupAmountButtons() { 117 const amountButtons = document.querySelectorAll('.amount-btn'); 118 const amountDisplay = document.querySelector('.amount-display h1'); 119
120 function formatAmount(amount) { 121 const num = parseInt(amount.replace(/[^0-9]/g, '')); 122 return `$${num.toFixed(2)}`; 123 } 124 125 amountButtons.forEach(button => { 126 button.addEventListener('click', function() { 127 amountButtons.forEach(btn => btn.classList.remove('active')); 128 this.classList.add('active'); 129 130 if (amountDisplay) { 131 const formattedAmount = formatAmount(this.textContent); 132 amountDisplay.textContent = formattedAmount; 133 134 const coinSelect = document.getElementById('coin-select'); 135 if (coinSelect) { 136 updateGeminiUrl(coinSelect.value, formattedAmount); 137 } 138 } 139 }); 140 }); 141 142 if (amountDisplay && amountButtons.length > 0) { 143 const activeButton = amountButtons[0]; 144 const formattedAmount = formatAmount(activeButton.textContent); 145 amountDisplay.textContent = formattedAmount; 146 147 const coinSelect = document.getElementById('coin-select'); 148 if (coinSelect) { 149 updateGeminiUrl(coinSelect.value, formattedAmount); 150 } 151 } 152} 153 154function initializeCustomSelect(cryptoParam = null) { 155 const customSelect = document.querySelector('.custom-select'); 156 if (!customSelect) return; 157 158 const selectSelected = customSelect.querySelector('.select-selected'); 159 const selectItems = customSelect.querySelector('.select-items'); 160 const select = customSelect.querySelector('select'); 161 let closeTimeout = null; 162 let touchStartY = 0; 163 let isScrolling = false; 164 let touchStartTime = 0; 165 let isInitializing = true; 166 167 const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0; 168 const getDelay = () => isTouchDevice ? 500 : 0; 169 170 function toggleDropdown(e) { 171 if (e) { 172 e.preventDefault(); 173 e.stopPropagation(); 174 } 175 selectItems.classList.toggle('select-hide'); 176 selectSelected.classList.toggle('select-arrow-active'); 177 } 178 179 function handleOptionSelect(div) { 180 if (closeTimeout) { 181 clearTimeout(closeTimeout); 182 } 183 184 const value = div.getAttribute('data-value'); 185 const text = div.querySelector('span').textContent; 186 const img = div.querySelector('img').src; 187 188 if (isTouchDevice) { 189 closeTimeout = setTimeout(() => { 190 selectItems.classList.add('select-hide'); 191 selectSelected.classList.remove('select-arrow-active'); 192 193 select.value = value; 194 selectSelected.querySelector('img').src = img; 195 selectSelected.querySelector('span').textContent = text; 196 197 const event = new Event('change'); 198 select.dispatchEvent(event); 199 }, getDelay()); 200 } else { 201 selectItems.classList.add('select-hide'); 202 selectSelected.classList.remove('select-arrow-active'); 203 204 select.value = value; 205 selectSelected.querySelector('img').src = img; 206 selectSelected.querySelector('span').textContent = text; 207 208 const event = new Event('change'); 209 select.dispatchEvent(event); 210 } 211 } 212 213 if (isTouchDevice) { 214 selectItems.addEventListener('touchstart', function(e) { 215 touchStartY = e.touches[0].clientY; 216 touchStartTime = Date.now(); 217 isScrolling = false; 218 }, { passive: true }); 219 220 selectItems.addEventListener('touchmove', function(e) { 221 const touchY = e.touches[0].clientY; 222 const diff = touchStartY - touchY; 223 if (Math.abs(diff) > 5) { 224 isScrolling = true; 225 } 226 }, { passive: true }); 227 228 selectItems.querySelectorAll('div').forEach(div => { 229 div.addEventListener('touchend', function(e) { 230 e.preventDefault(); 231 e.stopPropagation(); 232 const touchDuration = Date.now() - touchStartTime; 233 if (!isScrolling && touchDuration < 200) { 234 handleOptionSelect(this); 235 } 236 }); 237 }); 238 239 selectSelected.addEventListener('touchend', function(e) { 240 e.preventDefault(); 241 e.stopPropagation(); 242 toggleDropdown(e); 243 }); 244 245 selectSelected.addEventListener('touchstart', function(e) { 246 e.preventDefault(); 247 }, { passive: false }); 248 } 249 250 selectSelected.addEventListener('click', function(e) { 251 e.preventDefault(); 252 e.stopPropagation(); 253 toggleDropdown(e); 254 });
255 256 selectItems.querySelectorAll('div').forEach(div => { 257 div.addEventListener('click', function(e) { 258 e.preventDefault(); 259 e.stopPropagation(); 260 handleOptionSelect(this); 261 }); 262 }); 263 264 document.addEventListener('click', function(e) { 265 if (!customSelect.contains(e.target)) { 266 if (closeTimeout) { 267 clearTimeout(closeTimeout); 268 } 269 270 if (isTouchDevice) { 271 closeTimeout = setTimeout(() => { 272 selectItems.classList.add('select-hide'); 273 selectSelected.classList.remove('select-arrow-active'); 274 }, 400); 275 } else { 276 selectItems.classList.add('select-hide'); 277 selectSelected.classList.remove('select-arrow-active'); 278 } 279 } 280 }); 281 282 if (cryptoParam) { 283 const option = selectItems.querySelector(`div[data-value="${cryptoParam}"]`); 284 if (option) { 285 handleOptionSelect(option); 286 } 287 } else { 288 const firstOption = selectItems.querySelector('div'); 289 if (firstOption) { 290 const value = firstOption.getAttribute('data-value'); 291 const text = firstOption.querySelector('span').textContent; 292 const img = firstOption.querySelector('img').src; 293 294 select.value = value; 295 selectSelected.querySelector('img').src = img; 296 selectSelected.querySelector('span').textContent = text; 297 } 298 } 299 300 select.addEventListener('change', function() { 301 if (!isInitializing) { 302 updateCoinSelection(this.value); 303 } 304 }); 305 306 setTimeout(() => { 307 isInitializing = false; 308 }, 100); 309 310 window.addEventListener('beforeunload', function() { 311 if (closeTimeout) { 312 clearTimeout(closeTimeout); 313 } 314 }); 315} 316 317document.addEventListener('DOMContentLoaded', function() { 318 const cryptoParam = getUrlParameter('crypto'); 319 setupAmountButtons(); 320 initializeCustomSelect(cryptoParam); 321 updateCoinSelection(cryptoParam || 'currency'); 322 323 if (!cryptoParam) { 324 document.querySelectorAll('.selected-coin-display').forEach(element => { 325 element.innerText = 'Crypto'; 326 }); 327 } 328});
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.