const fs = require("fs") const { round, floor, ceil } = Math let boxes = {} let nodes = [] let edges = [] let mode, name, x, y, w, h, cx, cy, rx, ry, x2, y2 let scale = 1 function flush() { if (mode === 'path') { edges.push({ x1: x, y1: y, x2, y2 }) } if (mode === 'rect') { boxes[name] = [ x * scale |0, y * scale |0, w * scale |0, h * scale |0 ] nodes.push({ name, x: x + w/2, y: y + h/2 }) } if (mode === 'circle') { x = cx - rx y = cy - ry w = rx * 2 h = ry * 2 boxes[name] = [ x * scale |0, y * scale |0, w * scale |0, h * scale |0 ] nodes.push({ name, x: cx, y: cy }) } x = y = x2 = y2 = w = h = cx = cy = rx = ry = 0 name = null } function parse_path_data(path) { let cx = 0 let cy = 0 let abs = 0 for (let i = 0; i < path.length;) { switch (path[i]) { case 'M': x = cx = Number(path[i+1]) y = cy = Number(path[i+2]) i += 3 abs = true break case 'm': x = cx = cx + Number(path[i+1]) y = cy = cy + Number(path[i+2]) i += 3 abs = false break case 'C': x2 = cx = Number(path[i+5]) y2 = cy = Number(path[i+6]) i += 7 abs = true break case 'L': i += 1 abs = true break case 'H': x2 = cx = Number(path[i+1]) i += 2 abs = true break case 'V': y2 = cy = Number(path[i+1]) i += 2 abs = true break case 'c': x2 = cx = cx + Number(path[i+5]) y2 = cy = cy + Number(path[i+6]) i += 7 break case 'l': i += 1 abs = false break case 'h': x2 = cx = cx + Number(path[i+1]) i += 2 abs = false break case 'v': y2 = cy = cy + Number(path[i+1]) i += 2 abs = false break default: if (abs) { x2 = cx = Number(path[i+0]) y2 = cy = Number(path[i+1]) } else { x2 = cx = cx + Number(path[i+0]) y2 = cy = cy + Number(path[i+1]) } i += 2 break } } } for (let line of fs.readFileSync("tools/layout.svg", "utf-8").split("\n")) { line = line.trim() if (line.startsWith("