()
| 10565 | virtual_laa: ['Virtual/VM', 'text-gray-400'], |
| 10566 | }; |
| 10567 | html += `<p class="text-xs uppercase text-gray-400 mt-4 mb-1">All MACs observed (${obs.length})</p>` + |
| 10568 | '<table class="min-w-full text-xs text-gray-300 whitespace-nowrap"><thead>' + |
| 10569 | '<tr class="text-left text-gray-500"><th class="px-2 py-1">MAC</th><th class="px-2 py-1">Type</th><th class="px-2 py-1">Vendor</th><th class="px-2 py-1">IP(s)</th></tr>' + |
| 10570 | '</thead><tbody>' + |
| 10571 | obs.map(c => { |
| 10572 | const [lbl, cls] = KLASS[c.klass] || [c.klass, 'text-gray-400']; |
| 10573 | const ips = (c.ips || []); |
| 10574 | return `<tr class="border-t border-slate-800"> |
| 10575 | <td class="px-2 py-1 font-mono ${c.klass === 'spoofed_vendor_oui' ? 'text-red-300' : ''}">${escapeHtml(c.mac)}</td> |
| 10576 | <td class="px-2 py-1 ${cls}">${escapeHtml(lbl)}</td> |
| 10577 | <td class="px-2 py-1 text-gray-400">${escapeHtml(c.vendor || '—')}</td> |
| 10578 | <td class="px-2 py-1 font-mono">${escapeHtml(ips.slice(0, 4).join(', ')) || '—'}${ips.length > 4 ? '…' : ''}</td> |
| 10579 | </tr>`; |
| 10580 | }).join('') + |
| 10581 | '</tbody></table>'; |
| 10582 | } |
| 10583 | // Reasons narrative |
| 10584 | if (d.reasons && d.reasons.length) { |
| 10585 | html += '<ul class="text-xs text-gray-400 mt-3 list-disc pl-5">' + |
| 10586 | d.reasons.map(x => '<li>' + escapeHtml(x) + '</li>').join('') + '</ul>'; |
no test coverage detected