// Network Intelligence client — renders the pooled, anonymised ad results. (function () { 'use strict'; var $ = function (id) { return document.getElementById(id); }; function esc(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); } function n(v) { return Number(v || 0).toLocaleString(); } function pct(r) { return (Number(r || 0) * 100).toFixed(3) + '%'; } function gate(msg) { $('iLoading').style.display = 'none'; $('iGate').style.display = 'block'; $('iGate').innerHTML = msg; } function tile(v, label, cls) { return '
' + v + '
' + label + '
'; } function section(title, why, group, unitLabel) { if (!group || !group.rows.length) return ''; var top = group.rows[0].rate || 1; var rows = group.rows.map(function (r) { var w = Math.max(2, Math.round((r.rate / top) * 100)); return '' + esc(r.label) + '' + '' + n(r.served) + '' + '' + n(r.clicks) + '' + '' + pct(r.rate) + '' + '
'; }).join(''); var thin = group.thin ? '
' + group.thin + ' more not shown — under the evidence threshold (' + n(group.thinServed) + ' impressions between them).
' : ''; return '

' + esc(title) + '

' + esc(why) + '
' + '
' + rows + '
' + esc(unitLabel) + 'ServedClicksRate
' + thin + '
'; } function render(d) { var rep = d.report; $('iLoading').style.display = 'none'; if (!rep || !rep.ready) { gate('Not enough data yet. ' + esc((rep && rep.reason) || 'This fills in as the team advertises.')); return; } $('iBody').style.display = 'block'; $('iTiles').innerHTML = tile(n(rep.totals.ads), 'team ads measured', 'cool') + tile(n(rep.totals.served), 'impressions served') + tile(n(rep.totals.clicks), 'clicks', 'cool') + tile(pct(rep.totals.rate), 'network click rate'); $('iReadout').innerHTML = (d.readout || []).map(function (line) { return '
' + esc(line) + '
'; }).join('') || '
Not enough evidence yet to draw conclusions.
'; var html = ''; html += section('Format', 'Text placements against banner placements, across everything the team has run.', rep.format, 'Format'); html += section('Angle', 'Which hook the destination link carried. This is the one worth acting on — it tells you what to lead with everywhere, not just in ads.', rep.angle, 'Angle'); html += section('Banner creative', 'Which designs from the team kit are actually earning their impressions.', rep.creative, 'Design'); html += section('Banner size', 'Placement size, pooled across every design.', rep.size, 'Size'); html += section('Text ad headlines', 'Individual headlines that have run enough to be judged.', rep.headline, 'Headline'); $('iSections').innerHTML = html || '
Nothing has crossed the evidence threshold yet. Keep the ads running.
'; } async function boot() { try { var r = await fetch('/api/public/suite-intel'); if (r.status === 401) { gate('You’re not signed in yet. Open the Suite and connect the wallet that holds your position, then come back.'); return; } if (r.status === 403) { var g = await r.json(); gate((g.error || 'Not open for this position yet.') + ' See your Suite.'); return; } if (!r.ok) { gate('Could not read the network just now — try again shortly.'); return; } render(await r.json()); } catch (e) { gate('Connection hiccup — reload to try again.'); } } document.addEventListener('DOMContentLoaded', boot); })();