(server)
| 776 | } |
| 777 | |
| 778 | function updateResult(server) { |
| 779 | let row = findResultRow(server); |
| 780 | let detailsRow; |
| 781 | |
| 782 | const fmt = (v) => typeof v === 'number' ? v.toFixed(2) : 'N/A'; |
| 783 | const badgeHTML = reliabilityBadge(server.reliability); |
| 784 | |
| 785 | if (!row) { |
| 786 | row = document.createElement('tr'); |
| 787 | row.dataset.serverName = server.name; |
| 788 | row.dataset.serverUrl = server.url; |
| 789 | row.className = 'border-b border-slate-100 dark:border-slate-800/50 perf-border cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-800/30 transition-colors row-enter'; |
| 790 | resultsBody.appendChild(row); |
| 791 | |
| 792 | detailsRow = document.createElement('tr'); |
| 793 | detailsRow.className = 'details-row hidden'; |
| 794 | resultsBody.appendChild(detailsRow); |
| 795 | |
| 796 | row.addEventListener('click', (e) => { |
| 797 | if (e.target.closest('.copy-btn')) return; |
| 798 | detailsRow.classList.toggle('hidden'); |
| 799 | row.classList.toggle('row-expanded'); |
| 800 | }); |
| 801 | } else { |
| 802 | detailsRow = row.nextElementSibling; |
| 803 | } |
| 804 | |
| 805 | const ipsText = server.ips && server.ips.length ? server.ips.join(', ') : ''; |
| 806 | const safeName = escapeHTML(server.name); |
| 807 | const safeIpsText = escapeHTML(ipsText); |
| 808 | const country = countryLabel(server); |
| 809 | const countryHTML = country ? countryBadgeHTML(server) : ''; |
| 810 | const countryDetailHTML = country |
| 811 | ? `<p class="text-xs text-slate-500 dark:text-slate-400 mb-3">Provider country: ${countryHTML} <span>${escapeHTML(country)}</span></p>` |
| 812 | : ''; |
| 813 | |
| 814 | row.innerHTML = ` |
| 815 | <td class="py-3 px-4 text-left"> |
| 816 | <div class="flex items-center gap-2"> |
| 817 | <svg class="expand-chevron w-3 h-3 text-slate-400 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/></svg> |
| 818 | <div class="min-w-0"> |
| 819 | <div class="flex items-center gap-2 flex-wrap"> |
| 820 | ${countryHTML} |
| 821 | <span class="font-medium text-slate-800 dark:text-slate-200">${safeName}</span> |
| 822 | ${badgeHTML} |
| 823 | </div> |
| 824 | ${ipsText ? `<div class="text-xs text-slate-400 dark:text-slate-500 mt-0.5 tabnum">${safeIpsText}</div>` : ''} |
| 825 | </div> |
| 826 | </div> |
| 827 | </td> |
| 828 | <td class="py-3 px-4 text-right tabnum text-slate-700 dark:text-slate-300">${fmt(server.speed.min)}</td> |
| 829 | <td class="py-3 px-4 text-right tabnum text-slate-700 dark:text-slate-300">${fmt(server.speed.median)}</td> |
| 830 | <td class="py-3 px-4 text-right tabnum font-medium text-slate-900 dark:text-slate-100">${fmt(server.speed.avg)}</td> |
| 831 | <td class="py-3 px-4 text-right tabnum text-slate-700 dark:text-slate-300">${fmt(server.speed.max)}</td> |
| 832 | `; |
| 833 | |
| 834 | const reliabilityMsg = server.reliability && server.reliability.message |
| 835 | ? `<p class="text-xs text-slate-500 dark:text-slate-400 mb-3">${server.reliability.message}</p>` : ''; |
no test coverage detected