(function() { var C = window.ExplorerCommon; var state = { tab: 'fungible' }; function switchTab(name) { state.tab = name; document.getElementById('paneFungible').style.display = name === 'fungible' ? '' : 'none'; document.getElementById('paneNFT').style.display = name === 'nft' ? '' : 'none'; document.getElementById('tabFungible').className = 'tx-tab' + (name === 'fungible' ? ' tx-tab-active' : ''); document.getElementById('tabNFT').className = 'tx-tab' + (name === 'nft' ? ' tx-tab-active' : ''); } /* ── Fungible tokens ─────────────────────────────────────────────────────── */ function formatSupply(supply, decimals) { if (decimals === 0) return supply.toLocaleString(); var d = Math.pow(10, decimals); var whole = Math.floor(supply / d); var frac = supply % d; if (frac === 0) return whole.toLocaleString(); return whole.toLocaleString() + '.' + String(frac).padStart(decimals, '0').replace(/0+$/, ''); } async function loadTokens() { C.setStatus('Loading…', 'warn'); try { var data = await C.fetchJSON('/api/tokens'); var tokens = (data && Array.isArray(data.tokens)) ? data.tokens : []; document.getElementById('tokenCount').textContent = tokens.length; var tbody = document.getElementById('tokenBody'); if (!tokens.length) { tbody.innerHTML = 'No fungible tokens issued yet.'; } else { var rows = ''; tokens.forEach(function(t, i) { var supply = formatSupply(t.total_supply || 0, t.decimals || 0); rows += '' + '' + (i+1) + '' + '' + '' + C.esc(t.symbol) + '' + '' + '' + C.esc(t.name) + '' + '' + (t.decimals || 0) + '' + '' + C.esc(supply) + '' + '' + '' + C.short(t.issuer, 20) + '' + '' + '' + (t.issued_at || 0) + '' + ''; }); tbody.innerHTML = rows; } C.refreshIcons(); } catch(e) { C.setStatus('Load failed: ' + e.message, 'err'); } } /* ── NFTs ────────────────────────────────────────────────────────────────── */ async function loadNFTs() { try { var data = await C.fetchJSON('/api/nfts'); var nfts = (data && Array.isArray(data.nfts)) ? data.nfts : []; document.getElementById('nftCount').textContent = nfts.length; var grid = document.getElementById('nftGrid'); var empty = document.getElementById('nftEmpty'); if (!nfts.length) { grid.innerHTML = ''; empty.style.display = ''; return; } empty.style.display = 'none'; var cards = ''; nfts.forEach(function(n) { var burned = n.burned ? ' nft-card-burned' : ''; var imgHtml = ''; if (n.uri && /\.(png|jpg|jpeg|gif|svg|webp)/i.test(n.uri)) { imgHtml = ''; } else { imgHtml = '
'; } cards += '' + imgHtml + '
' + '
' + C.esc(n.name) + (n.burned ? ' BURNED' : '') + '
' + '
' + C.short(n.nft_id, 16) + '
' + (n.owner ? '
Owner: ' + C.short(n.owner, 16) + '
' : '') + '
' + '
'; }); grid.innerHTML = cards; C.refreshIcons(); } catch(e) { document.getElementById('nftCount').textContent = '?'; } } /* ── Boot ────────────────────────────────────────────────────────────────── */ document.getElementById('tabFungible').addEventListener('click', function() { switchTab('fungible'); }); document.getElementById('tabNFT').addEventListener('click', function() { switchTab('nft'); }); document.getElementById('refreshBtn').addEventListener('click', function() { loadTokens(); loadNFTs(); }); // Check URL hash for tab. if (window.location.hash === '#nft') switchTab('nft'); Promise.all([loadTokens(), loadNFTs()]).then(function() { C.setStatus('', ''); }); })();