Initial release.

It's working well enough that I am using it in another project, but API is subject to changing.