// Original 5×7 bitmap glyphs. All rendering is local; no fonts or API are fetched. const patterns = { A: '01110/10001/10001/11111/10001/10001/10001', B: '11110/10001/10001/11110/10001/10001/11110', C: '01111/10000/10000/10000/10000/10000/01111', D: '11110/10001/10001/10001/10001/10001/11110', E: '11111/10000/10000/11110/10000/10000/11111', F: '11111/10000/10000/11110/10000/10000/10000', G: '01111/10000/10000/10111/10001/10001/01111', H: '10001/10001/10001/11111/10001/10001/10001', I: '11111/00100/00100/00100/00100/00100/11111', J: '00111/00010/00010/00010/10010/10010/01100', K: '10001/10010/10100/11000/10100/10010/10001', L: '10000/10000/10000/10000/10000/10000/11111', M: '10001/11011/10101/10101/10001/10001/10001', N: '10001/11001/10101/10011/10001/10001/10001', O: '01110/10001/10001/10001/10001/10001/01110', P: '11110/10001/10001/11110/10000/10000/10000', Q: '01110/10001/10001/10001/10101/10010/01101', R: '11110/10001/10001/11110/10100/10010/10001', S: '01111/10000/10000/01110/00001/00001/11110', T: '11111/00100/00100/00100/00100/00100/00100', U: '10001/10001/10001/10001/10001/10001/01110', V: '10001/10001/10001/10001/10001/01010/00100', W: '10001/10001/10001/10101/10101/10101/01010', X: '10001/10001/01010/00100/01010/10001/10001', Y: '10001/10001/01010/00100/00100/00100/00100', Z: '11111/00001/00010/00100/01000/10000/11111', 0: '01110/10001/10011/10101/11001/10001/01110', 1: '00100/01100/00100/00100/00100/00100/01110', 2: '01110/10001/00001/00010/00100/01000/11111', 3: '11110/00001/00001/01110/00001/00001/11110', 4: '00010/00110/01010/10010/11111/00010/00010', 5: '11111/10000/10000/11110/00001/00001/11110', 6: '01110/10000/10000/11110/10001/10001/01110', 7: '11111/00001/00010/00100/01000/01000/01000', 8: '01110/10001/10001/01110/10001/10001/01110', 9: '01110/10001/10001/01111/00001/00001/01110', ' ': '000/000/000/000/000/000/000', '!': '1/1/1/1/1/0/1', '?': '01110/10001/00001/00010/00100/00000/00100', '.': '0/0/0/0/0/0/1', ',': '00/00/00/00/00/01/10', ':': '0/1/0/0/1/0/0', ';': '00/01/00/00/01/01/10', '-': '000/000/000/111/000/000/000', '_': '00000/00000/00000/00000/00000/00000/11111', '+': '00000/00100/00100/11111/00100/00100/00000', '=': '00000/00000/11111/00000/11111/00000/00000', '/': '00001/00001/00010/00100/01000/10000/10000', '\\': '10000/10000/01000/00100/00010/00001/00001', '(': '001/010/100/100/100/010/001', ')': '100/010/001/001/001/010/100', '[': '111/100/100/100/100/100/111', ']': '111/001/001/001/001/001/111', '{': '001/010/010/100/010/010/001', '}': '100/010/010/001/010/010/100', '<': '0001/0010/0100/1000/0100/0010/0001', '>': '1000/0100/0010/0001/0010/0100/1000', "'": '1/1/0/0/0/0/0', '"': '101/101/000/000/000/000/000', '`': '10/01/00/00/00/00/00', '#': '01010/11111/01010/01010/11111/01010/00000', '$': '00100/01111/10100/01110/00101/11110/00100', '%': '11001/11010/00010/00100/01000/01011/10011', '&': '01100/10010/10100/01000/10101/10010/01101', '*': '00000/10101/01110/11111/01110/10101/00000', '@': '01110/10001/10111/10101/10111/10000/01111', '^': '00100/01010/10001/00000/00000/00000/00000', '|': '1/1/1/1/1/1/1', '~': '00000/00000/01001/10110/00000/00000/00000', }; export const styles = ['block', 'banner', 'slant', 'compact']; export function normalizeText(text) { return text.replace(/ı/g, 'i').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toUpperCase(); } export function render(text, style = 'block') { if (!styles.includes(style)) throw new Error('Unknown lettering style'); if (text.length > 500) throw new Error('Text is too long'); return normalizeText(text).replace(/\r\n?/g, '\n').split('\n').map(line => { const characters = [...line.replace(/\t/g, ' ')]; const glyphs = characters.map(char => (patterns[char] || patterns['?']).split('/')); return Array.from({length: 7}, (_, row) => { const pixels = glyphs.map((glyph, i) => [...glyph[row]].map(pixel => { if (style === 'banner') return pixel === '1' ? characters[i] : ' '; if (style === 'compact') return pixel === '1' ? '#' : ' '; return pixel === '1' ? '##' : ' '; }).join('')).join(style === 'compact' || style === 'banner' ? ' ' : ' '); return (style === 'slant' ? ' '.repeat(6 - row) : '') + pixels.trimEnd(); }).join('\n'); }).join('\n\n'); }