${scoreText}
Overall Score: ${score.toFixed(0)} / 100
`; highlightedTextContainer.innerHTML = highlightedHtml; resultsPlaceholder.classList.add('hidden'); resultsContent.classList.remove('hidden'); downloadPdfBtn.disabled = false; renderDetailedReport(findings); }; const renderDetailedReport = (findings) => { reportView.innerHTML = ''; if(findings.length === 0) { reportView.innerHTML = `No risks were identified in the provided text.
`;
return;
}
findings.forEach(finding => {
const levelMap = {1: 'Low', 3: 'Medium', 5: 'High'};
const colorMap = {1: 'text-green-700 bg-green-100', 3: 'text-yellow-700 bg-yellow-100', 5: 'text-red-700 bg-red-100'};
const card = document.createElement('div');
card.className = 'p-4 border border-slate-200 rounded-lg bg-slate-50';
card.innerHTML = `
${finding.factor.description}
${levelMap[finding.factor.level]} RiskTriggered by keyword: "${finding.keyword}"
...${finding.context}...`; reportView.appendChild(card); }); }; // --- UI & TAB LOGIC --- const updateTabUI = () => { tabs.forEach(tab => tab.classList.toggle('active', tab.dataset.tab === currentTab)); tabContents.forEach(content => content.classList.toggle('active', content.id === `tab-${currentTab}`)); const currentIndex = tabOrder.indexOf(currentTab); prevBtn.disabled = currentIndex === 0; nextBtn.disabled = currentIndex === tabOrder.length - 1; if (currentTab === 'config') renderConfigList(); }; const changeTab = (direction) => { const currentIndex = tabOrder.indexOf(currentTab); const newIndex = currentIndex + direction; if (newIndex >= 0 && newIndex < tabOrder.length) { currentTab = tabOrder[newIndex]; updateTabUI(); } }; // --- CORE LOGIC --- const analyzeDefamationRisk = () => { const text = statementText.value; if (!text.trim()) { alert("Please paste some text to analyze."); return; } let findings = []; let totalRiskPoints = 0; let maxPossiblePoints = 0; const lowerCaseText = text.toLowerCase(); let highlightedText = text; riskFactors.forEach(factor => { const keywords = factor.keywords.split(',').map(k => k.trim().toLowerCase()).filter(Boolean); let factorFound = false; keywords.forEach(keyword => { if (lowerCaseText.includes(keyword)) { factorFound = true; const regex = new RegExp(`\\b${keyword}\\b`, 'gi'); let match; while((match = regex.exec(text)) !== null) { const startIndex = Math.max(0, match.index - 20); const endIndex = Math.min(text.length, match.index + keyword.length + 20); findings.push({ factor, keyword, context: text.substring(startIndex, endIndex).replace(match[0], `${match[0]}`) }); } highlightedText = highlightedText.replace(regex, `${keyword}${factor.description}`); } }); if (factorFound) { totalRiskPoints += factor.level; } maxPossiblePoints += factor.level; }); const score = maxPossiblePoints > 0 ? (totalRiskPoints / maxPossiblePoints) * 100 : 0; renderResults({ score, findings, highlightedHtml: highlightedText.replace(/\n/g, '
') }); }; // --- EVENT LISTENERS --- tabs.forEach(tab => tab.addEventListener('click', () => { currentTab = tab.dataset.tab; updateTabUI(); })); prevBtn.addEventListener('click', () => changeTab(-1)); nextBtn.addEventListener('click', () => changeTab(1)); analyzeRiskBtn.addEventListener('click', analyzeDefamationRisk); riskForm.addEventListener('submit', (e) => { e.preventDefault(); const id = document.getElementById('risk-id').value; const newItem = { id: id ? parseInt(id) : Date.now(), description: document.getElementById('risk-description').value, keywords: document.getElementById('risk-keywords').value, level: parseInt(document.getElementById('risk-level').value), }; if (id) { riskFactors = riskFactors.map(item => item.id === newItem.id ? newItem : item); } else { riskFactors.push(newItem); } resetForm(); renderConfigList(); }); cancelEditBtn.addEventListener('click', resetForm); configList.addEventListener('click', (e) => { const target = e.target; const id = parseInt(target.dataset.id); if (target.classList.contains('edit-btn')) { const itemToEdit = riskFactors.find(item => item.id === id); if (itemToEdit) populateForm(itemToEdit); } if (target.classList.contains('delete-btn')) { riskFactors = riskFactors.filter(item => item.id !== id); renderConfigList(); } }); // --- FORM & DATA HANDLING --- function populateForm(item) { formTitle.textContent = 'Edit Risk Factor'; document.getElementById('risk-id').value = item.id; document.getElementById('risk-description').value = item.description; document.getElementById('risk-keywords').value = item.keywords; document.getElementById('risk-level').value = item.level; cancelEditBtn.classList.remove('hidden'); } function resetForm() { formTitle.textContent = 'Add New Risk Factor'; riskForm.reset(); document.getElementById('risk-id').value = ''; cancelEditBtn.classList.add('hidden'); } // --- PDF DOWNLOAD --- downloadPdfBtn.addEventListener('click', () => { if (!lastResults) { console.error("No results to download."); return; } if (typeof window.jspdf === 'undefined') { console.error('jsPDF library is not available.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF({ unit: 'pt', format: 'a4' }); if (typeof doc.autoTable === 'undefined') { console.error('jsPDF autotable plugin is not available.'); return; } const { score, findings } = lastResults; const levelMap = {1: 'Low', 3: 'Medium', 5: 'High'}; doc.setFont('helvetica', 'bold'); doc.setFontSize(22); doc.setTextColor('#1e293b'); doc.text('Defamation Risk Analysis Report', doc.internal.pageSize.getWidth() / 2, 60, { align: 'center' }); doc.setFontSize(14); doc.text(`Overall Risk Score: ${score.toFixed(0)} / 100`, 40, 100); doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.text(`Source Text: "${statementText.value.substring(0, 70)}..."`, 40, 120); const tableData = findings.map(f => [ f.factor.description, levelMap[f.factor.level], f.keyword, f.context.replace(/<[^>]*>/g, '') // strip html from context for pdf ]); doc.autoTable({ startY: 150, head: [['Risk Factor', 'Level', 'Trigger Keyword', 'Context']], body: tableData, theme: 'grid', headStyles: { fillColor: '#1e293b', textColor: '#ffffff', fontStyle: 'bold' }, columnStyles: { 3: { cellWidth: 200 } } }); doc.save('Defamation-Risk-Report.pdf'); }); // --- INITIALIZATION --- updateTabUI(); });
