const fs = require('fs') const path = require('path') function walk(dir, out = []) { for (const name of fs.readdirSync(dir)) { const p = path.join(dir, name) const st = fs.statSync(p) if (st.isDirectory()) walk(p, out) else if (/\.(vue|js|scss)$/.test(name)) out.push(p) } return out } const root = path.join(__dirname, '../src/views/lobster') for (const file of walk(root)) { const buf = fs.readFileSync(file) let invalid = 0 for (let i = 0; i < buf.length; i++) { const b = buf[i] if (b <= 0x7f) continue if (b >= 0xc2 && b <= 0xdf) { if (i + 1 >= buf.length || buf[i + 1] < 0x80 || buf[i + 1] > 0xbf) invalid++ else i++ } else if (b >= 0xe0 && b <= 0xef) { if (i + 2 >= buf.length || buf[i + 1] < 0x80 || buf[i + 1] > 0xbf || buf[i + 2] < 0x80 || buf[i + 2] > 0xbf) invalid++ else i += 2 } else if (b >= 0xf0 && b <= 0xf4) { if (i + 3 >= buf.length) invalid++ else i += 3 } else if (b >= 0x80 && b <= 0xbf) { invalid++ } else { invalid++ } } const text = buf.toString('utf8') const repl = (text.match(/\uFFFD/g) || []).length const mojibake = /[\u0080-\u00ff]{3,}/.test(text) && /label=/.test(text) if (invalid || repl || mojibake) { console.log(path.relative(root, file), { invalid, repl, mojibake }) } }