const zlib = require('zlib'); const fs = require('fs'); const path = require('path'); const outDir = process.argv[2] || path.join(__dirname, '..', 'public', 'icons'); fs.mkdirSync(outDir, { recursive: true }); function writeChunk(type, data) { const chunk = Buffer.concat([Buffer.alloc(4), Buffer.from(type), data, Buffer.alloc(4)]); chunk.writeUInt32BE(data.length, 0); const crc = zlib.crc32(Buffer.concat([Buffer.from(type), data])); chunk.writeUInt32BE(crc >>> 0, 4 + 4 + data.length); return chunk; } function writePng(filename, width, height, r, g, b) { const signature = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]); const ihdr = Buffer.alloc(13); ihdr.writeUInt32BE(width, 0); ihdr.writeUInt32BE(height, 4); ihdr.writeUInt8(8, 8); ihdr.writeUInt8(2, 9); ihdr.writeUInt8(0, 10); ihdr.writeUInt8(0, 11); ihdr.writeUInt8(0, 12); const rowLength = 1 + width * 3; const imageData = Buffer.alloc(rowLength * height); for (let y = 0; y < height; y++) { const rowStart = y * rowLength; imageData[rowStart] = 0; for (let x = 0; x < width; x++) { const offset = rowStart + 1 + x * 3; imageData[offset] = r; imageData[offset + 1] = g; imageData[offset + 2] = b; } } const compressed = zlib.deflateSync(imageData); const chunks = [signature, writeChunk('IHDR', ihdr), writeChunk('IDAT', compressed), writeChunk('IEND', Buffer.alloc(0))]; fs.writeFileSync(filename, Buffer.concat(chunks)); } const teal = [0x22, 0xD3, 0xEE]; writePng(path.join(outDir, 'icon16.png'), 16, 16, ...teal); writePng(path.join(outDir, 'icon48.png'), 48, 48, ...teal); writePng(path.join(outDir, 'icon128.png'), 128, 128, ...teal); console.log('Icons generated');