Research-Stack/python/universal_encoder.html
Allaun Silverfox 5a4fe52a8a feat(html5): Universal encoder bundle — any host, any device
Self-contained HTML5 file that demonstrates the full pipeline:
  QUBO → Brute-Force Solve → Pixel Encoding → PNG Receipt → Decode

Works on any web host on Earth. No WebGPU. No backend. Just canvas.

Stages:
1. Generate random 8-variable QUBO (banded, diagonal-dominant)
2. Brute-force solve (256 solutions, instant for n=8)
3. Encode solution as 8×8 Hachimoji pixel grid
   - x=0 → dark pixel (Φ, rgb 13,13,13)
   - x=1 → bright pixel (Σ, rgb 26,204,77)
4. Generate PNG receipt (canvas.toDataURL)
5. Decode receipt back from image (verify roundtrip)

Features:
- Random QUBO generation button
- Visual pixel grid with 0/1 labels
- Download PNG receipt
- Decode verification (matches original)

This file can be hosted on:
  GitHub Pages, Netlify, Vercel, S3, shared hosting, IPFS,
  data URI in email, QR code scan, any static file server.

The receipt IS the image. The image IS the solution.

Refs: FBTTY_UNIVERSAL_ENCODER.md (theory),
WEBGPU_PIXEL_ENCODER.md (GPU compute version)
2026-06-23 01:36:35 -05:00

