Gold Calculator
}
}
function calc(){
const spot = Number($('spot').value) || 0; // $/ozt
const karat = Number($('karat').value) || 24;
const lengthMM = toMM($('length').value, $('lengthUnit').value);
const diaMM = toMM($('diameter').value, $('diameterUnit').value);
const premiumPct = Number($('premium').value) || 0; // +/- %
const qty = Math.max(1, Math.floor(Number($('qty').value)||1));
const radiusMM = diaMM / 2;
const areaMM2 = Math.PI * Math.pow(radiusMM, 2);
const volMM3 = areaMM2 * lengthMM; // mm^3
const volCM3 = volMM3 / 1000; // 1000 mm^3 = 1 cm^3
const GOLD_DENSITY = 19.32; // g/cm3 (pure)
const weightG = volCM3 * GOLD_DENSITY; // approximate total mass
const purity = Math.min(24, Math.max(0, karat)) / 24; // 0..1
const pureG = weightG * purity; // grams of pure gold
const perGram = (spot > 0) ? (spot / 31.1034768) : 0; // $/g
const baseValue = pureG * perGram; // value at spot for the gold content
const priceOne = baseValue * (1 + premiumPct/100);
const priceTotal = priceOne * qty;
$('weight').textContent = fmt(weightG, 3) + ' g';
$('pure').textContent = fmt(pureG, 3) + ' g';
$('value').textContent = formatUSD(baseValue);
$('price').textContent = formatUSD(priceTotal);
$('qty').value = qty; // normalize
}
inputs.forEach(el => el.addEventListener('input', calc));
calc();
\/\/ Live spot price fetching from server-side proxy
let timer = null;
async function fetchSpotOnce(){
try{
const res = await fetch('\/api\/spot', {cache:'no-store'});
if(!res.ok) throw new Error('HTTP '+res.status);
const data = await res.json();
const price = Number(data.price_per_ozt || data.price || data.usd_per_ozt || data.XAUUSD);
if(Number.isFinite(price) && price>0){
$('spot').value = price.toFixed(2);
calc();
}
}catch(err){
console.warn('Spot fetch failed:', err);
}
}
function startLive(){
const secs = Math.max(10, Math.floor(Number($('interval').value)||60));
clearInterval(timer);
fetchSpotOnce();
timer = setInterval(fetchSpotOnce, secs*1000);
}
function stopLive(){ clearInterval(timer); timer=null; }
$('autoUpdate').addEventListener('change', (e)=>{ e.target.checked ? startLive() : stopLive(); });
$('interval').addEventListener('input', ()=>{ if($('autoUpdate').checked) startLive(); });
// Copy embed code (minimal)
const copyBtn = $('copyBtn');
const copyState = $('copyState');
copyBtn.addEventListener('click', function(e){
e.preventDefault();
const embed = document.documentElement.outerHTML;
navigator.clipboard.writeText(embed).then(()=>{
copyState.textContent = 'Copied! Paste into your site.';
setTimeout(()=> copyState.textContent = '', 3000);
}).catch(()=>{
copyState.textContent = 'Press Ctrl/Cmd+C to copy.';
setTimeout(()=> copyState.textContent = '', 3000);
});
});
})();