gallery = fetch("https://api.observablehq.com/@d3/gallery.js?v=3")
.then(r => r.text())
.then(t => t.match(/\{\n\s{2}path([\s\S]*?)\}/g))
.then(t => t.map(d => JSON.parse(d.replace(/\n\s{2}/g, "\"").replace(/\:/g, "\":"))))
.then(a => Promise.all(a.map(async d => ({...d, definition: (await import(`https://api.observablehq.com/${d.path}.js?v=3`).then(m => m.default).catch(() => false))}))))
.then(m => m.filter(({definition}) => definition))
.then(m => m.reduce(async (acc, n) => await getCell("data", n.definition, true) && await getCell("chart", n.definition, true) ? [...await acc, n] : acc, []))
.then(m => Promise.all(m.map(async d => ({...d, data: await getCell("data", d.definition)}))))
.then(f => f.sort((a, b) => a.title.localeCompare(b.title)))