const fs = require('fs'), crypto = require('crypto'); const d = 'storage/app/private/investmoz-v2/'; const r = (f) => JSON.parse(fs.readFileSync(d + f, 'utf8').replace(/^\uFEFF/, '')); const p = r('master-paragraphs-reopened.json'), source = r('docx-reopened.json'); const heads = p.filter((x) => /^(Ttulo|Title|Heading)/i.test(x.style)); const rows = heads.map((x, i) => ({ title: x.text, start: x.p, end: heads[i + 1] ? heads[i + 1].p - 1 : p.length, style: x.style, })); const q = (s) => '"' + String(s).replaceAll('"', '""') + '"'; fs.writeFileSync( 'docs/investmoz/v2/indice-documento-mestre-atual.csv', [ 'fonte,sha256,paragrafo_inicio,paragrafo_fim,estilo,secção,estado', ...rows.map((x) => [ 'melhorar e transformar o Portal do Investidor atual.docx', source.sha256, x.start, x.end, x.style, x.title, 'Leitura atual; implementação individual não certificada', ] .map(q) .join(','), ), ].join('\n') + '\n', ); const groups = new Map(); for (const x of rows) { const text = p .filter((v) => v.p >= x.start && v.p <= x.end) .map((v) => v.text.replace(/\s+/g, ' ').trim()) .join('\n'); const row = { ...x, contentSha256: crypto.createHash('sha256').update(text).digest('hex'), }; const key = x.title.trim().toLowerCase(); groups.set(key, [...(groups.get(key) ?? []), row]); } const repeated = [...groups.values()] .filter((g) => g.length > 1) .map((g) => ({ title: g[0].title, occurrences: g, comparison: new Set(g.map((v) => v.contentSha256)).size > 1 ? 'current_content_differs' : 'current_content_identical', })); fs.writeFileSync( 'docs/investmoz/v2/repeticoes-reconciliacao-atual.json', JSON.stringify( { sha256: source.sha256, checked_at: source.checked_at, repeated }, null, 2, ), ); const changes = r('master-aligned-changes.json'); const map = new Map(changes.mapping.map((v) => [v.old, v.current])); const historic = r('master-paragraphs.json'); const steps = []; for (let old = 1782; old <= 1847; old += 5) { const title = historic.find((x) => x.p === old).text; const inputs = historic.find((x) => x.p === old + 2).text; const current = map.get(old); if ( !current || p.find((v) => v.p === current).text !== title || p.find((v) => v.p === map.get(old + 2)).text !== inputs ) throw Error('Guide text changed ' + old); steps.push({ title, inputs, sourceParagraph: current, historicalSourceParagraph: old, href: old === 1797 ? '/simulador-fiscal' : old === 1802 || old === 1807 ? '/balcao-virtual/painel' : '/documentos', }); } if (!fs.existsSync(d + 'fiscal-preparation-guide-before-reread.ts')) fs.copyFileSync( 'resources/js/lib/fiscal-preparation-guide.ts', d + 'fiscal-preparation-guide-before-reread.ts', ); fs.writeFileSync( 'resources/js/lib/fiscal-preparation-guide.ts', '// Current source verified against preserved historical paragraphs; orientation only.\nexport const fiscalPreparationSource = ' + JSON.stringify({ sha256: source.sha256, start: 973, end: 1042 }) + ';\nexport const fiscalPreparationGuide = ' + JSON.stringify(steps, null, 2) + ';\n', ); fs.writeFileSync( d + 'master-reread-verification.json', JSON.stringify( { sha256: source.sha256, paragraphs: p.length, headingCount: heads.length, repeatedGroups: repeated.length, differentGroups: repeated.filter( (g) => g.comparison === 'current_content_differs', ).length, bodyAdded: changes.added.length, bodyRemoved: changes.removed.length, guideStepsVerified: steps.length, guideTextUnchanged: true, newFunctionalRequirementsIdentified: false, }, null, 2, ), ); console.log(fs.readFileSync(d + 'master-reread-verification.json', 'utf8'));