/* Flow console harvester — paste into DevTools Console on the project's
   Videos page (labs.google/fx/tools/flow/project/<id> with Videos filter).
   Auto-scrolls the grid to load every tile, collects every unique video
   source, and downloads them sequentially as flowvid_NNN.mp4 into the
   browser's Downloads folder. Grid previews are the full mp4s at ~720p,
   which is the game's target resolution anyway.
   Safe: read-only against Flow; no clicks on app buttons. */
(async () => {
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
  const seen = new Set();

  const collect = () => {
    document.querySelectorAll("video").forEach((v) => {
      const s = v.currentSrc || v.src || v.querySelector?.("source")?.src;
      if (s) seen.add(s);
    });
  };

  // Find the scrollable container (falls back to window)
  const scroller =
    [...document.querySelectorAll("*")].find(
      (el) => el.scrollHeight > el.clientHeight + 500 && el.clientHeight > 400
    ) || document.scrollingElement;

  console.log("%cHarvest: scrolling to load all tiles…", "color:#0f0");
  let lastCount = -1, stable = 0;
  while (stable < 3) {
    collect();
    scroller.scrollBy?.(0, 900) ?? window.scrollBy(0, 900);
    await sleep(700);
    collect();
    if (seen.size === lastCount) stable++;
    else { stable = 0; lastCount = seen.size; }
  }
  console.log(`%cHarvest: found ${seen.size} unique videos. Downloading…`, "color:#0f0");

  let n = 0;
  for (const src of seen) {
    n++;
    try {
      const blob = await fetch(src).then((r) => r.blob());
      const a = document.createElement("a");
      a.href = URL.createObjectURL(blob);
      a.download = `flowvid_${String(n).padStart(3, "0")}.mp4`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      console.log(`downloaded ${n}/${seen.size}`);
      await sleep(1200); // gentle: don't trip the download shelf
    } catch (e) {
      console.warn(`miss ${n}: ${e.message}`);
    }
  }
  console.log("%cHarvest complete. Check your Downloads folder.", "color:#0f0");
})();
