# butterchurn

- Author: Jordan Berg (jberg), with butterchurn-presets (MilkDrop presets collected and converted by the same project)
- Source: https://github.com/jberg/butterchurn (demo page: examples/demo.html) and https://github.com/jberg/butterchurn-presets
- Commit: fbac2f6bab62fd9c6a50ebbeb29359c5eb05903e (butterchurn master; package.json 3.0.0-beta.5, the version demo.html imports);
  butterchurn-presets master checked at c10e2616762f262de898e5d4c1f162a3e01340c1
- Licence: MIT (./LICENSE). Bundled deps:
  - dist/butterchurn.js — npm butterchurn@3.0.0-beta.5 (MIT; includes eel-wasm, MIT). Only change: the trailing
    `//# sourceMappingURL=butterchurn.js.map` line removed (the map is not vendored).
  - vendor/butterchurn-presets/base.min.js, extra.min.js — npm butterchurn-presets@3.0.0-beta.4 (MIT, LICENSE alongside),
    the exact files demo.html loads. They contain converted MilkDrop community presets as distributed by that package.
  - vendor/lodash/lodash.min.js — lodash 4.17.21 (MIT); demo loaded unpkg.com/lodash (latest = 4.17.21)
  - vendor/jquery/jquery.min.js — jQuery 3.1.1 (MIT), same version as the demo's code.jquery.com script
  - vendor/normalize.css/normalize.css — normalize.css 8.0.1 (MIT); demo loaded unpkg.com/normalize.css (latest = 8.0.1)
- Vendored files: examples/demo.html (unmodified, reference), dist/butterchurn.js, vendor/*
- Added by Web Curio: stage.html (made from examples/demo.html), museum-synth.js (CC0: a procedurally sequenced
  Web Audio beat — kick, snare, hats, filtered saw bass, chord stabs — no samples, no copyrighted music), this file
- Modifications to the original (stage.html, via stage.py):
  - strict CSP + sandbox shim
  - all CDN scripts/styles (unpkg lodash, butterchurn-presets, normalize.css, butterchurn ES module; code.jquery.com jQuery)
    → the bundled copies above
  - a third audio button "Play a generated beat" added next to "Load local files" / "Use Mic"; it feeds museum-synth.js
    through the demo's own connectToAudioAnalyzer()
  - the render loop is started at init so presets animate (without audio) before a source is picked, and a guard stops
    connectMicAudio() from starting a second loop
- "Use Mic" uses the legacy navigator.getUserMedia (provided by the shim); the host iframe must allow the microphone for it to work.
