svg`<svg width="${w}" height="${h}">
<rect x="0" y="0" width="${w}" height="${h}" stroke="blue" fill="none"></rect>
<g transform="translate(${randInt(w)}, ${randInt(h)})">
${array(n).map(i => {
const rad = 20 + i * 8
const from = random(TAU)
return `<path
d="${array(360).map(j => {
const angle = from + j / 360 * TAU
const c = Math.cos(angle)
const s = Math.sin(angle)
const noise = sn.noise3D(c, s, seed) * .5 + .5
const r = rad * (1 + noise * ((i / n) ** 3))
const x = c * r
const y = s * r
return `${j === 0 ? 'M' : 'L'} ${x} ${y}`
}).join(' ')} Z"
fill="none"
stroke="${random() > .5 ? 'black' : 'red'}"
stroke-width="${map(i, 20, n, 1, 5, true)}"
stroke-linejoin="round"
stroke-linecap="round"
${i === 0 ? '' : `stroke-dasharray="${array(200).map(j => j % 2 === 1 ? randInt(5, i) : random() > i/n ? randInt(200) : randInt(3, 10)).join(' ')}"`}
/>`
}).join('\n')}
</g>
</svg>`