import fs from 'fs'; import Papa from 'papaparse'; const loadTsv = (name) => Papa.parse(fs.readFileSync(name).toString(), { dynamicTyping: true, header: true, skipEmptyLines: true, delimiter: '\t', }).data; const _each = (obj, callable) => { const ret = []; for (const key in obj) { if (Object.hasOwn(obj, key)) { ret.push(callable(obj[key], key)); } } return ret; }; const peselK1 = loadTsv(`./locale/${process.env.NUXT_PUBLIC_LOCALE ?? '_'}/names/K1.tsv`); const peselK2 = loadTsv(`./locale/${process.env.NUXT_PUBLIC_LOCALE ?? '_'}/names/K2.tsv`); const peselM1 = loadTsv(`./locale/${process.env.NUXT_PUBLIC_LOCALE ?? '_'}/names/M1.tsv`); const peselM2 = loadTsv(`./locale/${process.env.NUXT_PUBLIC_LOCALE ?? '_'}/names/M2.tsv`); const pesel = {}; for (const [names, sex, ordinal] of [ [peselK1, 'K', 1], [peselK2, 'K', 2], [peselM1, 'M', 1], [peselM2, 'M', 2], ]) { for (const { name, count } of names) { if (pesel[name] === undefined) { pesel[name] = { K: [0, 0], M: [0, 0] }; } pesel[name][sex][ordinal - 1] = count; } } const calculateBalance = (k, m) => { const balance = k / (k + m); return balance > 0.5 ? 1 - balance : balance; }; const allUnisex = {}; const popularUnisex = {}; const allFirstUnisex = {}; const popularFirstUnisex = {}; _each(pesel, (counts) => { counts.balanceBoth = calculateBalance(counts.K[0] + counts.K[1], counts.M[0] + counts.M[1]); counts.balanceFirst = calculateBalance(counts.K[0], counts.M[0]); counts.balanceBothPop = counts.balanceBoth * (counts.K[0] + counts.K[1] + counts.M[0] + counts.M[1]); counts.balanceFirstPop = counts.balanceFirst * (counts.K[0] + counts.M[0]); }); let maxBalanceBoth = { balance: 0, name: '' }; let maxBalanceBothPop = { balance: 0, name: '' }; let maxBalanceFirst = { balance: 0, name: '' }; let maxBalanceFirstPop = { balance: 0, name: '' }; const popularMin = 100; _each(pesel, (counts, name) => { if (counts.K[0] + counts.K[1] > 0 && counts.M[0] + counts.M[1] > 0) { allUnisex[name] = counts; } if (counts.K[0] + counts.K[1] >= popularMin && counts.M[0] + counts.M[1] >= popularMin) { popularUnisex[name] = counts; if (counts.balanceBoth > maxBalanceBoth.balance) { maxBalanceBoth = { balance: counts.balanceBoth, name }; } } if (counts.balanceBothPop > maxBalanceBothPop.balance) { maxBalanceBothPop = { balance: counts.balanceBothPop, name }; } if (counts.K[0] > 0 && counts.M[0] > 0) { allFirstUnisex[name] = counts; } if (counts.K[0] >= popularMin && counts.M[0] >= popularMin) { popularFirstUnisex[name] = counts; if (counts.balanceFirst > maxBalanceFirst.balance) { maxBalanceFirst = { balance: counts.balanceFirst, name }; } } if (counts.balanceFirstPop > maxBalanceFirstPop.balance) { maxBalanceFirstPop = { balance: counts.balanceFirstPop, name }; } }); const buildTable = (names, both, sortBy) => { names = _each(names, (counts, name) => { return { name, counts }; }).sort((a, b) => { return b.counts[sortBy] - a.counts[sortBy]; }); let table = '
Imię | '; table += `Kobiety${both ? ' (pierwsze imię)' : ''} | `; if (both) { table += 'Kobiety (drugie imię) | '; } table += `Mężczyźni${both ? ' (pierwsze imię)' : ''} | `; if (both) { table += 'Mężczyźni (drugie imię) | '; } table += 'Balans | '; table += 'Balans × popularność | '; table += '
---|---|---|---|---|---|---|
${name} | `; table += `${counts.K[0]} | `; if (both) { table += `${counts.K[1]} | `; } table += `${counts.M[0]} | `; if (both) { table += `${counts.M[1]} | `; } table += `${counts[both ? 'balanceBoth' : 'balanceFirst'].toFixed(3)} | `; table += `${counts[both ? 'balanceBothPop' : 'balanceFirstPop'].toFixed(0)} | `; table += '