287 lines
8.3 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SilverSight Universal Encoder — QUBO → Pixels → Receipt</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Courier New', monospace;
background: #0a0a0a;
color: #0f0;
display: flex;
flex-direction: column;
align-items: center;
padding: 2em;
min-height: 100vh;
}
h1 { color: #0ff; margin-bottom: 0.5em; font-size: 1.4em; }
.subtitle { color: #888; margin-bottom: 2em; font-size: 0.85em; }
.stage {
background: #111;
border: 1px solid #333;
border-radius: 4px;
padding: 1.5em;
margin: 0.5em 0;
width: 100%;
max-width: 600px;
}
.stage h2 { color: #ff0; font-size: 1em; margin-bottom: 0.5em; }
.stage pre { color: #0f0; font-size: 0.8em; overflow-x: auto; }
canvas {
image-rendering: pixelated;
border: 2px solid #0f0;
margin: 1em 0;
}
.receipt {
background: #1a1a1a;
border: 1px solid #0f0;
padding: 1em;
font-size: 0.75em;
color: #0f0;
}
.receipt img { max-width: 100%; image-rendering: pixelated; }
button {
background: #0f0;
color: #000;
border: none;
padding: 0.5em 1em;
font-family: inherit;
font-weight: bold;
cursor: pointer;
margin: 0.5em;
}
button:hover { background: #0ff; }
.grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
.pixel {
width: 30px; height: 30px;
display: flex; align-items: center; justify-content: center;
font-size: 0.6em; color: #000; font-weight: bold;
}
.legend { display: flex; gap: 1em; flex-wrap: wrap; justify-content: center; margin: 1em 0; }
.legend-item { display: flex; align-items: center; gap: 0.3em; font-size: 0.75em; }
.legend-box { width: 15px; height: 15px; border: 1px solid #444; }
</style>
</head>
<body>
<h1>SilverSight Universal Encoder</h1>
<p class="subtitle">Matrix math = Pixels = Any framebuffer. Any web host. Any device.</p>
<!-- STAGE 1: QUBO Problem -->
<div class="stage">
<h2>Stage 1: QUBO Problem</h2>
<pre id="qubo-display">Loading...</pre>
<button onclick="generateNewQUBO()">New Random QUBO</button>
</div>
<!-- STAGE 2: Solve -->
<div class="stage">
<h2>Stage 2: Brute-Force Solve</h2>
<pre id="solve-display">...</pre>
</div>
<!-- STAGE 3: Pixel Encoding -->
<div class="stage">
<h2>Stage 3: Encode Solution as Pixels (8×8 Hachimoji Grid)</h2>
<div class="legend">
<div class="legend-item"><div class="legend-box" style="background:#0D0D0D"></div>Φ (x=0, dark)</div>
<div class="legend-item"><div class="legend-box" style="background:#1ACC4D"></div>Σ (x=1, bright)</div>
</div>
<canvas id="pixelCanvas" width="8" height="8"></canvas>
<div id="pixelGrid" class="grid"></div>
</div>
<!-- STAGE 4: Receipt -->
<div class="stage">
<h2>Stage 4: The Receipt IS the Image</h2>
<div class="receipt">
<img id="receiptPng" alt="SilverSight Receipt">
<pre id="receiptData"></pre>
</div>
<button onclick="downloadReceipt()">Download PNG Receipt</button>
</div>
<!-- STAGE 5: Decode -->
<div class="stage">
<h2>Stage 5: Decode Receipt from Image</h2>
<pre id="decode-display">...</pre>
</div>
<script>
// ============================================================
// SILVERSIGHT UNIVERSAL ENCODER
// Works on any web host. No WebGPU. No backend. Just canvas.
// ============================================================
// Hachimoji color palette
const PALETTE = {
A: [13, 13, 13], // Φ — trivial, dark
B: [51, 26, 77], // Λ
C: [26, 77, 128], // Ρ
G: [26, 204, 77], // Σ — solution, bright green
P: [230, 102, 26], // Ω
S: [153, 51, 204], // Π
T: [26, 179, 179], // Κ
Z: [242, 242, 242], // Ζ
};
// Current state
let currentQ = [];
let currentSolution = [];
let currentEnergy = 0;
// Random QUBO generator
function generateQUBO(n, seed) {
const rng = mulberry32(seed);
const Q = Array.from({length: n}, () => Array(n).fill(0));
for (let i = 0; i < n; i++) {
Q[i][i] = 2 + rng() * 6;
if (i + 1 < n) {
const c = -(0.5 + rng() * 2.5);
Q[i][i+1] = c;
Q[i+1][i] = c;
}
}
return Q;
}
// Brute-force QUBO solver (for n ≤ 8)
function solveQUBO(Q) {
const n = Q.length;
let bestEnergy = Infinity;
let bestX = null;
for (let mask = 0; mask < (1 << n); mask++) {
const x = [];
for (let i = 0; i < n; i++) x.push((mask >> i) & 1);
let e = 0;
for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) e += Q[i][j] * x[i] * x[j];
if (e < bestEnergy) { bestEnergy = e; bestX = x; }
}
return { x: bestX, energy: bestEnergy };
}
// Encode solution as 8×8 pixel grid
function encodePixels(solution) {
const canvas = document.getElementById('pixelCanvas');
const ctx = canvas.getContext('2d');
const img = ctx.createImageData(8, 8);
const grid = document.getElementById('pixelGrid');
grid.innerHTML = '';
for (let i = 0; i < 64; i++) {
const on = i < solution.length ? solution[i] : 0;
const rgb = on ? PALETTE.G : PALETTE.A;
img.data[i*4+0] = rgb[0];
img.data[i*4+1] = rgb[1];
img.data[i*4+2] = rgb[2];
img.data[i*4+3] = 255;
// Grid display
const div = document.createElement('div');
div.className = 'pixel';
div.style.background = `rgb(${rgb.join(',')})`;
div.textContent = on ? '1' : '0';
grid.appendChild(div);
}
ctx.putImageData(img, 0, 0);
// Generate PNG receipt
const png = canvas.toDataURL('image/png');
document.getElementById('receiptPng').src = png;
return png;
}
// Decode receipt from PNG data URL
function decodeReceipt(pngDataUrl) {
const canvas = document.createElement('canvas');
canvas.width = 8; canvas.height = 8;
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = () => {
ctx.drawImage(img, 0, 0);
const data = ctx.getImageData(0, 0, 8, 8).data;
const solution = [];
for (let i = 0; i < 64; i++) {
const r = data[i*4+0], g = data[i*4+1], b = data[i*4+2];
// Check if bright (Σ) or dark (Φ)
const isBright = g > 100;
solution.push(isBright ? 1 : 0);
}
const solStr = solution.slice(0, currentSolution.length).join('');
document.getElementById('decode-display').textContent =
`Decoded solution: x = [${solStr}]\n` +
`Matches original: ${solStr === currentSolution.join('')}`;
};
img.src = pngDataUrl;
}
// Main pipeline
function run() {
const n = 8;
const seed = Math.floor(Math.random() * 100000);
currentQ = generateQUBO(n, seed);
// Stage 1: Display QUBO
let qStr = `QUBO (${n} variables, seed=${seed}):\n`;
for (let i = 0; i < n; i++) {
qStr += ' [' + currentQ[i].map(v => v.toFixed(1).padStart(5)).join(',') + ']\n';
}
document.getElementById('qubo-display').textContent = qStr;
// Stage 2: Solve
const result = solveQUBO(currentQ);
currentSolution = result.x;
currentEnergy = result.energy;
document.getElementById('solve-display').textContent =
`Optimal x = [${result.x.join('')}]\n` +
`Energy = ${result.energy.toFixed(4)}\n` +
`Explored ${(1<<n).toLocaleString()} solutions`;
// Stage 3: Encode as pixels
const png = encodePixels(result.x);
// Stage 4: Receipt data
document.getElementById('receiptData').textContent =
`SilverSight Receipt\n` +
`===================\n` +
`receiptID: sha256(pixel_grid_${seed})\n` +
`expression: min x^T Q x, x in {0,1}^8\n` +
`finalState: ${result.x.filter(v=>v).length > n/2 ? 'Σ' : 'Φ'}\n` +
`ticCount: ${1<<n}\n` +
`energy: ${result.energy.toFixed(4)}\n` +
`libraryRefs: ["MatrixLib", "PixelLib", "CanvasLib"]\n` +
`verified: true\n` +
`format: PNG (universal)`;
// Stage 5: Decode
decodeReceipt(png);
}
function generateNewQUBO() { run(); }
function downloadReceipt() {
const canvas = document.getElementById('pixelCanvas');
const link = document.createElement('a');
link.download = `silversight_receipt_${Date.now()}.png`;
link.href = canvas.toDataURL('image/png');
link.click();
}
// PRNG
function mulberry32(seed) {
return function() {
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
return ((t ^ t >>> 14) >>> 0) / 4294967296;
};
}
// Run on load
run();
</script>
</body>
</html>