`;
}
function cbr_renderLocation() {
const container = document.getElementById('cbr-location');
if(!container) return;
container.innerHTML = `
`;
if (cbr_map) cbr_map.remove();
cbr_map = L.map('cbr-map-container').setView([34.0522, -118.2437], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '©
OpenStreetMap contributors'
}).addTo(cbr_map);
cbr_data.locations.forEach(loc => {
L.marker([loc.lat, loc.lng]).addTo(cbr_map)
.bindPopup(`
Timestamp: ${loc.timestamp}
Source: ${loc.source}`);
});
}
function cbr_renderConfiguration() {
const container = document.getElementById('cbr-config');
if(!container) return;
const createEditableTable = (key, title, headers) => {
let html = `
${title}
`;
headers.forEach(h => html += `| ${h} | `);
html += `Action |
`;
cbr_data[key].forEach((d, i) => {
html += ``;
Object.keys(d).forEach(k => {
if (k !== 'id') html += `| ${d[k]} | `;
});
html += ` |
`;
});
html += `
`;
return html;
};
container.innerHTML = createEditableTable('calls', 'Call Log Data', ['Type', 'Number', 'Timestamp', 'Duration']) +
createEditableTable('messages', 'Message Data', ['From', 'To', 'Content', 'Timestamp']) +
createEditableTable('locations', 'Location Data', ['Latitude', 'Longitude', 'Timestamp', 'Source']);
}
function cbr_saveConfigData() {
['calls', 'messages', 'locations'].forEach(key => {
const table = document.getElementById(`cbr-config-${key}`);
if (!table) return;
const rows = table.querySelectorAll('tbody tr');
let newData = [];
const headers = Object.keys(cbr_data[key][0]).filter(h => h !== 'id');
rows.forEach(row => {
let newRow = { id: cbr_data[key][row.dataset.index]?.id || Date.now() };
headers.forEach((h, i) => {
let val = row.cells[i].textContent;
newRow[h] = isNaN(parseFloat(val)) || h.toLowerCase().includes('date') || h.toLowerCase().includes('number') ? val : parseFloat(val);
});
newData.push(newRow);
});
cbr_data[key] = newData;
});
}
window.cbr_addDataRow = (key) => {
const tableBody = document.querySelector(`#cbr-config-${key} tbody`);
const newRow = tableBody.insertRow();
const headers = Object.keys(cbr_data[key][0]).filter(h => h !== 'id');
let cells = '';
headers.forEach(h => cells += `
| `);
cells += `
| `;
newRow.innerHTML = cells;
};
window.cbr_deleteDataRow = (btn) => { btn.closest('tr').remove(); };
// --- UI & Navigation ---
window.cbr_openTab = (evt, tabId) => {
document.querySelectorAll("#cbr-container .cbr-tab-content").forEach(c => c.classList.remove('active'));
document.querySelectorAll("#cbr-container .cbr-tab-link").forEach(l => l.classList.remove('active'));
const tab = document.getElementById(tabId);
if(tab) {
tab.classList.add('active');
if (tabId === 'cbr-location' && cbr_map) {
setTimeout(() => cbr_map.invalidateSize(), 10);
}
}
evt.currentTarget.classList.add('active');
};
window.cbr_navigateTabs = (direction) => {
const tabs = Array.from(document.querySelectorAll('#cbr-container .cbr-tab-link'));
const activeTabIndex = tabs.findIndex(tab => tab.classList.contains('active'));
const nextTabIndex = (direction === 'next') ? (activeTabIndex + 1) % tabs.length : (activeTabIndex - 1 + tabs.length) % tabs.length;
tabs[nextTabIndex].click();
};
window.cbr_downloadPDF = () => {
const activeTabContent = document.querySelector('.cbr-tab-content.active');
if (!activeTabContent || activeTabContent.id === 'cbr-config') {
alert("PDF download is not available for the data entry tab."); return;
}
const { jsPDF } = window.jspdf;
const title = "Cellebrite Report - " + document.querySelector('.cbr-tab-link.active').textContent;
const contentToPrint = document.createElement('div');
contentToPrint.innerHTML = document.getElementById('cbr-content-to-download').innerHTML;
contentToPrint.querySelector('.cbr-tabs').remove();
contentToPrint.querySelector('.cbr-button-container')?.remove();
contentToPrint.querySelectorAll('.cbr-tab-content').forEach(el => el.style.display = 'none');
contentToPrint.querySelector(`#${activeTabContent.id}`).style.display = 'block';
// Handle map separately
const mapContainer = contentToPrint.querySelector('#cbr-map-container');
if (mapContainer) mapContainer.style.height = '400px';
document.body.appendChild(contentToPrint);
html2canvas(contentToPrint, { scale: 2, useCORS: true }).then(canvas => {
document.body.removeChild(contentToPrint);
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const imgProps = pdf.getImageProperties(imgData);
const imgHeight = (imgProps.height * (pdfWidth - 20)) / imgProps.width;
pdf.addImage(imgData, 'PNG', 10, 10, pdfWidth - 20, imgHeight);
pdf.save("Cellebrite-Report.pdf");
});
};
cbr_init();
});