function reorder(pointLists) {
if (pointLists.length === 0) { return pointLists; }
const pt = i =>
i % 2 === 0
? pointLists[(i / 2)|0][0]
: pointLists[(i / 2)|0][pointLists[(i / 2)|0].length - 1]
class PointRBush extends RBush {
toBBox(i) { const {x, y} = pt(i); return {minX: x, minY: y, maxX: x, maxY: y}; }
compareMinX(a, b) { return pt(a).x - pt(b).x; }
compareMinY(a, b) { return pt(a).y - pt(b).y; }
}
const tree = new PointRBush()
tree.load([...range(2, pointLists.length * 2)])
const sortedPointLists = [];
sortedPointLists.push(pointLists[0]);
let cur = pt(1)
let n = pointLists.length * 2 - 2
while (n) {
const [nn] = knn(tree, cur.x, cur.y, 1)
const plId = (nn/2)|0
tree.remove(plId * 2)
tree.remove(plId * 2 + 1)
sortedPointLists.push(
nn % 2 === 0
? pointLists[plId]
: pointLists[plId].slice().reverse()
)
cur = pt(nn % 2 === 0 ? nn + 1 : nn - 1)
n -= 2
}
return sortedPointLists
}