const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); function lineOf(source, index) { return source.slice(0, index).split(/\r?\n/).length; } function readAttr(attrs, name) { return attrs.match(new RegExp(`\\b${name}\\s*=\\s*(["'])(.*?)\\1`, 's'))?.[2] || ''; } function hasClass(attrs, className) { return readAttr(attrs, 'class').split(/\s+/).includes(className); } function collectDataRows(html) { const tagRe = /<\/?([a-zA-Z][\w:-]*)([^>]*)>|/g; const voidTags = new Set([ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr', ]); const stack = []; const rows = []; for (const match of html.matchAll(tagRe)) { const raw = match[0]; if (raw.startsWith('