shithub: barf

Download patch

ref: bd5bce727abff8a02a61685f6ee2a199f875557e
author: sl <sl@gaff>
date: Sat Aug 24 23:45:18 EDT 2024

mercurial -> git: initial import (sans commit history)

diff: cannot open b/barf//null: file does not exist: 'b/barf//null' diff: cannot open b/bin//null: file does not exist: 'b/bin//null' diff: cannot open b/lib//null: file does not exist: 'b/lib//null' diff: cannot open b/pub//null: file does not exist: 'b/pub//null' diff: cannot open b/src/1/tags//null: file does not exist: 'b/src/1/tags//null' diff: cannot open b/src/1//null: file does not exist: 'b/src/1//null' diff: cannot open b/src//null: file does not exist: 'b/src//null'
--- /dev/null
+++ b/README
@@ -1,0 +1,158 @@
+BARF - emit HTML
+
+DESCRIPTION
+	BARF utilizes rc(1) and command line tools to compile a structured
+	directory of files into a single page of HTML. Tagging and RSS 2.0
+	feeds have been implemented.
+
+SETUP
+	To enable BARF, add:
+
+		conf_enable_barf
+
+	to _werc/config under the site root.
+
+	To configure BARF, copy or create the following files under the site
+	root (example files have been included in this distribution):
+
+	_werc/barf/config
+		A list of variables that control various site options:
+
+			barf_type=paste # blog, image, log, paste
+			posts_per_page=10
+			show_ascending=0
+			show_footer=0
+			show_header=0
+			show_sidebar=0
+			require_login=0 # if not logged in, redirect to /login
+			allow_anon=1 # allow posts without logging in
+			show_disqus=0 # include disqus comments template
+					# from _werc/barf/disqus
+
+	_werc/barf/footer
+		HTML or markdown that will appear as the foot of
+		the BARF content area.
+
+	_werc/barf/header
+		HTML or markdown that will appear at the head of
+		the BARF content area.
+
+	_werc/barf/sidebar
+		HTML or markdown that will appear on one side of
+		the BARF content area.
+
+	Finally, sample stylesheets are provided in the directory
+	pub/. Copy any of these to _werc/pub/style.css to try
+	them out.
+
+POSTS
+	Posts are stored in the directory src/ relative to the
+	site root.
+
+	Directory names in src/ that do not match the regular
+	expression ^[0-9]*$ will not be included in the listing of
+	posts that are displayed in the browser. However, such
+	directories are still accessible when called directly via
+	an appropriately constructed URL.
+
+	A post's directory contains the following files and
+	directories (an example post's directory has been
+	included in this distribution):
+
+		body
+		date
+		img/
+		link
+		tags/
+		title
+
+	The img/ directory contains images uploaded to the
+	image board, including the original image and a
+	thumbnail version, resized to no greater than 500
+	pixels wide and 600 pixels tall.
+
+	The tags/ directory contains one empty file named
+	for each tag associated with the post.
+
+	The site root contains a file named tags that is compr-
+	ised of an index of the tags associated with each post.
+	This index is consulted when searching for a given tag in
+	the web browser.
+
+UTILS
+	bin/gf
+		Parse Livejournal and Tumblr RSS feeds into
+		BARF posts. (Abandoned, may no longer work.)
+	bin/gk
+		Create a list of known tags in the site root in
+		a file named known_tags.
+	bin/gr
+		Parse Google Reader bundles into BARF posts.
+	bin/gt
+		Create an index of tags in the site root in a file
+		named tags.
+
+	For more information on these tools, read the source.
+
+ADMIN
+	Any tool that can create, alter, or delete flat files
+	and directories is sufficient to administer a BARF.
+
+	Web-based login and administration utilizes werc's
+	built-in user authentication:
+
+		http://domain.com/login
+
+	After login, links to edit and delete will appear in
+	each post's meta data.
+
+	Web-based administration requires that the src/
+	directory and its sub-directories are writable by
+	the web server process.
+
+REQUIREMENTS
+	Unix
+		Plan9port or 9base are required. Site type
+		image requires ImageMagick and curl. Site
+		type url also requires curl if the user employs
+		the option to download remote URLs. These
+		utilities may be swapped out for others by
+		altering the source.
+
+SOURCE
+	http://plan9.stanleylieber.com/werc/apps/barf.tgz
+	https://code.9front.org/hg/barf
+
+EXAMPLES
+	blog
+		http://read.stanleylieber.com
+		RSS feeds are converted by the utility rrss[0]
+		and stored as individual blog posts.
+	image
+		http://img.stanleylieber.com
+		Hybrid public/private image board. Requires
+		standard werc authentication to post, but all
+		posts are visible to the public.
+	paste
+		http://okturing.com
+		Public pastebin. No authentication required
+		to post.
+	url
+		http://url.stanleylieber.com
+		Private index of URL bookmarks, similar
+		in functionality to the old delicious.com.
+		(In fact, most of the index was imported
+		from delicious.)
+
+SEE ALSO
+	[0] https://code.9front.org/hg/rrss
+
+LICENSE
+	Public domain.
+
+BUGS
+	On Plan 9, if the web server process is run as user
+	none (typically the case), directories used for entering
+	posts or uploading/downloading files from the browser
+	must be set world writable. This could prove problematic
+	on multiuser systems.
--- /dev/null
+++ b/app.rc
@@ -1,0 +1,80 @@
+fn conf_enable_barf{
+	barf_base_uri=$conf_wd
+	barf_root=`{pwd}
+	conf_enable_app barf
+}
+
+fn barf_init{
+	p=`{echo $req_path | sed 's!^'^$barf_base_uri^'!!'}
+	barf_dir=`{basename -d $"p | sed 's!^\.$!!'}
+	barf_items=`{cat $barf_root/_werc/barf/items}
+	. ./apps/barf/lib/core
+	. ./apps/barf/barf/config
+	. $barf_root/_werc/barf/config
+	. ./apps/barf/lib/$barf_type
+	if(test -f $barf_root/_werc/barf/lib/$barf_type)
+		. $barf_root/_werc/barf/lib/$barf_type
+	if(~ $require_login 1 && ! ~ $req_path $barf_base_uri^login){
+		check_user
+		if(~ $#logged_user 0)
+			post_redirect /login
+	}
+	if(~ $REQUEST_METHOD GET && ~ $REQUEST_URI *'='*){
+		load_get_args
+		parse_get_args
+	}
+	if(~ $REQUEST_METHOD POST)
+		parse_post_args
+	if(~ $a_func add_post){
+		if(~ $allow_anon 1 || {check_user && ! ~ $#logged_user 0})
+			add_post
+			post_redirect /
+	}
+	if(~ $a_func edit_post delete_post dsrc){
+		if(check_user && ! ~ $#logged_user 0){
+			switch($a_func){
+			case edit_post
+				edit_post
+			case delete_post
+				delete_post
+			case dsrc
+				dsrc
+			}
+		}
+	}
+	get_start
+	get_stop
+	get_tags
+	if(~ $req_path $barf_base_uri){
+		extraHeaders=$"extraHeaders ^ \
+'<link rel="alternate" type="application/rss+xml" title="RSS" href="'$base_url^$barf_base_uri'index.rss" />'
+		handler_body_main=(tpl_handler `{barf_template barf})
+	}
+	if not if(~ $req_path $barf_base_uri^index.rss){
+		obarf_type=$barf_type	# disgusting hack. fix!
+		barf_type=rss
+		. ./apps/barf/lib/rss
+		barf_setup_feed_handlers barf.tpl 'text/xml; charset=utf-8'
+	}
+	if not if(~ $req_path $barf_base_uri^login){
+		barf_type=login
+		handler_body_main=(tpl_handler `{barf_template barf})
+	}
+}
+
+fn barf_setup_feed_handlers{
+	handler_body_main=NOT_USED_by_barf_feeds
+	res_tail=()
+	http_content_type=$2
+	headers=()
+	master_template=apps/barf/lib/$1
+}
+
+fn barf_template{
+	if(test -f $barf_root/$"barf_dir/_werc/barf/lib/$1.tpl)
+		echo -n $barf_root/$"barf_dir/_werc/barf/lib/$1.tpl
+	if not if(test -f $barf_root/_werc/barf/lib/$1.tpl)
+		echo -n $barf_root/_werc/barf/lib/$1.tpl
+	if not
+		get_lib_file barf/$1.tpl apps/barf/lib/$1.tpl
+}
--- /dev/null
+++ b/barf/config
@@ -1,0 +1,9 @@
+barf_type=blog # blog, image, log, paste, url
+site_tmp=_tmp # used by hoc on plan 9
+posts_per_page=10
+show_ascending=0
+show_footer=0
+show_header=0
+show_sidebar=0
+require_login=0 # if not logged in, redirect to /login
+allow_anon=1 # allow posts without logging in
--- /dev/null
+++ b/barf/footer
@@ -1,0 +1,1 @@
+THIS IS THE FOOTER.
--- /dev/null
+++ b/barf/header
@@ -1,0 +1,1 @@
+THIS IS THE HEADER.
--- /dev/null
+++ b/barf/sidebar
@@ -1,0 +1,1 @@
+THIS IS THE SIDEBAR.
--- /dev/null
+++ b/bin/bsrc
@@ -1,0 +1,174 @@
+#!/bin/rc
+# Build static pages for $site.
+rfork e
+fn usage{
+	echo usage: $0 [ domain.com ] >[1=2]
+	exit usage
+}
+if(~ $#1 0)
+	usage
+
+fn conf_enable_barf{ }
+
+werc=/usr/sl/www/werc
+site=$werc/sites/$1
+barf_root=$site
+
+. $site/_werc/config
+. $site/_werc/barf/config
+. $werc/apps/barf/lib/core
+. $werc/apps/barf/lib/$barf_type
+if(test -f $site/_werc/barf/lib/$barf_type)
+	. $site/_werc/barf/lib/$barf_type
+if(~ $show_ascending 1)
+	sort=(sort -nu)
+if not
+	sort=(sort -nru)
+
+fn check_user{ }
+
+fn display_html_footers{
+	echo '</body>
+</html>'
+}
+
+fn display_html_headers{
+	echo '<html>
+<head>
+
+    <title>'$"siteTitle'</title>
+
+    <link rel="stylesheet" href="/_werc/pub/style.css" type="text/css" media="screen" title="default">
+    <link rel="shortcut icon" href="/favicon.ico" type="image/vnd.microsoft.icon">
+    <link rel="alternate" type="application/rss+xml" title="RSS" href="'$"rss'">
+    <meta charset="UTF-8">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
+
+</head>
+<body>
+'
+}
+
+fn display_prevnext{
+	if(~ $#nstart 1){
+		echo '
+		<div id="page_list">
+		<span>
+		'
+		if(test $start -lt $pstop && ! ~ $start $pstart)
+			echo '<a href="'$pstart^'-'^$pstop^'.html">prev</a> | '
+		echo '</span>
+		<span>
+		'
+		if(test $nstart -gt $bposts($#bposts))
+			echo '<a href="'$nstart^'-'^$nstop^'.html">next</a>'
+		echo '
+		</span>
+		</div>
+		'
+	}
+}
+
+fn get_post_list{
+	if(~ $#posts 0){
+		if(~ $id [0-9]*)
+			posts=$id
+		if not{
+			posts=`{
+				if(~ $tags all)
+					ls -p $site/src |
+						grep -e '^[0-9]*$' |
+						eval $sort |
+						sed -n $start^,^$stop^p
+				if not
+					grep -e '^.*\/'$tags'$' $site/tags |
+						awk -F '/' '{print $1;}' |
+						eval $sort |
+						sed -n $start^,^$stop^p
+			}
+			if(! ~ $posts [0-9]*)
+				posts=()
+		}
+	}
+}
+
+fn print{
+	display_html_headers
+	if(~ $show_header 1)
+		display_header
+	display_^$barf_type
+	if(~ $show_sidebar 1)
+		display_sidebar
+	if(~ $show_footer 1)
+		display_footer
+	display_html_footers
+}
+
+fn print_id{
+	echo '<span id="post_id"><a href="'$"a_id'.html">No.'$"a_id'</a></span>'
+}
+
+fn print_tags{
+	a_tags=`{ls -p $a_dir/tags}
+	a_tags=`{for(t in $a_tags) echo '<a href="/tag/'$t'">'$t'</a>, '}
+	a_tags=`{echo $a_tags | awk '{print substr($0, 1, length($0) -1)}'}
+	echo '<span id="post_tags">'$"a_tags'</span>'
+}
+
+fn print_title{
+	a_title=`{cat $a_dir/title}
+	if(! ~ $#a_title 0){
+		if(~ $barf_type log url)
+			echo '<a href="'`{cat $a_dir/link}'">'$"a_title'</a>'
+		if not
+			echo '<a href="'$"a_id'.html">'$"a_title'</a>'
+	}
+}
+
+cd $site
+
+# individual posts
+bposts=`{ls -p $site/src | grep -v private | grep -e '^[0-9]*$' | eval $sort}
+for(b in $bposts){
+	id=$b posts=() print >$b.html
+	echo $"b^'.html' >[1=2]
+}
+
+# paginated posts
+start=$bposts(1)
+stop=`{echo $bposts(1)^-^$posts_per_page | bc}
+pstart=$start
+pstop=$stop
+while(test $start -ge $bposts($#bposts)){
+	if(test $stop -lt $bposts($#bposts))
+		stop=$bposts($#bposts)
+	nstart=`{echo $stop^-^1 | bc}
+	nstop=`{echo $stop^-^$posts_per_page^-1 | bc}
+	pposts=`{
+		for(i in `{seq $stop $start | eval $sort})
+			if(test -d $site/src/$i)
+				echo $i
+	}
+	tags=all posts=$pposts print >$start^-^$stop.html
+	echo $"start^'-'^$"stop^'.html' >[1=2]
+	pstart=$start
+	pstop=$stop
+	start=`{echo $stop^-1 | bc}
+	stop=`{echo $start^-^$posts_per_page | bc}
+}
+cp `{ls [0-9]*-[0-9]*.html | sort -n | tail -1} index.html
+if(test -x /boot/factotum)
+	chmod +t [0-9]*.html [0-9]*-[0-9]*.html index.html
+
+# tags
+for(b in `{awk -F '/' '{print $3;}' tags | sort -u}){
+	btags=$b
+	mkdir -p tag/$btags
+	bposts=`{grep -e '^.*\/'$btags'$' tags | awk -F '/' '{print $1;}' | eval $sort}
+	start=$bposts(1)
+	stop=$bposts($#bposts)
+	tags=all posts=$bposts print >tag/$btags/index.html
+	echo tag/$btags/index.html >[1=2]
+	if(test -x /boot/factotum)
+		chmod +t tag tag/$btags tag/$btags/index.html
+}
--- /dev/null
+++ b/bin/dsrc
@@ -1,0 +1,31 @@
+#!/bin/rc
+# 2016-05-01T18:47:42-0400
+# Delete posts $low through $high.
+rfork e
+dhost=ur.inri.net
+fn usage {
+	echo usage: dsrc [ -r n ] [ -t n ] >[1=2]
+	exit usage
+}
+switch($1){
+case -r
+	site=/usr/sl/www/werc/sites/read.stanleylieber.com
+case -t
+	site=/usr/sl/www/werc/sites/tumblr.stanleylieber.com
+case *
+	usage
+}
+if(! ~ $sysname ur){
+	rcpu -h $dhost -c dsrc $*
+	exit
+}
+low=`{ls -p $site/src | sort -n | sed 1q}
+high=$2
+cd $site/src && rm -rf `{seq $low $high}
+{
+for(i in `{seq $low $high})
+	echo ',x/^'$i'\/.*\n/d'
+echo w
+echo w
+echo q
+} | sam -d $site/tags >[2]/dev/null
--- /dev/null
+++ b/bin/gf
@@ -1,0 +1,426 @@
+#!/bin/rc
+# Parse RSS feeds from livejournal or tumblr into BARF blog posts
+# for the specified site. If a post with a matching <link> already
+# exists, no new post will be created for that <item>. Accordingly,
+# the gf script may run slowly for sites with a large number of
+# existing posts. Tags will be created from each <category>.
+rfork en
+switch($1){
+case 1oct1993_lj
+	feed=http://feeds.feedburner.com/Sl/1oct1993
+	site=1oct1993.com
+	tags=(rss)
+case architecture
+	feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6e361b590b57934fb1e7c4e29339d619&_render=rss'
+	site=read.stanleylieber.com
+	tags=(architecture)
+case comics
+	feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6bc617a6b20aafd526affafc9a28a5d5&_render=rss'
+	site=read.stanleylieber.com
+	tags=(comics)
+case fg_lj
+	feed=http://feeds.feedburner.com/Sl/flamesgif
+	site=flamesgif.com
+	tags=(rss livejournal)
+case inri_lj
+	feed=http://feeds.feedburner.com/Sl/itrecords
+	site=inri.net
+	tags=(rss livejournal)
+case mf_lj
+	feed=http://feeds.feedburner.com/Sl/massivefictions
+	site=massivefictions.com
+	tags=(rss livejournal)
+case other_lj
+	feed=http://feeds.feedburner.com/SL/other
+	site=other.stanleylieber.com
+	tags=()
+case read
+	#feed=http://feeds.feedburner.com/SL/g/friends
+	#feed='http://pipes.yahoo.com/pipes/pipe.run?_id=f5d60acfd41497310d74900270192600&_render=rss'
+	feed='http://pipes.yahoo.com/pipes/pipe.run?_id=d1f7146306b019d96d768facf95eebd9&_render=rss'
+	site=test.stanleylieber.com
+	tags=()
+case sl_lj
+	feed=http://feeds.feedburner.com/ImNotReallyStanleyLieber
+	site=stanleylieber.com
+	tags=(rss livejournal)
+case sl_tumblr
+	feed=http://stanleylieber.tumblr.com/rss
+	site=stanleylieber.com
+	tags=(rss tumblr)
+case ta_lj
+	feed=http://feeds.feedburner.com/Sl/text_adventure
+	site=textadventure.stanleylieber.com
+	tags=(rss livejournal)
+case tech
+	feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6dd49be6e34a6871db9bcfc74d4b36b1&_render=rss'
+	site=read.stanleylieber.com
+	tags=(tech)
+case *
+	echo 'Usage: gf [ ... ]' >[1=2]
+	exit usage
+}
+
+file=/tmp/gf.$1
+werc=/usr/sl/www/werc
+
+if(test -f /boot/factotum)
+	cmd=hget
+if not
+	cmd='curl -s'
+
+fn get_feed{
+	$"cmd $feed >$file.work
+	{
+	echo '
+,s/
//g
+,s/\&quot;/\"/g
+,s/\&#34;/\"/g
+,s/\&amp;/\&/g
+,s/\&#38;/\&/g
+,s/\&#39;/''/g
+,s/\&#44;/,/g
+,s/\&#45;/-/g
+,s/\&#46;/\./g
+,s/\&#47;/\//g
+,s/\&#58;/:/g
+,s/\&#59;/;/g
+,s/\&lt;/</g
+,s/\&#60;/</g
+,s/\&#61;/=/g
+,s/\&gt;/>/g
+,s/\&#62;/>/g
+,s/\&#95;/_/g
+,s/\|/\&#124;/g
+,s/\n//g
+,s/<\/item>/\n<\/item>\n/g
+,s/^<item>/<item>\n/g
+,s/^[ ]*<guid/<guid/g
+,s/^<[\/i].*$//g
+,s/^[ ]*\n[ ]*$//g
+x/<description>.*<\/description>/ s/\n//g
+w
+q
+'
+	echo
+} | sam -d $file.work >[2]/dev/null >[1=2]
+	awk '/(^<item>|<guid|<link>|<pubDate>|<title>|<description>|<comments>|<category>|<\/item>)/ {print $0;}' $file.work >$file
+}
+
+fn get_tags{
+	switch($a_link){
+	case *1oct1993*
+		tags=($tags 1oct1993)
+	case *9front*
+		tags=($tags software plan9 9front)
+	case *amyearles* *pushedunder* *seaglass* *woolandwater*
+		tags=($tags amy_earles)
+	case *animenewsnetwork*
+		tags=($tags telescreen anime)
+	case *spikejapan*
+		tags=($tags japan comics manga telescreen anime)
+	case *ArchDaily* *archdaily*
+		tags=($tags archdaily architecture)
+	case *bldgblog*
+		tags=($tags bldgblog architecture)
+	case *kazuyosejima*
+		tags=($tags japan architecture)
+	case *Minimalissimo*
+		tags=($tags minimalissimo design architecture)
+	case *ArtFagCity* *artfagcity*
+		tags=($tags artfagcity art)
+	case *rhizome-fp*
+		tags=($tags rhizome-fp art)
+	case *rhizome*
+		tags=($tags rhizome art)
+	case *starwarsmodern*
+		tags=($tags starwarsmodern art)
+	case *tokyoartbeat*
+		tags=($tags tokyoartbeat japan art)
+	case *trendbeheer*
+		tags=($tags trendbeheer art)
+	case *ValentinaTanni*
+		tags=($tags valentinatanni art)
+	case *vvork*
+		tags=($tags vwork art)
+	case *auriea* *tale-of-tales* *taleoftales*
+		tags=($tags auriea)
+	case *basscomm* *closeoutwarrior* *crummysocks* *gamerrelocationproject* *protipoftheday* *PushButtonB* *pushbuttonb*
+		tags=($tags video_games basscomm)
+	case *benjaminmarra*
+		tags=($tags comics benjamin_marra)
+	case *boingboing*
+		tags=($tags boingboing)
+	case *bushinbooks* *henka*
+		tags=($tags budo)
+	case *alexaanddave* *CEREBUS* *Cerebus* *cerebus* *davesim* *gerhard*
+		tags=($tags comics cerebus gerhard)
+	case *coilhouse*
+		tags=($tags coilhouse)
+	case *arche-arc*
+		tags=($tags arche comics)
+	case *blaiselarmee*
+		tags=($tags blaise_larmee comics)
+	case *bleedingcool*
+		tags=($tags bleedingcool comics)
+	case *bobgreenberger*
+		tags=($tags bob_greengerger comics)
+	case *coldheatcomics*
+		tags=($tags coldheat comics)
+	case *comicbookresources*
+		tags=($tags cbr comics)
+	case *comicsbeat*
+		tags=($tags comicsbeat comics)
+	case *ComicsComics* *comicscomics*
+		tags=($tags comicscomics comics)
+	case *coveredblog*
+		tags=($tags coveredblog comics)
+	case *dcfifty-too*
+		tags=($tags dcfifty-too comics)
+	case *Destructoid* *destructoid*
+		tags=($tags destructoid video_games)
+	case *economist.com*
+		tags=($tags economist)
+	case *ferrandelgado*
+		tags=($tags ferran_delgado comics)
+	case *eddiecampbell*
+		tags=($tags eddie_campbell comics)
+	case *factualopinion*
+		tags=($tags factualopinion comics)
+	case *floating_world* *floatingworld*
+		tags=($tags floating_world comics)
+	case *frankmiller*
+		tags=($tags frank_miller comics)
+	case *humancolor*
+		tags=($tags humancolor comics)
+	case *jerkcity*
+		tags=($tags jerkcity comics)
+	case *newconstructionblog*
+		tags=($tags newconstruction manga comics)
+	case *ohdannyboy*
+		tags=($tags ohdannyboy comics)
+	case *pulphope*
+		tags=($tags pulphope comics)
+	case *pwbeat*
+		tags=($tags pwbeat comics)
+	case *reliablecomics*
+		tags=($tags reliablecomics comics)
+	case *reneefrench*
+		tags=($tags renee_french comics)
+	case *rickveitch*
+		tags=($tags rick_veitch comics)
+	case *smbc-comics*
+		tags=($tags smbc comics)
+	case *studygroup*
+		tags=($tags studygroup comics)
+	case *xkcd*
+		tags=($tags xkcd comics)
+	case *bowiesongs* *DavidBowie* *davidbowie*
+		tags=($tags music david_bowie)
+	case *designboom*
+		tags=($tags designboom design)
+	case *dezeen*
+		tags=($tags dezeen design)
+	case *infosthetics*
+		tags=($tags infosthetics design)
+	case *inhabitat*
+		tags=($tags inhabitat architecture design)
+	case *luigicolani*
+		tags=($tags luigicolani design)
+	case *mocoloco*
+		tags=($tags mocoloco design)
+	case *sydmead*
+		tags=($tags sydmead design)
+	case *dzima*
+		tags=($tags dzima)
+	case *bbcicecream*
+		tags=($tags bbcicecream fashion)
+	case *DamStyle *damstyle*
+		tags=($tags damstyle fashion)
+	case *facehunter*
+		tags=($tags facehunter fashion)
+	case *StilInBerlin*
+		tags=($tags germany fashion)
+	case *jstreets*
+		tags=($tags jstreets japan fashion)
+	case *stylefromtokyo*
+		tags=($tags stylefromtokyo japan fashion)
+	case *tokyofashion*
+		tags=($tags tokyofashion japan fashion)
+	case *flames.gif* *flamesgif*
+		tags=($tags flames.gif)
+	case *contemporary-home-computing*
+		tags=($tags software flames.gif)
+	case *kurzweil*
+		tags=($tags kurzweil future)
+	case *longnow*
+		tags=($tags longnow future)
+	case *OpenTheFuture*
+		tags=($tags openthefuture future)
+	case *golang* *blog.nella.org*
+		tags=($tags golang)
+	case *googlepluses*
+		tags=($tags google)
+	case *news.ycombinator.com*
+		tags=($tags hackernews hack)
+	case *seanbonner*
+		tags=($tags sean_bonner hack)
+	case *banriman*
+		tags=($tags banriman japan)
+	case *japansubculture*
+		tags=($tags japansubculture japan)
+	case *jeansnow*
+		tags=($tags jeansnow japan)
+	case *Kotaku* *kotaku*
+		tags=($tags kotaku video_games)
+	case *eforemario*
+		tags=($tags before_mario video_games)
+	case *nakakobooks*
+		tags=($tags books nakakobooks japan)
+	case *ozawamaria*
+		tags=($tags maria_ozawa japan)
+	case *shisaku.blogspot.com*
+		tags=($tags shisaku japan)
+	case *jimshooter*
+		tags=($tags comics jim_shooter)
+	case *LettersOfNote* *lettersofnote*
+		tags=($tags letters)
+	case *nasa*letters.rss*
+		tags=($tags nasa letters)
+	case *hellodamage* *manganews* *naokiurasawa* *samehat*
+		tags=($tags comics manga)
+	case *mangatraders*
+		tags=($tags p2p comics manga)
+	case *hortonheardawho*
+		tags=($tags hortonheardawho flickr nasa mars)
+	case *me-vs-gutenberg* *mevsgutenberg*
+		tags=($tags martin_sand)
+	case *marxy*
+		tags=($tags marxy)
+	case *etamodern*
+		tags=($tags metamodern)
+	case *aviationintel*
+		tags=($tags aviationintel mil)
+	case *aviationweek*
+		tags=($tags aviationweek mil)
+	case *codeonemagazine*
+		tags=($tags codeonemagazine mil)
+	case *geimint*
+		tags=($tags geimint mil)
+	case *momus* *mrstsk*
+		tags=($tags books music momus)
+	case *bjork* *toog*
+		tags=($tags music)
+	case *nasa.gov*
+		tags=($tags space nasa)
+	case *mongoliad*
+		tags=($tags neal_stephenson)
+	case *gaiman*
+		tags=($tags comics neil_gaiman)
+	case *nin.com* *feeds.nin.com*
+		tags=($tags music nin)
+	case *nix-os* *syssoftware*
+		tags=($tags plan9 nix)
+	case *bsdly* *OPENBSD* *OpenBSD* *openbsd* *scientist-home* *undeadly*
+		tags=($tags software openbsd)
+	case *godownmatthew* *mysticmilk* *petetoms*
+		tags=($tags pete_toms)
+	case *Pitchfork* *pitchfork*
+		tags=($tags music pitchfork)
+	case *9gridchan* *cat-v* *maht0x0r* *Plan9* *plan9*
+		tags=($tags software plan9)
+	case *FlauntTalks* *prince.org* *purpleinterviews* *wendyandlisa*
+		tags=($tags music prince)
+	case *commandcenter* *rob_pike*
+		tags=($tags golang plan9 rob_pike)
+	case *prometheus*
+		tags=($tags telescreen prometheus)
+	case *reddit.com*
+		tags=($tags reddit)
+	case *swtch.com*
+		tags=($tags golang plan9 rsc)
+	case *bunniestudios*
+		tags=($tags bunniestudios security)
+	case *jwz*
+		tags=($tags jwz security)
+	case *Krebs* *krebs*
+		tags=($tags krebs security)
+	case *scarybeastsecurity*
+		tags=($tags scarybeast security)
+	case *schneier*
+		tags=($tags bruce_schneier security)
+	case *chinchillakwak* *skwak*
+		tags=($tags skwak)
+	case *slashdot*
+		tags=($tags slashdot)
+	case *stanleylieber*
+		tags=($tags stanleylieber)
+	case *fastcompany*
+		tags=($tags fastcompany tech)
+	case *danharmon*
+		tags=($tags danharmon telescreen)
+	case *mindlessones*
+		tags=($tags mindlessones telescreen)
+	case *tcj.com*
+		tags=($tags comics tcj)
+	case *TEDblog* *ted.com*
+		tags=($tags ted)
+	case *ticom*
+		tags=($tags ticom security)
+	case *orrentfreak*
+		tags=($tags p2p torrentfreak)
+	case *ultra*culture*
+		tags=($tags ultraculture)
+	case *kleinletters*
+		tags=($tags comics todd_klein)
+	case *plaidstallions*
+		tags=($tags plaidstallions toys)
+	case *shojikawamori*
+		tags=($tags shojikawamori japan toys)
+	}
+	echo -n $tags
+}
+
+fn parse_posts{
+	ifs='
+' {
+		posts=`{cat $file}
+		for(i in `{seq 1 $#posts | sort -nr}){
+			post=`{echo $posts($i) | sed 's/>  </>\n</g' | grep -v -e '<comments>'}
+			if(! ~ $post ''){
+				a_title=`{echo $post | grep -e 'title>' | sed 's/^.*<title>//g; s/<\/title>.*$//g'}
+				a_date=`{echo $post | grep -e '<pubDate>' | sed 's/^.*<pubDate>//g; s/<\/pubDate>.*$//g'}
+				a_link=`{echo $post | grep -e '<link>' | sed 's/^.*<link>//g; s/<\/link>.*$//g; s/^.*http/http/g'}
+				a_tags=`{echo $post | grep -e '<category>' | sed 's/^.*<\/comments>//g; s/^.*<description>//g; s/^.*<\/description>//g; s/^.*<\/pubDate>//g; s/<category>/ /g; s/<\/category>//g; s/<dc.*$//g; s/^ //g; s/ $//g'}
+				a_tags=`{for(j in $a_tags){ echo $j | sed 's/^.*(<|>).*$//g'}}
+				a_body=`{echo $post | grep -e '<description>' | sed 's/^.*<description>//g; s/<\/description>.*$//g'}
+				a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
+				if(~ $#a_id 0)
+					a_id=1
+				while(test -d $werc/sites/$site/src/$a_id)
+					a_id=`{echo $a_id^+1 | bc}
+				if(! ~ $"a_link '' && ! ~ $"a_link `{cat $werc/sites/$site/src/*/link}){
+					mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
+					echo $"a_title >$werc/sites/$site/src/$a_id/title
+					echo $"a_date >$werc/sites/$site/src/$a_id/date
+					echo $"a_link >$werc/sites/$site/src/$a_id/link
+					echo $"a_body '</a></li></ul>' >$werc/sites/$site/src/$a_id/body
+					ifs=' ' {
+						for(j in `{get_tags}){
+							>$werc/sites/$site/src/$a_id/tags/$j
+							echo $a_id/tags/$j >>$werc/sites/$site/tags
+						}
+					}
+				}
+				if(test -f /boot/factotum && ~ $site *.stanleylieber.com)
+					for(i in `{f $werc/sites/$site/src/$a_id})
+						chmod +t $i
+			}
+		}
+	}
+}
+
+if(test -f /boot/factotum && test -f /rc/bin/hget)
+	webfs
+get_feed
+parse_posts
--- /dev/null
+++ b/bin/gk
@@ -1,0 +1,20 @@
+#!/bin/rc
+# Create an index of known_tags in $werc/sites/$site/known_tags
+if(! ~ $#1 0)
+	base=$1
+if not if(~ $#barf_root 1 && $#barf_base 1)
+	base=$barf_root/$"barf_base
+if not
+	base=`{pwd}
+
+if(test -f $base/_known_tags)
+	rm $base/_known_tags
+for(i in `{cat $base/etc/tags}){
+	grep -e '^.*\/'$i'$' $base/tags |
+	awk -F '/' '{print $3;}' |
+	sort |
+	uniq -c |
+	awk '{print $2 "	" $1;}' >>$base/_known_tags
+}
+if(test -f $base/_known_tags)
+	cp $base/_known_tags $base/known_tags
--- /dev/null
+++ b/bin/gr
@@ -1,0 +1,415 @@
+#!/bin/rc
+# Parse RSS feeds from Google Reader bundles into BULGE blog posts.
+# If a post with a matching <link> already exists, no new post will
+# be created for that <item>. Accordingly, the gr script may run
+# slowly for sites with a large number of existing posts. Tags will
+# be created from each <category>.
+rfork en
+switch($1){
+case architecture
+	feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6e361b590b57934fb1e7c4e29339d619&_render=rss'
+	site=read.stanleylieber.com
+	tags=(architecture)
+case comics
+	feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6bc617a6b20aafd526affafc9a28a5d5&_render=rss'
+	site=read.stanleylieber.com
+	tags=(comics)
+case friends
+	feed='https://www.google.com/reader/bundle/user%2F08193524211692385241%2Fbundle%2Ffriends'
+	site=read.stanleylieber.com
+	tags=(friends)
+case tech
+	feed='http://pipes.yahoo.com/pipes/pipe.run?_id=6dd49be6e34a6871db9bcfc74d4b36b1&_render=rss'
+	site=read.stanleylieber.com
+	tags=(tech)
+case *
+	echo usage: `{basename $0} '[ ... ]' >[1=2]
+	exit usage
+}
+
+file=/tmp/gr.$1
+werc=/usr/sl/www/werc
+
+if(test -f /boot/factotum)
+	cmd=hget
+if not
+	cmd='curl -s'
+
+fn f{ du -a $* | sed 's/^.*	//g' }
+
+fn get_feed{
+	$"cmd $feed >$file.work
+	{
+	echo '
+,s/\&quot;/\"/g
+,s/\&#34;/\"/g
+,s/\&amp;/\&/g
+,s/\&#38;/\&/g
+,s/\&#39;/\''/g
+,s/\&#44;/,/g
+,s/\&#45;/-/g
+,s/\&#46;/\./g
+,s/\&#47;/\//g
+,s/\&#58;/:/g
+,s/\&#59;/;/g
+,s/\&lt;/</g
+,s/\&#60;/</g
+,s/\&#61;/=/g
+,s/\&gt;/>/g
+,s/\&#62;/>/g
+,s/\&#95;/_/g
+,s/\|/\&#124;/g
+,/<div id="items">/d
+/<div id="sidebar">/,d
+,s/<h2 class="item-title">/\n<h2 class="item-title">/g
+,s/<div class="item">.*$/HJDIVIDER/g
+,s/\n//g
+,s/HJDIVIDER/\n/g
+1d
+w
+q
+'
+	echo
+} | sam -d $file.work >[2]/dev/null >[1=2]
+}
+
+fn get_tags{
+	switch($a_link){
+	case *1oct1993*
+		tags=($tags 1oct1993)
+	case *9front*
+		tags=($tags software plan9 9front)
+	case *amyearles* *pushedunder* *seaglass* *woolandwater*
+		tags=($tags amy_earles)
+	case *animenewsnetwork*
+		tags=($tags telescreen anime)
+	case *spikejapan*
+		tags=($tags japan comics manga telescreen anime)
+	case *ArchDaily* *archdaily*
+		tags=($tags archdaily architecture)
+	case *bldgblog*
+		tags=($tags bldgblog architecture)
+	case *kazuyosejima*
+		tags=($tags japan architecture)
+	case *Minimalissimo*
+		tags=($tags minimalissimo design architecture)
+	case *ArtFCity* *ArtFagCity* *artfagcity*
+		tags=($tags artfagcity art)
+	case *rhizome-fp*
+		tags=($tags rhizome-fp art)
+	case *rhizome*
+		tags=($tags rhizome art)
+	case *starwarsmodern*
+		tags=($tags starwarsmodern art)
+	case *tokyoartbeat*
+		tags=($tags tokyoartbeat japan art)
+	case *trendbeheer*
+		tags=($tags trendbeheer art)
+	case *ValentinaTanni*
+		tags=($tags valentinatanni art)
+	case *vvork*
+		tags=($tags vwork art)
+	case *auriea* *tale-of-tales* *taleoftales*
+		tags=($tags auriea)
+	case *basscomm* *closeoutwarrior* *crummysocks* *gamerrelocationproject* *protipoftheday* *PushButtonB* *pushbuttonb*
+		tags=($tags video_games basscomm)
+	case *benjaminmarra*
+		tags=($tags comics benjamin_marra)
+	case *boingboing*
+		tags=($tags boingboing)
+	case *bushinbooks* *henka*
+		tags=($tags budo)
+	case *alexaanddave* *CEREBUS* *Cerebus* *cerebus* *davesim* *gerhard*
+		tags=($tags comics cerebus gerhard)
+	case *coilhouse*
+		tags=($tags coilhouse)
+	case *arche-arc*
+		tags=($tags arche comics)
+	case *blaiselarmee*
+		tags=($tags blaise_larmee comics)
+	case *bleedingcool*
+		tags=($tags bleedingcool comics)
+	case *bobgreenberger*
+		tags=($tags bob_greengerger comics)
+	case *coldheatcomics*
+		tags=($tags coldheat comics)
+	case *comicbookresources*
+		tags=($tags cbr comics)
+	case *comicsbeat*
+		tags=($tags comicsbeat comics)
+	case *ComicsComics* *comicscomics*
+		tags=($tags comicscomics comics)
+	case *coveredblog*
+		tags=($tags coveredblog comics)
+	case *dcfifty-too*
+		tags=($tags dcfifty-too comics)
+	case *Destructoid* *destructoid*
+		tags=($tags destructoid video_games)
+	case *economist.com*
+		tags=($tags economist)
+	case *ferrandelgado*
+		tags=($tags ferran_delgado comics)
+	case *eddiecampbell*
+		tags=($tags eddie_campbell comics)
+	case *factualopinion*
+		tags=($tags factualopinion comics)
+	case *floating_world* *floatingworld*
+		tags=($tags floating_world comics)
+	case *frankmiller*
+		tags=($tags frank_miller comics)
+	case *humancolor*
+		tags=($tags humancolor comics)
+	case *jerkcity*
+		tags=($tags jerkcity comics)
+	case *newconstructionblog*
+		tags=($tags newconstruction manga comics)
+	case *ohdannyboy*
+		tags=($tags ohdannyboy comics)
+	case *pulphope*
+		tags=($tags pulphope comics)
+	case *pwbeat*
+		tags=($tags pwbeat comics)
+	case *reliablecomics*
+		tags=($tags reliablecomics comics)
+	case *reneefrench*
+		tags=($tags renee_french comics)
+	case *rickveitch*
+		tags=($tags rick_veitch comics)
+	case *smbc-comics*
+		tags=($tags smbc comics)
+	case *studygroup*
+		tags=($tags studygroup comics)
+	case *xkcd*
+		tags=($tags xkcd comics)
+	case *bowiesongs* *DavidBowie* *davidbowie*
+		tags=($tags music david_bowie)
+	case *designboom*
+		tags=($tags designboom design)
+	case *dezeen*
+		tags=($tags dezeen design)
+	case *infosthetics*
+		tags=($tags infosthetics design)
+	case *inhabitat*
+		tags=($tags inhabitat architecture design)
+	case *luigicolani*
+		tags=($tags luigicolani design)
+	case *mocoloco*
+		tags=($tags mocoloco design)
+	case *sydmead*
+		tags=($tags sydmead design)
+	case *dzima*
+		tags=($tags dzima)
+	case *bbcicecream*
+		tags=($tags bbcicecream fashion)
+	case *DamStyle *damstyle*
+		tags=($tags damstyle fashion)
+	case *facehunter*
+		tags=($tags facehunter fashion)
+	case *StilInBerlin*
+		tags=($tags germany fashion)
+	case *jstreets*
+		tags=($tags jstreets japan fashion)
+	case *Stilinberlin*
+		tags=($tags stilinberlin germany fashion)
+	case *stylefromtokyo*
+		tags=($tags stylefromtokyo japan fashion)
+	case *tokyofashion*
+		tags=($tags tokyofashion japan fashion)
+	case *flames.gif* *flamesgif*
+		tags=($tags flames.gif)
+	case *contemporary-home-computing*
+		tags=($tags software flames.gif)
+	case *kurzweil*
+		tags=($tags kurzweil future)
+	case *longnow*
+		tags=($tags longnow future)
+	case *OpenTheFuture*
+		tags=($tags openthefuture future)
+	case *golang* *blog.nella.org*
+		tags=($tags golang)
+	case *googlepluses*
+		tags=($tags google)
+	case *news.ycombinator.com*
+		tags=($tags hackernews hack)
+	case *seanbonner*
+		tags=($tags sean_bonner hack)
+	case *banriman*
+		tags=($tags banriman japan)
+	case *japansubculture*
+		tags=($tags japansubculture japan)
+	case *jeansnow*
+		tags=($tags jeansnow japan)
+	case *Kotaku* *kotaku*
+		tags=($tags kotaku video_games)
+	case *eforemario*
+		tags=($tags before_mario video_games)
+	case *nakakobooks*
+		tags=($tags books nakakobooks japan)
+	case *ozawamaria*
+		tags=($tags maria_ozawa japan)
+	case *ibuya246*
+		tags=($tags shibuya246 japan)
+	case *shisaku.blogspot.com*
+		tags=($tags shisaku japan)
+	case *jimshooter*
+		tags=($tags comics jim_shooter)
+	case *LettersOfNote* *lettersofnote*
+		tags=($tags letters)
+	case *nasa*letters.rss*
+		tags=($tags nasa letters)
+	case *hellodamage* *manganews* *naokiurasawa* *samehat*
+		tags=($tags comics manga)
+	case *mangatraders*
+		tags=($tags p2p comics manga)
+	case *hortonheardawho*
+		tags=($tags hortonheardawho flickr nasa mars)
+	case *me-vs-gutenberg* *mevsgutenberg*
+		tags=($tags martin_sand)
+	case *marxy*
+		tags=($tags marxy)
+	case *etamodern*
+		tags=($tags metamodern)
+	case *aviationintel*
+		tags=($tags aviationintel mil)
+	case *aviationweek*
+		tags=($tags aviationweek mil)
+	case *codeonemagazine*
+		tags=($tags codeonemagazine mil)
+	case *geimint*
+		tags=($tags geimint mil)
+	case *bjork*
+		tags=($tags bjork music)
+	case *momus* *mrstsk*
+		tags=($tags books momus music)
+	case *toog*
+		tags=($tags toog music)
+	case *nasa.gov*
+		tags=($tags space nasa)
+	case *mongoliad*
+		tags=($tags neal_stephenson)
+	case *gaiman*
+		tags=($tags comics neil_gaiman)
+	case *nin.com* *feeds.nin.com*
+		tags=($tags music nin)
+	case *nix-os* *syssoftware*
+		tags=($tags plan9 nix)
+	case *bsdly* *OPENBSD* *OpenBSD* *openbsd* *scientist-home* *undeadly*
+		tags=($tags software openbsd)
+	case *godownmatthew* *mysticmilk* *petetoms*
+		tags=($tags pete_toms)
+	case *Pitchfork* *pitchfork*
+		tags=($tags music pitchfork)
+	case *9gridchan* *cat-v* *maht0x0r* *Plan9* *plan9*
+		tags=($tags software plan9)
+	case *FlauntTalks* *prince.org* *purpleinterviews* *wendyandlisa*
+		tags=($tags music prince)
+	case *commandcenter* *rob_pike*
+		tags=($tags golang plan9 rob_pike)
+	case *prometheus*
+		tags=($tags telescreen prometheus)
+	case *reddit.com*
+		tags=($tags reddit)
+	case *swtch.com*
+		tags=($tags golang plan9 rsc)
+	case *bunniestudios*
+		tags=($tags bunniestudios security)
+	case *jwz*
+		tags=($tags jwz security)
+	case *Krebs* *krebs*
+		tags=($tags krebs security)
+	case *scarybeastsecurity*
+		tags=($tags scarybeast security)
+	case *schneier*
+		tags=($tags bruce_schneier security)
+	case *chinchillakwak* *skwak*
+		tags=($tags skwak)
+	case *slashdot*
+		tags=($tags slashdot)
+	case *stanleylieber*
+		tags=($tags stanleylieber)
+	case *fastcompany*
+		tags=($tags fastcompany tech)
+	case *danharmon*
+		tags=($tags danharmon telescreen)
+	case *mindlessones*
+		tags=($tags mindlessones telescreen)
+	case *tcj.com*
+		tags=($tags comics tcj)
+	case *TEDblog* *ted.com*
+		tags=($tags ted)
+	case *ticom*
+		tags=($tags ticom security)
+	case *orrentfreak*
+		tags=($tags p2p torrentfreak)
+	case *ultra*culture*
+		tags=($tags ultraculture)
+	case *kleinletters*
+		tags=($tags comics todd_klein)
+	case *kennercollector*
+		tags=($tags kennercollector toys)
+	case *plaidstallions*
+		tags=($tags plaidstallions toys)
+	case *shojikawamori*
+		tags=($tags shojikawamori japan toys)
+	case *ruinedcartridge*
+		tags=($tags basscomm video_games)
+	}
+	echo -n $tags
+}
+
+fn parse_posts{
+	ifs='
+' {
+		for(post in `{sort -r $file.work}){
+			if(! ~ $post ''){
+				a_title=`{echo $post | sed 's/^.*<h2 class="item-title"><div class="">//g' | sed 's/<div class="item-info">.*$//g' | htmlfmt}
+				if(~ $#a_title 0)
+					a_title=`{echo $post | sed 's/^.*<div class="item-info">//g' | sed 's/<div class="item-annotations">.*$//g' | htmlfmt}
+				if(~ $#a_title 0)
+					a_title=fake
+				a_link=`{echo $post | sed 's/^.*<h2 class="item-title"><div class="">//g' | sed 's/<div class="item-info">.*$//g' | htmlfmt -a | sed 's/^.*\[//g' | sed 's/\].*$//g' | sed 's/ .*$//g'}
+				if(~ $#a_link 0 || ! ~ $"a_link http*)
+					a_link=`{echo $post | sed 's/^.*<h2 class="item-title"><div class="">//g' | sed 's/<div class="item-info">.*$//g' | sed 's/^.*<a href="//g' | sed 's/\".*$//g' | sed 's/^.*http/http/g' | sed 's/ .*$//g'}
+				if(~ $#a_link 0 || ! ~ $"a_link http*)
+					a_link=`{echo $post | sed 's/^.*<div class="item-info">//g' | sed 's/<div class="item-annotations">.*$//g' | htmlfmt -a | sed 's/^.*\[//g' | sed 's/\].*$//g' | sed 's/ .*$//g'}
+				if(~ $#a_link 0 || ! ~ $"a_link http*)
+					a_link=`{echo $post | sed 's/^.*<div class="item-info">//g' | sed 's/<div class="item-annotations">.*$//g' | sed 's/^.*<a href="//g' | sed 's/" class="f">.*$//g' | sed 's/\".*$//g' | sed 's/^.*http/http/g' | sed 's/ .*$//g'}
+				a_link=$a_link(1)
+				if(~ $#a_link 0 || ~ $"a_link '' || ! ~ $"a_link http*)
+					a_link=fake
+				if(! ~ $#a_link 1)
+					a_link=`{echo $a_link | awk '{print $1;}'}
+				a_date=`{date -n}
+				a_body=`{echo $post | sed 's/^.*<div class="item-body">//g' | sed 's/<div class="clear">.*$//g'}
+				if(~ $#a_body 0)
+					a_body=fake
+				a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
+				if(~ $#a_id 0)
+					a_id=1
+				while(test -d $werc/sites/$site/src/$a_id)
+					a_id=`{echo $a_id^+1 | bc}
+				if(! ~ $"a_link `{cat $werc/sites/$site/src/*/link}){
+					mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
+					echo $"a_title >$werc/sites/$site/src/$a_id/title
+					echo $"a_date >$werc/sites/$site/src/$a_id/date
+					echo $"a_link >$werc/sites/$site/src/$a_id/link
+					echo $"a_body '</a></li></ul>' >$werc/sites/$site/src/$a_id/body
+					ifs=' ' {
+						for(j in `{get_tags}){
+							>$werc/sites/$site/src/$a_id/tags/$j
+							echo $a_id/tags/$j >>$werc/sites/$site/tags
+						}
+					}
+				}
+				if(test -f /boot/factotum)
+					for(i in `{f $werc/sites/$site/src/$a_id})
+						chmod +t $i
+			}
+		}
+	}
+}
+
+if(test -f /boot/factotum && test -f /rc/bin/hget)
+	webfs
+get_feed
+parse_posts
--- /dev/null
+++ b/bin/gt
@@ -1,0 +1,23 @@
+#!/bin/rc
+# Create an index of tags in $werc/sites/$site/tags. BULGE
+# greps this index when running a search on a given tag.
+# This file is also maintained by the bin/g* commands, or
+# when adding posts through the web interface.
+if(! ~ $#1 0)
+	base=$1
+if not if(~ $#barf_root 1 && $#barf_base 1)
+	base=$barf_root/$"barf_base
+if not
+	base=`{pwd}
+
+if(test -f $base/_tags)
+	rm $base/_tags
+builtin cd $base/src
+ls -p |
+sort -n |
+xargs du -a |
+sed 's/^.*	//g' |
+grep -e '^[0-9]*\/tags' |
+grep -v -e '^.*\/tags$' >>$base/_tags
+if(test -s $base/_tags)
+	cp $base/_tags $base/tags
--- /dev/null
+++ b/bin/gy
@@ -1,0 +1,455 @@
+#!/bin/rc
+# Parse XML RSS feeds from Yahoo Pipes into BARF blog posts
+# for the specified site. If a post with a matching _link_ already
+# exists, no new post will be created for that item. Accordingly,
+# the gy script may run slowly for sites with a large number of
+# existing posts. Tags will be created according to the rules
+# defined in the get_tags() function.
+#
+# Requires 20h's xmlpull and rssread.
+rfork en
+switch($1){
+case read
+	feed='http://pipes.yahoo.com/pipes/pipe.run?_id=d1f7146306b019d96d768facf95eebd9&_render=rss'
+	site=read.stanleylieber.com
+	tags=()
+case *
+	echo 'Usage: gy [ ... ]' >[1=2]
+	exit usage
+}
+
+file=/tmp/gy.$1
+werc=/usr/sl/www/werc
+
+if(test -f /boot/factotum)
+	cmd=hget
+if not
+	cmd='curl -s'
+
+fn cram{
+	ssam '
+,s/^link:.*$/HJDIVIDER&HJDIVIDER/g
+,s/^title:.*$/HJDIVIDER&HJDIVIDER/g
+,s/\n//g
+,s/HJDIVIDERtitle:/\n&/g
+	'
+}
+
+fn scape{
+	ssam '
+,s/
//g
+,s/\&quot;/\"/g
+,s/\&#34;/\"/g
+,s/\&amp;/\&/g
+,s/\&#38;/\&/g
+,s/\&#39;/''/g
+,s/\&#44;/,/g
+,s/\&#45;/-/g
+,s/\&#46;/\./g
+,s/\&#47;/\//g
+,s/\&#58;/:/g
+,s/\&#59;/;/g
+,s/\&lt;/</g
+,s/\&#60;/</g
+,s/\&#61;/=/g
+,s/\&gt;/>/g
+,s/\&#62;/>/g
+,s/\&#95;/_/g
+,s/\|/\&#124;/g
+	'
+}
+
+fn get_posts{
+	$"cmd $feed | rssread | cram | scape >$file
+	echo >>$file
+}
+
+fn get_tags{
+	switch($a_link){
+	case *1oct1993*
+		tags=($tags 1oct1993)
+	case *9front*
+		tags=($tags software plan9 9front)
+	case *organicmentalcore* 
+		tags=($tags aleks)
+	case *amyearles* *etsy.com* *pushedunder* *seaglass* *woolandwater*
+		tags=($tags amy_earles)
+	case *animenewsnetwork*
+		tags=($tags telescreen anime)
+	case *spikejapan*
+		tags=($tags japan comics manga telescreen anime)
+	case *augmented.org*
+		tags=($tags augmented.org ar)
+	case *ArchDaily* *archdaily*
+		tags=($tags archdaily architecture)
+	case *bldgblog*
+		tags=($tags bldgblog architecture)
+	case *kazuyosejima*
+		tags=($tags japan architecture)
+	case *Minimalissimo*
+		tags=($tags minimalissimo design architecture)
+	case *ArtFagCity* *ArtFCity* *artfagcity*
+		tags=($tags artfagcity art)
+	case *rhizome-fp*
+		tags=($tags rhizome-fp art)
+	case *rhizome*
+		tags=($tags rhizome art)
+	case *starwarsmodern*
+		tags=($tags starwarsmodern art)
+	case *tokyoartbeat*
+		tags=($tags tokyoartbeat japan art)
+	case *trendbeheer*
+		tags=($tags trendbeheer art)
+	case *ValentinaTanni*
+		tags=($tags valentinatanni art)
+	case *vvork*
+		tags=($tags vwork art)
+	case *auriea* *tale-of-tales* *taleoftales*
+		tags=($tags auriea)
+	case *basscomm* *closeoutwarrior* *crummysocks* *gamerrelocationproject* *protipoftheday* *PushButtonB* *pushbuttonb*
+		tags=($tags video_games basscomm)
+	case *benjaminmarra*
+		tags=($tags comics benjamin_marra)
+	case *boingboing*
+		tags=($tags boingboing)
+	case *bushinbooks* *henka*
+		tags=($tags budo)
+	case *alexaanddave* *CEREBUS* *Cerebus* *cerebus* *davesim* *gerhard*
+		tags=($tags comics cerebus gerhard)
+	case *coilhouse*
+		tags=($tags coilhouse)
+	case *arche-arc*
+		tags=($tags arche comics)
+	case *bitolithic.com*
+		tags=($tags bitolithic comics)
+	case *blaiselarmee*
+		tags=($tags blaise_larmee comics)
+	case *bleedingcool*
+		tags=($tags bleedingcool comics)
+	case *bobgreenberger*
+		tags=($tags bob_greengerger comics)
+	case *coldheatcomics*
+		tags=($tags coldheat comics)
+	case *comicbookresources*
+		tags=($tags cbr comics)
+	case *comicsbeat*
+		tags=($tags comicsbeat comics)
+	case *ComicsComics* *comicscomics*
+		tags=($tags comicscomics comics)
+	case *coveredblog*
+		tags=($tags coveredblog comics)
+	case *dcfifty-too*
+		tags=($tags dcfifty-too comics)
+	case *Destructoid* *destructoid*
+		tags=($tags destructoid video_games)
+	case *economist.com*
+		tags=($tags economist)
+	case *brucesterling.tumblr.com*
+		tags=($tags bruce_sterling)
+	case *thecreatorsproject*
+		tags=($tags thecreatorsproject)
+	case *ferrandelgado*
+		tags=($tags ferran_delgado comics)
+	case *eddiecampbell*
+		tags=($tags eddie_campbell comics)
+	case *factualopinion*
+		tags=($tags factualopinion comics)
+	case *floating_world* *floatingworld*
+		tags=($tags floating_world comics)
+	case *frankmiller*
+		tags=($tags frank_miller comics)
+	case *humancolor*
+		tags=($tags humancolor comics)
+	case *jerkcity*
+		tags=($tags jerkcity comics)
+	case *maakies.com*
+		tags=($tags tony_millionaire maakies comics)
+	case *newconstructionblog*
+		tags=($tags newconstruction manga comics)
+	case *ohdannyboy*
+		tags=($tags ohdannyboy comics)
+	case *pulphope*
+		tags=($tags pulphope comics)
+	case *pwbeat*
+		tags=($tags pwbeat comics)
+	case *reliablecomics*
+		tags=($tags reliablecomics comics)
+	case *reneefrench*
+		tags=($tags renee_french comics)
+	case *rickveitch*
+		tags=($tags rick_veitch comics)
+	case *royalboiler*
+		tags=($tags royalboiler comics)
+	case *smbc-comics*
+		tags=($tags smbc comics)
+	case *studygroup*
+		tags=($tags studygroup comics)
+	case *xkcd*
+		tags=($tags xkcd comics)
+	case *bowiesongs* *DavidBowie* *davidbowie*
+		tags=($tags music david_bowie)
+	case *designboom*
+		tags=($tags designboom design)
+	case *dezeen*
+		tags=($tags dezeen design)
+	case *infosthetics*
+		tags=($tags infosthetics design)
+	case *inhabitat*
+		tags=($tags inhabitat architecture design)
+	case *luigicolani*
+		tags=($tags luigicolani design)
+	case *mocoloco*
+		tags=($tags mocoloco design)
+	case *sydmead*
+		tags=($tags sydmead design)
+	case *dzima*
+		tags=($tags dzima)
+	case *bbcicecream*
+		tags=($tags bbcicecream fashion)
+	case *DamStyle *damstyle*
+		tags=($tags damstyle fashion)
+	case *facehunter*
+		tags=($tags facehunter fashion)
+	case *StilInBerlin* *Stilinberlin*
+		tags=($tags germany fashion)
+	case *jstreets*
+		tags=($tags jstreets japan fashion)
+	case *stylefromtokyo*
+		tags=($tags stylefromtokyo japan fashion)
+	case *tokyofashion*
+		tags=($tags tokyofashion japan fashion)
+	case *flames.gif* *flamesgif*
+		tags=($tags flames.gif)
+	case *contemporary-home-computing*
+		tags=($tags software flames.gif)
+	case *acceler8or.com*
+		tags=($tags acceler8or future)
+	case *afrocyberpunk.wordpress.com*
+		tags=($tags afrocyberpunk future)
+	case *hyperallergic.com*
+		tags=($tags hyperallergic future)
+	case *kurzweil*
+		tags=($tags kurzweil future)
+	case *longnow*
+		tags=($tags longnow future)
+	case *OpenTheFuture*
+		tags=($tags openthefuture future)
+	case *theverge.com*
+		tags=($tags theverge future)
+	case *golang* *blog.nella.org*
+		tags=($tags golang)
+	case *googlepluses*
+		tags=($tags google)
+	case *news.ycombinator.com*
+		tags=($tags hackernews hack)
+	case *seanbonner*
+		tags=($tags sean_bonner hack)
+	case *banriman*
+		tags=($tags banriman japan)
+	case *japansubculture*
+		tags=($tags japansubculture japan)
+	case *jeansnow*
+		tags=($tags jeansnow japan)
+	case *Kotaku* *kotaku*
+		tags=($tags kotaku video_games)
+	case *eforemario*
+		tags=($tags before_mario video_games)
+	case *instagram* *web.stagram.com*
+		tags=($tags instagram)
+	case *nakakobooks*
+		tags=($tags books nakakobooks japan)
+	case *ozawamaria*
+		tags=($tags maria_ozawa japan)
+	case *Shibuya246*
+		tags=($tags shibuya246 japan)
+	case *shisaku.blogspot.com*
+		tags=($tags shisaku japan)
+	case *jimshooter*
+		tags=($tags comics jim_shooter)
+	case *LettersOfNote* *lettersofnote*
+		tags=($tags letters)
+	case *nasa*letters.rss*
+		tags=($tags nasa letters)
+	case *kore.livejournal.com*
+		tags=($tags kore livejournal)
+	case *real-funny-lady.livejournal.com*
+		tags=($tags rea_funny_lady livejournal)
+	case *vintage-ads.livejournal.com*
+		tags=($tags vintage_ads livejournal)
+	case *hellodamage*
+		tags=($tags comics hellodamage manga)
+	case *manganews*
+		tags=($tags comics manganews manga)
+	case *naokiurasawa*
+		tags=($tags comics naokiurasawa manga)
+	case *samehat*
+		tags=($tags comics samehat manga)
+	case *mangatraders*
+		tags=($tags p2p comics manga)
+	case *hortonheardawho*
+		tags=($tags hortonheardawho flickr nasa mars)
+	case *marstoday.com*
+		tags=($tags marstoday mars)
+	case *kielbryant*
+		tags=($tags kiel_bryant flickr)
+	case *flickr*paoru*
+		tags=($tags paoru flickr)
+	case *me-vs-gutenberg* *mevsgutenberg*
+		tags=($tags martin_sand)
+	case *marxy*
+		tags=($tags marxy)
+	case *etamodern*
+		tags=($tags metamodern)
+	case *aviationintel*
+		tags=($tags aviationintel mil)
+	case *aviationweek*
+		tags=($tags aviationweek mil)
+	case *codeonemagazine*
+		tags=($tags codeonemagazine mil)
+	case *geimint*
+		tags=($tags geimint mil)
+	case *momus* *mrstsk*
+		tags=($tags books music momus)
+	case *bjork*
+		tags=($tags bjork music)
+	case *c-h-r-i-s-c-a-r-t-e-r*
+		tags=($tags chris_carter music)
+	case *toog*
+		tags=($tags toog music)
+	case *nasa.gov*
+		tags=($tags space nasa)
+	case *mongoliad*
+		tags=($tags neal_stephenson)
+	case *gaiman*
+		tags=($tags comics neil_gaiman)
+	case *111567547782666546187*
+		tags=($tags daniel_rehn gplus)
+	case *114408853762245370512*
+		tags=($tags francesco_cardi gplus)
+	case *106673611724400311137*
+		tags=($tags mark_jondahl gplus)
+	case *113974084460235989118*
+		tags=($tags jose_nazario gplus)
+	case *102089697005520721324*
+		tags=($tags zaki_hasan gplus)
+	case *nin.com* *feeds.nin.com*
+		tags=($tags music nin.com nin)
+	case *ninofficialnews.tumblr.com*
+		tags=($tags music tumblr nin)
+	case *nix-os* *syssoftware*
+		tags=($tags plan9 nix)
+	case *bsdly* *OPENBSD* *OpenBSD* *openbsd* *scientist-home* *undeadly*
+		tags=($tags software openbsd)
+	case *godownmatthew* *mysticmilk* *petetoms*
+		tags=($tags pete_toms)
+	case *Pitchfork* *pitchfork*
+		tags=($tags music pitchfork)
+	case *9gridchan* *cat-v* *maht0x0r* *Plan9* *plan9*
+		tags=($tags software plan9)
+	case *FlauntTalks* *prince.org* *purpleinterviews* *wendyandlisa*
+		tags=($tags music prince)
+	case *101960720994009339267*
+		tags=($tags gplus rob_pike)
+	case *commandcenter* *rob_pike*
+		tags=($tags blogger rob_pike)
+	case *prometheus*
+		tags=($tags telescreen prometheus)
+	case *reddit.com*
+		tags=($tags reddit)
+	case *swtch.com*
+		tags=($tags golang plan9 rsc)
+	case *bunniestudios*
+		tags=($tags bunniestudios security)
+	case *jwz*
+		tags=($tags jwz security)
+	case *Krebs* *krebs*
+		tags=($tags krebs security)
+	case *scarybeastsecurity*
+		tags=($tags scarybeast security)
+	case *schneier*
+		tags=($tags bruce_schneier security)
+	case *chinchillakwak* *skwak*
+		tags=($tags skwak)
+	case *slashdot*
+		tags=($tags slashdot)
+	case *spaceref.com*
+		tags=($tags space spaceref)
+	case *StanleyLieber* *stanleylieber*
+		tags=($tags stanleylieber)
+	case *fastcompany*
+		tags=($tags fastcompany tech)
+	case *gizchina.com*
+		tags=($tags gizchina tech)
+	case *danharmon*
+		tags=($tags danharmon telescreen)
+	case *mindlessones*
+		tags=($tags mindlessones telescreen)
+	case *tcj.com*
+		tags=($tags comics tcj)
+	case *TEDBlog* *TEDblog* *ted.com*
+		tags=($tags ted)
+	case *ticom*
+		tags=($tags ticom security)
+	case *orrentfreak*
+		tags=($tags p2p torrentfreak)
+	case *ultra*culture*
+		tags=($tags ultraculture)
+	case *kleinletters*
+		tags=($tags comics todd_klein)
+	case *collectiondx.com*
+		tags=($tags collectiondx toys)
+	case *kennercollector.com*
+		tags=($tags kennercollector toys)
+	case *plaidstallions*
+		tags=($tags plaidstallions toys)
+	case *shojikawamori*
+		tags=($tags shojikawamori japan toys)
+	case *tumblr*
+		tags=($tags tumblr)
+	case *ruinedcartridge*
+		tags=($tags ruinedcartridge basscomm video_games)
+	}
+	echo -n $tags
+}
+
+fn parse_posts{
+	ifs='
+' {
+		posts=`{cat $file}
+		for(i in `{seq 1 $#posts | sort -nr}){
+			post=$posts($i)
+			if(! ~ $post ''){
+				a_title=`{echo $post | sed 's/^.*HJDIVIDERtitle: //g; s/HJDIVIDER.*$//g'}
+				a_date=`{date}
+				a_link=`{echo $post | sed 's/^.*HJDIVIDERlink:  //g; s/HJDIVIDER.*$//g'}
+				a_body=`{echo $post | sed 's/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g'}
+				a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
+				if(~ $#a_id 0)
+					a_id=1
+				while(test -d $werc/sites/$site/src/$a_id)
+					a_id=`{echo $a_id^+1 | bc}
+				if(! ~ $"a_link '' && ! grep -s `{echo $"a_link | md5sum} $werc/sites/$site/links){
+					mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
+					echo $"a_title >$werc/sites/$site/src/$a_id/title
+					echo $"a_date >$werc/sites/$site/src/$a_id/date
+					echo $a_link(1) >$werc/sites/$site/src/$a_id/link
+					echo $a_link(1) | md5sum >>$werc/sites/$site/links
+					echo $"a_body '</a></li></ul>' >$werc/sites/$site/src/$a_id/body
+					ifs=' ' {
+						for(j in `{get_tags}){
+							>$werc/sites/$site/src/$a_id/tags/$j
+							echo $a_id/tags/$j >>$werc/sites/$site/tags
+						}
+					}
+				}
+				if(test -f /boot/factotum && ~ $site *.stanleylieber.com && test -d $werc/sites/$site/src/$a_id)
+					chmod +t $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/* $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/tags/*
+			}
+		}
+	}
+}
+
+if(test -f /boot/factotum && test -f /rc/bin/hget)
+	webfs
+get_posts
+parse_posts
--- /dev/null
+++ b/bin/gz
@@ -1,0 +1,119 @@
+#!/bin/rc
+# Parse XML RSS feeds into BARF blog posts for the specified site.
+# If a post with a matching _link_ already exists, no new post will
+# be created for that item. Tags will be created according to the rules
+# defined in the get_tags() function.
+#
+# The file argument should point to a file containing one line per feed,
+# with fields separated by the | character, in the following format:
+#
+#	http://feeds.feedburner.com/ImNotReallyStanleyLieber|stanleylieber
+#
+# where the first field is the feed URL and each addition field is a tag.
+#
+# Requires 20h's xmlpull and rssread.
+rfork en
+switch($1){
+case /*
+	feeds=$1
+	site=read.stanleylieber.com
+	tags=()
+case *
+	echo 'Usage: gz file' >[1=2]
+	exit usage
+}
+
+file=/tmp/gz.$pid
+werc=/usr/sl/www/werc
+
+if(test -f /boot/factotum)
+	cmd=hget
+if not
+	cmd='curl -s'
+
+fn cram{
+	ssam '
+,s/^link:.*$/HJDIVIDER&HJDIVIDER/g
+,s/^title:.*$/HJDIVIDER&HJDIVIDER/g
+,s/\n//g
+,s/HJDIVIDERtitle:/\n&/g
+	'
+}
+
+fn scape{
+	ssam '
+,s/
//g
+,s/\&quot;/\"/g
+,s/\&#34;/\"/g
+,s/\&amp;/\&/g
+,s/\&#38;/\&/g
+,s/\&#39;/''/g
+,s/\&#44;/,/g
+,s/\&#45;/-/g
+,s/\&#46;/\./g
+,s/\&#47;/\//g
+,s/\&#58;/:/g
+,s/\&#59;/;/g
+,s/\&lt;/</g
+,s/\&#60;/</g
+,s/\&#61;/=/g
+,s/\&gt;/>/g
+,s/\&#62;/>/g
+,s/\&#95;/_/g
+,s/\|/\&#124;/g
+	'
+}
+
+fn get_posts{
+	$"cmd $"feed | rssread | cram | scape >$file
+	echo >>$file
+}
+
+fn parse_posts{
+	ifs='
+' {
+		posts=`{cat $file}
+		for(i in `{seq 1 $#posts | sort -nr}){
+			post=$posts($i)
+			if(! ~ $post ''){
+				a_title=`{echo $post | sed 's/^.*HJDIVIDERtitle: //g; s/HJDIVIDER.*$//g'}
+				a_date=`{date}
+				a_link=`{echo $post | sed 's/^.*HJDIVIDERlink:  //g; s/HJDIVIDER.*$//g'}
+				a_body=`{echo $post | sed 's/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g'}
+				a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
+				if(~ $#a_id 0)
+					a_id=1
+				while(test -d $werc/sites/$site/src/$a_id)
+					a_id=`{echo $a_id^+1 | bc}
+				if(! ~ $"a_link '' && ! grep -s `{echo $"a_link | md5sum} $werc/sites/$site/links){
+					mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
+					echo $"a_title >$werc/sites/$site/src/$a_id/title
+					echo $"a_date >$werc/sites/$site/src/$a_id/date
+					echo $a_link(1) >$werc/sites/$site/src/$a_id/link
+					echo $a_link(1) | md5sum >>$werc/sites/$site/links
+					if(~ $a_link(1) *staticflickr.com*)
+						echo '<img src="'$"a_link'">' >$werc/sites/$site/src/$a_id/body
+					echo $"a_body '</a></li></ul>' >>$werc/sites/$site/src/$a_id/body
+					ifs=' ' {
+						for(j in $tags){
+							>$werc/sites/$site/src/$a_id/tags/$j
+							echo $a_id/tags/$j >>$werc/sites/$site/tags
+						}
+					}
+				}
+				if(test -f /boot/factotum && ~ $site *.stanleylieber.com && test -d $werc/sites/$site/src/$a_id)
+					chmod +t $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/* $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/tags/*
+			}
+		}
+	}
+}
+
+if(test -f /boot/factotum && test -f /rc/bin/hget)
+	webfs
+for(i in `{grep -v -e '^#' $feeds}){
+	feed=`{echo $"i | sed 's/\|.*$//g'}
+	tags=`{echo $"i | sed 's/\|/ /g'}
+	tags=$tags(2-)
+	get_posts
+	parse_posts
+}
--- /dev/null
+++ b/bin/gz.read
@@ -1,0 +1,119 @@
+#!/bin/rc
+# Parse XML RSS feeds into BARF blog posts for the specified site.
+# If a post with a matching _link_ already exists, no new post will
+# be created for that item. Tags will be created according to the rules
+# defined in the get_tags() function.
+#
+# The file argument should point to a file containing one line per feed,
+# with fields separated by the | character, in the following format:
+#
+#	http://feeds.feedburner.com/ImNotReallyStanleyLieber|stanleylieber
+#
+# where the first field is the feed URL and each addition field is a tag.
+#
+# Requires 20h's xmlpull and rssread.
+rfork en
+switch($1){
+case /*
+	feeds=$1
+	site=read.stanleylieber.com
+	tags=()
+case *
+	echo 'Usage: gz file' >[1=2]
+	exit usage
+}
+
+file=/tmp/gz.$pid
+werc=/usr/sl/www/werc
+
+if(test -f /boot/factotum)
+	cmd=hget
+if not
+	cmd='curl -s'
+
+fn cram{
+	ssam '
+,s/^link:.*$/HJDIVIDER&HJDIVIDER/g
+,s/^title:.*$/HJDIVIDER&HJDIVIDER/g
+,s/\n//g
+,s/HJDIVIDERtitle:/\n&/g
+	'
+}
+
+fn scape{
+	ssam '
+,s/
//g
+,s/\&quot;/\"/g
+,s/\&#34;/\"/g
+,s/\&amp;/\&/g
+,s/\&#38;/\&/g
+,s/\&#39;/''/g
+,s/\&#44;/,/g
+,s/\&#45;/-/g
+,s/\&#46;/\./g
+,s/\&#47;/\//g
+,s/\&#58;/:/g
+,s/\&#59;/;/g
+,s/\&lt;/</g
+,s/\&#60;/</g
+,s/\&#61;/=/g
+,s/\&gt;/>/g
+,s/\&#62;/>/g
+,s/\&#95;/_/g
+,s/\|/\&#124;/g
+	'
+}
+
+fn get_posts{
+	$"cmd $"feed | rssread | cram | scape >$file
+	echo >>$file
+}
+
+fn parse_posts{
+	ifs='
+' {
+		posts=`{cat $file}
+		for(i in `{seq 1 $#posts | sort -nr}){
+			post=$posts($i)
+			if(! ~ $post ''){
+				a_title=`{echo $post | sed 's/^.*HJDIVIDERtitle: //g; s/HJDIVIDER.*$//g'}
+				a_date=`{date}
+				a_link=`{echo $post | sed 's/^.*HJDIVIDERlink:  //g; s/HJDIVIDER.*$//g'}
+				a_body=`{echo $post | sed 's/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g'}
+				a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
+				if(~ $#a_id 0)
+					a_id=1
+				while(test -d $werc/sites/$site/src/$a_id)
+					a_id=`{echo $a_id^+1 | bc}
+				if(! ~ $"a_link '' && ! grep -s `{echo $"a_link | md5sum} $werc/sites/$site/links){
+					mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
+					echo $"a_title >$werc/sites/$site/src/$a_id/title
+					echo $"a_date >$werc/sites/$site/src/$a_id/date
+					echo $a_link(1) >$werc/sites/$site/src/$a_id/link
+					echo $a_link(1) | md5sum >>$werc/sites/$site/links
+					if(~ $a_link(1) *staticflickr.com*)
+						echo '<img src="'$"a_link'">' >$werc/sites/$site/src/$a_id/body
+					echo $"a_body '</a></li></ul>' >>$werc/sites/$site/src/$a_id/body
+					ifs=' ' {
+						for(j in $tags){
+							>$werc/sites/$site/src/$a_id/tags/$j
+							echo $a_id/tags/$j >>$werc/sites/$site/tags
+						}
+					}
+				}
+				if(test -f /boot/factotum && ~ $site *.stanleylieber.com && test -d $werc/sites/$site/src/$a_id)
+					chmod +t $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/* $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/tags/*
+			}
+		}
+	}
+}
+
+if(test -f /boot/factotum && test -f /rc/bin/hget)
+	webfs
+for(i in `{grep -v -e '^#' $feeds}){
+	feed=`{echo $"i | sed 's/\|.*$//g'}
+	tags=`{echo $"i | sed 's/\|/ /g'}
+	tags=$tags(2-)
+	get_posts
+	parse_posts
+}
--- /dev/null
+++ b/bin/gz.tumblr
@@ -1,0 +1,119 @@
+#!/bin/rc
+# Parse XML RSS feeds into BARF blog posts for the specified site.
+# If a post with a matching _link_ already exists, no new post will
+# be created for that item. Tags will be created according to the rules
+# defined in the get_tags() function.
+#
+# The file argument should point to a file containing one line per feed,
+# with fields separated by the | character, in the following format:
+#
+#	http://feeds.feedburner.com/ImNotReallyStanleyLieber|stanleylieber
+#
+# where the first field is the feed URL and each addition field is a tag.
+#
+# Requires 20h's xmlpull and rssread.
+rfork en
+switch($1){
+case /*
+	feeds=$1
+	site=tumblr.stanleylieber.com
+	tags=()
+case *
+	echo 'Usage: gz file' >[1=2]
+	exit usage
+}
+
+file=/tmp/gz.$pid
+werc=/usr/sl/www/werc
+
+if(test -f /boot/factotum)
+	cmd=hget
+if not
+	cmd='curl -s'
+
+fn cram{
+	ssam '
+,s/^link:.*$/HJDIVIDER&HJDIVIDER/g
+,s/^title:.*$/HJDIVIDER&HJDIVIDER/g
+,s/\n//g
+,s/HJDIVIDERtitle:/\n&/g
+	'
+}
+
+fn scape{
+	ssam '
+,s/
//g
+,s/\&quot;/\"/g
+,s/\&#34;/\"/g
+,s/\&amp;/\&/g
+,s/\&#38;/\&/g
+,s/\&#39;/''/g
+,s/\&#44;/,/g
+,s/\&#45;/-/g
+,s/\&#46;/\./g
+,s/\&#47;/\//g
+,s/\&#58;/:/g
+,s/\&#59;/;/g
+,s/\&lt;/</g
+,s/\&#60;/</g
+,s/\&#61;/=/g
+,s/\&gt;/>/g
+,s/\&#62;/>/g
+,s/\&#95;/_/g
+,s/\|/\&#124;/g
+	'
+}
+
+fn get_posts{
+	$"cmd $"feed | rssread | cram | scape >$file
+	echo >>$file
+}
+
+fn parse_posts{
+	ifs='
+' {
+		posts=`{cat $file}
+		for(i in `{seq 1 $#posts | sort -nr}){
+			post=$posts($i)
+			if(! ~ $post ''){
+				a_title=`{echo $post | sed 's/^.*HJDIVIDERtitle: //g; s/HJDIVIDER.*$//g'}
+				a_date=`{date}
+				a_link=`{echo $post | sed 's/^.*HJDIVIDERlink:  //g; s/HJDIVIDER.*$//g'}
+				a_body=`{echo $post | sed 's/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g; s/^.*HJDIVIDER//g'}
+				a_id=`{echo `{ls -p $werc/sites/$site/src | sort -n | tail -1}^+1 | bc}
+				if(~ $#a_id 0)
+					a_id=1
+				while(test -d $werc/sites/$site/src/$a_id)
+					a_id=`{echo $a_id^+1 | bc}
+				if(! ~ $"a_link '' && ! grep -s `{echo $"a_link | md5sum} $werc/sites/$site/links){
+					mkdir -p $werc/sites/$site/src/$a_id/tags # big fat race
+					echo $"a_title >$werc/sites/$site/src/$a_id/title
+					echo $"a_date >$werc/sites/$site/src/$a_id/date
+					echo $a_link(1) >$werc/sites/$site/src/$a_id/link
+					echo $a_link(1) | md5sum >>$werc/sites/$site/links
+					if(~ $a_link(1) *staticflickr.com*)
+						echo '<img src="'$"a_link'">' >$werc/sites/$site/src/$a_id/body
+					echo $"a_body '</a></li></ul>' >>$werc/sites/$site/src/$a_id/body
+					ifs=' ' {
+						for(j in $tags){
+							>$werc/sites/$site/src/$a_id/tags/$j
+							echo $a_id/tags/$j >>$werc/sites/$site/tags
+						}
+					}
+				}
+				if(test -f /boot/factotum && ~ $site *.stanleylieber.com && test -d $werc/sites/$site/src/$a_id)
+					chmod +t $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/* $werc/sites/$site/src/$a_id $werc/sites/$site/src/$a_id/tags/*
+			}
+		}
+	}
+}
+
+if(test -f /boot/factotum && test -f /rc/bin/hget)
+	webfs
+for(i in `{grep -v -e '^#' $feeds}){
+	feed=`{echo $"i | sed 's/\|.*$//g'}
+	tags=`{echo $"i | sed 's/\|/ /g'}
+	tags=$tags(2-)
+	get_posts
+	parse_posts
+}
--- /dev/null
+++ b/bin/rsrc
@@ -1,0 +1,3 @@
+#!/bin/rc
+# Remove static files.
+rm -r [0-9]*.html [0-9]*-[0-9]*.html tag
--- /dev/null
+++ b/bin/srct
@@ -1,0 +1,4 @@
+#!/bin/rc
+# do not store these files in the worm
+fn f{ du -a $* | sed 's/^.*	//g' }
+for(i in `{f $1}){ chmod +t $i }
--- /dev/null
+++ b/lib/barf.tpl
@@ -1,0 +1,14 @@
+% if(~ $show_header 1 && ! ~ $barf_type login rss)
+%	display_header
+% if(~ $a_func edit_form){
+%	if(check_user && ! ~ $#logged_user 0)
+%		edit_form
+%	if not
+%		display_^$barf_type
+% }
+% if not
+%	display_^$barf_type
+% if(~ $show_sidebar 1 && ~ $#a_func 0 && ! ~ $barf_type login rss)
+%	display_sidebar
+% if(~ $show_footer 1 && ~ $#a_func 0 && ! ~ $barf_type login rss)
+%	display_footer
--- /dev/null
+++ b/lib/blog
@@ -1,0 +1,43 @@
+fn display_blog{
+	echo '<div id="center">
+	<div id="posts">'
+	get_post_list
+	for(i in `{seq 1 $#posts}){
+		a_id=$posts($i)
+		a_dir=$barf_root/$"barf_dir/src/$a_id
+		echo '<div id="post">
+		<div id="post_title">'
+		print_title
+		echo '</div>
+		<div id="post_meta">'
+		link=`{cat $a_dir/link}
+		echo '<span id="post_link">
+		<a href="'$"link'" target="_b">link</a>
+		</span>
+		| <span id="post_tags">'
+		print_tags
+		echo '</span>
+		| <span id="post_date">'
+		cat $a_dir/date
+		echo '</span>'
+		print_id
+		if(check_user && ! ~ $#logged_user 0){
+			echo ' | <span id="post_edit">'
+			print_edit
+			echo '</span>'
+		}
+		echo '</div>
+		<div id="post_body">'
+		cat $a_dir/body
+		if(~ $show_disqus 1 && ! ~ $#id 0)
+			cat $barf_root/_werc/barf/disqus
+		echo '</div>
+		</div>
+		<br>'
+	}
+	display_prevnext
+	echo '<br><br><br>
+	</div>
+	</div>
+	</div>'
+}
--- /dev/null
+++ b/lib/core
@@ -1,0 +1,414 @@
+fn delete_post{
+	a_dir=$barf_root/$"barf_dir/src/$a_id
+	if(test -d $a_dir){
+		rm -rf $a_dir &&
+		{echo ',x/^'$a_id'\/.*\n/d'; echo w; echo q} | sam -d $barf_root/$"barf_dir/tags >[2]/dev/null
+	}
+	post_redirect $base_url^$barf_base_uri
+}
+
+fn display_footer{
+	if(test -f $barf_root/$"barf_dir/_werc/barf/footer)
+		cat $barf_root/$"barf_dir/_werc/barf/footer
+	if not if(test -f $barf_root/_werc/barf/footer)
+		cat $barf_root/_werc/barf/footer
+	if not
+		cat apps/barf/barf/footer
+}
+
+fn display_header{
+	if(test -f $barf_root/$"barf_dir/_werc/barf/header)
+		cat $barf_root/$"barf_dir/_werc/barf/header
+	if not if(test -f $barf_root/_werc/barf/header)
+		cat $barf_root/_werc/barf/header
+	if not
+		cat apps/barf/barf/header
+}
+
+fn display_login{
+	echo '<div id="login">
+	<form method="post" action="/">
+	<input type="hidden" name="a_func" value="login">
+	username: <input type="text" name="user_name"><br> 
+	password: <input type="password" name="user_password"><br> 
+	<input name="s" type="submit" value="login"> 
+	</form>
+	</div>'
+}
+
+fn display_prevnext{
+	if(test $stop -gt `{echo 1+^$posts_per_page | bc}){
+		nprev=`{echo $start^-1-^$posts_per_page | bc}
+		prev='<span>
+		<a href="'$base_url^$barf_base_uri'?tags='$"tags'&start='$"nprev'">prev</a> | 
+		</span>'
+	}
+	if(test $#posts -gt $posts_per_page){
+		nnext=`{echo $stop^+1 | bc}
+		next='<span>
+		<a href="'$base_url^$barf_base_uri'?tags='$"tags'&start='$"nnext'">next</a>
+		</span>'
+	}
+	echo '<div id="page_list">
+	'$"prev'
+	'$"next'
+	</div>'
+}
+
+fn display_sidebar{
+	if(test -f $barf_root/$"barf_dir/_werc/barf/sidebar)
+		cat $barf_root/$"barf_dir/_werc/barf/sidebar
+	if not if(test -f $barf_root/_werc/barf/sidebar)
+		cat $barf_root/_werc/barf/sidebar
+	if not
+		cat apps/barf/barf/sidebar
+}
+
+fn dsrc{
+	low=`{ls -p $barf_root/$"barf_dir/src | sort -n | sed 1q}
+	high=$a_id
+	if(~ $#low 1 && ~ $#high 1){
+		cd $barf_root/$"barf_dir/src && rm -rf `{seq $low $high} &&
+		{
+			for(i in `{seq $low $high})
+				echo ',x/^'$i'\/.*\n/d'
+			echo w
+			echo w
+			echo q
+		} | sam -d $barf_root/$"barf_dir/tags >[2]/dev/null
+	}
+	post_redirect $base_url^$barf_base_uri
+}
+
+fn edit_form{
+	if(~ $#a_id 0)
+		name=add
+	if not{
+		name=update
+		a_dir=$barf_root/$"barf_dir/src/$a_id
+		for(x in $barf_items){
+			if(~ $x img)
+				a_img=`{ls -p $a_dir/img | sed 1q}
+			if(~ $x tags)
+				a_tags=`{ls -p $a_dir/tags}
+			if not
+				$x=`{cat $a_dir/$x}
+		}
+	}
+	echo '<div id="list">
+	<form action="/" method="post" name="edit" id="button">
+	<input type="hidden" name="fake" value="fake">
+	<input type="text" name="url" style="display: none;">
+	<input type="hidden" name="a_func" value="edit_post">'
+	if(~ $name update)
+		echo '<input type="hidden" name="a_id" value="'$"a_id'">'
+	for(x in $barf_items){
+		if(~ $x body){
+			echo '<div id="edit_body">' \
+			'body:<br>' \
+			'<textarea name="a_body">'
+			if(~ $name update)
+				cat $a_dir/body
+			echo '</textarea></div>'
+		}
+		if not if(~ $x img){
+			echo '<div id="edit_img">' \
+			'image:<br>' \
+			'<input name="a_img"  type="text" value="'$"a_img'" id="edit"> &nbsp;&nbsp;' \
+			'download: <input name="a_download" type="checkbox" value="1">' \
+			'</div>'
+		}
+		if not if(~ $x tags){
+			echo '<div id="edit_tags">' \
+			'tags: &nbsp;&nbsp;(space separated list of tags)<br>' \
+			'<input name="a_tags" type="text" value="'$"a_tags'" id="edit">' \
+			'</div>'
+		}
+		if not{
+			echo '<div id="edit_'$"x'">' \
+			$"x':<br>' \
+			'<input name="a_'$"x'" type="text" value="'$"$x'" id="edit">' \
+			'</div>'
+		}
+	}
+	echo '<div id="edit_submit">' \
+	'<input type="submit" name="'$name'" value="'$name'">' \
+	'</div>
+	</form>
+	</div>'
+}
+
+fn edit_post{
+	if(~ $#a_id 0){
+		a_id=`{echo `{ls -p $barf_root/$"barf_dir/src | sort -n | tail -1}^+1 | bc}
+		if(~ $#a_id 0)
+			a_id=1
+		while(test -d $barf_root/$"barf_dir/src/$a_id)
+			a_id=`{echo $a_id^+1 | bc}
+	}
+	a_dir=$barf_root/$"barf_dir^src/$a_id
+	mkdir -p $a_dir/img $a_dir/tags
+	rm -f $a_dir/tags/*
+	for(x in $barf_items){
+		if(~ $x date){
+			if(! ~ $#a_date 0)
+				echo $"a_date >$a_dir/date
+			if not
+				date >$a_dir/date
+		}
+		if not if(~ $x tags){
+			if(! ~ $#a_tags 0){
+				a_tags=`{echo $"a_tags | sed 's/[^A-Za-z0-9_\- ]//g'}
+				ifs=' '{a_tags=`{echo -n $a_tags}}
+				{
+					t=1
+					while(test $t -le $#a_tags){
+						>$a_dir/tags/$a_tags($t)
+						t=`{echo $t^+1 | bc}
+					}
+				}
+				for(i in $a_tags)
+					echo $a_id'/tags/'$i >>$barf_root/$"barf_dir/tags
+			}
+		}
+		if not if(! ~ $x img tags){
+			item='a_'$"x
+			if(! ~ $$item ''){
+				>$a_dir/$x
+				echo $$item >$a_dir/$x
+			}
+		}
+	}
+	if(~ $a_download 1){
+		switch($barf_type){
+		case image
+			rm -f $a_dir/img/*
+			img=$a_dir/img/^`{date -n}^.^`{echo $"a_img |
+				sed 's/^.*\.(gif|GIF)$/gif/g;
+					s/^.*\.(jpg|jpeg|JPG|JPEG)$/jpg/g;
+					s/^.*\.(png|PNG)$/png/g;
+					s/^.*\.(tif|TIF|tiff|TIFF)$/tif/g'
+			}
+			thumb=$a_dir/img/small.^`{basename $img | sed 's/\..*$//g'}^.png
+			if(test -f /boot/factotum){
+				@{
+				rfork n
+				if(test -f /rc/bin/hget)
+					webfs
+				hget $"a_img >$img
+				#magick/convert $img -resize 500x600 $thumb
+				switch($img){
+				case *.bmp
+					cmd=bmp
+				case *.gif
+					cmd=gif
+				case *.ico
+					cmd=ico
+				case *.jpg
+					cmd=jpg
+				case *.png
+					cmd=png
+				case *.tif
+					cmd=tif
+				case *.tga
+					cmd=tga
+				}
+				$cmd -9et <$img | resample -x 500 | topng >$thumb
+				}
+			}
+			if not{
+				curl -s -o $"a_img >$img
+				convert $img -resize 500x600 $thumb
+			}
+		case url
+			if(test -f /boot/factotum){
+				@{
+				rfork n
+				if(test -f /rc/bin/hget)
+					webfs
+				hget $"a_link | htmlfmt | fmt >$a_dir/body
+				}
+			}
+			if not
+				curl -s $"a_link | htmlfmt | fmt >$a_dir/body
+		}
+	}
+	if(! ~ $gp 1)
+		post_redirect $base_url^$barf_base_uri
+}
+
+fn get_post_list{
+	if(~ $id [0-9]*)
+		posts=$id
+	if not{
+		posts=`{
+			if(~ $show_ascending 1)
+				sort=(sort -n)
+			if not
+				sort=(sort -nr)
+			if(~ $tags all)
+				ls -p $barf_root/$"barf_dir/src |
+					grep -e '^[0-9]*$' |
+					eval $sort |
+					sed -n $start^,^$stop^p # awk 'NR=='$start',NR=='$stop' {print;}'
+			if not
+				grep -e '^.*\/'$tags'$' $barf_root/$"barf_dir/tags |
+					awk -F '/' '{print $1;}' |
+					eval $sort |
+					uniq |
+					sed -n $start^,^$stop^p
+		}
+		if(! ~ $posts [0-9]*)
+			posts=()
+	}
+}
+
+fn get_start{
+	if(~ $#start 0)
+		start=1
+}
+
+fn get_stop{
+	if(~ $#stop 0)
+		stop=`{echo $start^+^$posts_per_page | bc}
+}
+
+fn get_tags{
+	if(~ $#tags 0)
+		tags=all
+}
+
+fn load_get_args{
+	if(~ $REQUEST_METHOD GET && ~ $#get_args 0 && ~ $REQUEST_URI *'='*){
+		ifs='&' {
+			a=`{echo $"REQUEST_URI | sed 's/(^\/|#.*$)//g'}
+			for(pair in $a){
+				ifs='=' { pair=`{echo -n $pair} }
+					n='get_arg_'^`{echo $pair(1) | urldecode | tr -cd 'a-zA-Z0-9_'}
+					get_args=( $get_args $n )
+					ifs=() { $n=`{echo -n $pair(2) | urldecode | tr -d '
'} }
+			}
+		}
+		pair=()
+	}
+}
+
+fn parse_get_args{
+	if(! ~ $#get_arg_a_func 0)
+		a_func=$get_arg_a_func
+	if(! ~ $#get_arg_a_id 0)
+		a_id=$get_arg_a_id
+	if(! ~ $#get_arg_id 0)
+		id=$get_arg_id
+	if(! ~ $#get_arg_start 0)
+		start=$get_arg_start
+	if(! ~ $#get_arg_stop 0)
+		stop=$get_arg_stop
+	if(! ~ $#get_arg_reply 0)
+		reply=$get_arg_reply
+	if(! ~ $#get_arg_tags 0)
+		tags=$get_arg_tags
+}
+
+fn parse_post_args{
+	for(x in $barf_items){
+		a='a_'$"x
+		p='post_arg_'$"a
+		$a=$$p
+	}
+	if(! ~ $#post_arg_a_download 0)
+		a_download=$post_arg_a_download
+	if(! ~ $#post_arg_a_func 0)
+		a_func=$post_arg_a_func
+	if(! ~ $#post_arg_fake 0)
+		fake=$post_arg_fake
+	if(! ~ $#post_arg_a_id 0)
+		a_id=$post_arg_a_id
+	if(! ~ $#post_arg_url 0)
+		url=$post_arg_url
+}
+
+fn print_edit{
+	edit='<a href="'$base_url^$barf_base_uri'?a_func=edit_form&a_id='$"a_id'">edit</a>'
+	delete='<a href="'$base_url^$barf_base_uri'?a_func=delete_post&a_id='$"a_id'" onclick="return confirm(''are you sure you want to delete?'');">delete</a>'
+	dsrc='<a href="'$base_url^$barf_base_uri'?a_func=dsrc&a_id='$"a_id'" onclick="return confirm(''are you sure you want to dsrc?'');">dsrc</a>'
+	echo $"edit' | '$"delete' | '$"dsrc
+}
+
+fn print_id{
+	echo '<span id="post_id"><a href="/?id='$"a_id'">No.'$"a_id'</a></span>'
+}
+
+fn print_img{
+	a_img=`{ls -p $a_dir/img/[0-9]*}
+	a_thumb=`{ls -p $a_dir/img/small*}
+	if(! ~ $#a_img 0)
+		if(~ $#a_thumb 0)
+			a_thumb=$a_img
+	echo '<a href="'$base_url^$barf_base_uri'src/'$a_id'/img/'$a_img'" target="_b"><img src="'$base_url^$barf_base_uri'src/'$a_id'/img/'$a_thumb'" border="0"></a>'
+}
+
+fn print_tags{
+	a_tags=`{ls -p $a_dir/tags}
+	a_tags=`{for(t in $a_tags) echo '<a href="'$base_url^$barf_base_uri'?tags='$t'">'$t'</a>, '}
+	a_tags=`{echo $a_tags | awk '{print substr($0, 1, length($0) -1)}'}
+	echo '<span id="post_tags">'$"a_tags'</span>'
+}
+
+fn print_title{
+	a_title=`{cat $a_dir/title}
+	if(! ~ $#a_title 0){
+		if(~ $barf_type log url)
+			echo '<a href="'`{cat $a_dir/link}'">'$"a_title'</a>'
+		if not
+			echo '<a href="'$base_url^$barf_base_uri'?id='$"a_id'">'$"a_title'</a>'
+	}
+}
+
+fn redirect_bots{
+	if(! ~ $fake fake || ! ~ $url '')
+		post_redirect http://google.com
+}
+
+fn urldecode {
+awk '
+BEGIN {
+    hextab ["0"] = 0; hextab ["8"] = 8;
+    hextab ["1"] = 1; hextab ["9"] = 9;
+    hextab ["2"] = 2; hextab ["A"] = hextab ["a"] = 10
+    hextab ["3"] = 3; hextab ["B"] = hextab ["b"] = 11;
+    hextab ["4"] = 4; hextab ["C"] = hextab ["c"] = 12;
+    hextab ["5"] = 5; hextab ["D"] = hextab ["d"] = 13;
+    hextab ["6"] = 6; hextab ["E"] = hextab ["e"] = 14;
+    hextab ["7"] = 7; hextab ["F"] = hextab ["f"] = 15;
+}
+{
+    decoded = ""
+    i = 1
+    len = length ($0)
+    while ( i <= len ) {
+        c = substr ($0, i, 1)
+        if ( c == "%" ) {
+            if ( i+2 <= len ) {
+                c1 = substr ($0, i+1, 1)
+                c2 = substr ($0, i+2, 1)
+                if ( hextab [c1] == "" || hextab [c2] == "" ) {
+                    print "WARNING: invalid hex encoding: %" c1 c2 | "cat >&2"
+                } else {
+                    code = 0 + hextab [c1] * 16 + hextab [c2] + 0
+                    c = sprintf ("%c", code)
+                    i = i + 2
+                }
+            } else {
+                print "WARNING: invalid % encoding: " substr ($0, i, len - i)
+            }
+        } else if ( c == "+" ) {
+            c = " "
+        }
+        decoded = decoded c
+        ++i
+    }
+    printf "%s", decoded
+}
+'
+}
--- /dev/null
+++ b/lib/default_master.tpl
@@ -1,0 +1,1 @@
+% run_handler $handler_body_main
--- /dev/null
+++ b/lib/image
@@ -1,0 +1,68 @@
+fn add_post{
+	redirect_bots
+	a_download=1
+	edit_post
+}
+
+fn display_image{
+	echo '<div id="center">'
+	if(~ $allow_anon 1 || {check_user && ! ~ $#logged_user 0}){
+		echo '<div id="upload">
+		<form method="post" action="/">
+		<input type="hidden" name="fake" value="fake">
+		<input type="text" name="url" style="display: none;">
+		<input type="hidden" name="a_func" value="add_post">
+		<div id="upload_heading">/'$tags'/</div>
+		<table id="upload_table">
+		<tr><td id="upload_label">Image</td><td><input type="text" name="a_img"  id="upload_input"></td></tr>
+		<tr><td id="upload_label">Link</td><td><input type="text" name="a_link"  id="upload_input"></td></tr>
+		<tr><td id="upload_label">Tags</td><td><input type="text" name="a_tags"  id="upload_tags">
+		<input type="submit" name="submit" value="add" id="upload_submit"></td></tr>
+		</table>
+		</form>
+		<table align="center">
+		<tr>
+		<td>
+		<p>
+		<li id="upload_meta">Supported file types are: GIF, JPG, PNG</li>
+		<li id="upload_meta">Images greater than 500x600 pixels will be thumbnailed.</li>
+		</td>
+		</tr>
+		</table>
+		</div>'
+	}
+	echo '<div id="center_body">'
+	get_post_list
+	for(i in `{seq 1 $#posts}){
+		a_id=$posts($i)
+		a_dir=$barf_root/$"barf_dir/src/$a_id
+		echo '<div id="post">
+		<div id="post_meta">
+		<span id="post_link">'
+		link=`{cat $a_dir/link}
+		echo '<a href="'$"link'">link</a>
+		</span> |
+		<span id="post_tags">'
+		print_tags
+		echo '</span> |
+		<span id="post_date">'
+		cat $a_dir/date
+		echo '</span>'
+		if(check_user && ! ~ $#logged_user 0){
+			echo '| <span id="post_edit">'
+			print_edit
+			echo '</span>'
+		}
+		echo '</div>
+		<div id="post_img">'
+		print_img
+		echo '</div>
+		</div>
+		<br><br>'
+	}
+	display_prevnext
+	echo '<br><br><br><br>
+	</div>
+	</div>
+	</div>'
+}
--- /dev/null
+++ b/lib/log
@@ -1,0 +1,55 @@
+fn display_log{
+	if(~ $#logged_user 0)
+		a='<a href="'$base_url^$barf_base_uri'login">login</a>'
+	if not
+		a='<a href="'$base_url^$barf_base_uri'?a_func=edit_form">add</a>'
+	echo '<div>
+	<span id="add">'$"a'</span>
+	<span id="search">
+	<form method="get" action="/">
+	<input type="text" name="tags" size="28">
+	<input type="submit" value="search">
+	</form>
+	</span>
+	</div>
+	</div>
+	<div id="list">
+	<table id="post_table">
+	<tbody>
+	<tr id="blank">
+	<th style="display: none;">&nbsp;</th>
+	<th style="display: none;">&nbsp;</th>
+	<th style="display: none;">&nbsp;</th>'
+	if(check_user && ! ~ $#logged_user 0)
+		echo '<th style="display: none;">&nbsp;</th>'
+	echo '</tr>'
+	get_post_list
+	for(i in `{seq 1 $#posts}){
+		a_id=$posts($i)
+		a_dir=$barf_root/$"barf_dir/src/$a_id
+		echo '<tr>'
+		for(j in $barf_items){
+			echo '<td id="post_'$"j'">'
+			if(~ $j img)
+				print_img
+			if not if(~ $j tags)
+				print_tags
+			if not if(~ $j title)
+				print_title
+			if not
+				cat $a_dir/$j
+			echo '</td>'
+		}
+		if(check_user && ! ~ $#logged_user 0){
+			echo '<td id="post_edit">'
+			print_edit
+			echo '</td>'
+		}
+		echo '</tr>'
+	}
+	echo '</tbody>
+	</table>'
+	display_prevnext
+	echo '<br><br><br><br>
+	</div>'
+}
--- /dev/null
+++ b/lib/paste
@@ -1,0 +1,50 @@
+fn add_post{
+	redirect_bots
+	a_date=`{date}
+	edit_post
+}
+
+fn display_paste{
+	echo '<div id="center">'
+	if(~ $allow_anon 1 || {check_user && ! ~ $#logged_user 0}){
+		echo '<div id="paste">
+		<p>
+		<form method="post" action="/">
+		<input type="hidden" name="fake" value="fake">
+		<input type="text" name="url" style="display: none;">
+		<input type="hidden" name="a_func" value="add_post">
+		<textarea name="a_body" id="paste_box"></textarea><br>
+		<input type="submit" name="submit" value="submit" id="paste_submit">
+		</form>
+		</div>'
+	}
+	echo '<p>
+	<div id="posts">'
+	get_post_list
+	for(i in `{seq 1 $#posts}){
+		a_id=$posts($i)
+		a_dir=$barf_root/$"barf_dir/src/$a_id
+		echo '<div id="post">
+		<div id="post_meta">'
+		date=`{cat $a_dir/date}
+		echo '<span id="post_date">
+		<a href="/src/'$"a_id'/body" target="_b">'$"date'</a>
+		</span>'
+		if(check_user && ! ~ $#logged_user 0){
+			echo ' | <span id="post_edit">'
+			print_edit
+			echo '</span>'
+		}
+		echo '</div>
+		<div id="post_body">'
+		txt_handler $barf_root/$"barf_dir/src/$a_id/body 
+		echo '</div>
+		</div>
+		<br>'
+	}
+	display_prevnext
+	echo '<br><br><br><br>
+	</div>
+	</div>
+	</div>'
+}
--- /dev/null
+++ b/lib/rss
@@ -1,0 +1,56 @@
+fn display_rss{
+	echo '<?xml version="1.0" encoding="UTF-8"?>'
+	echo '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">'
+	echo '<channel>'
+	echo '<atom:link href="'$base_url^$req_path'" rel="self" type="application/rss+xml" />'
+	echo '<title><![CDATA['$"siteTitle']]></title>'
+	echo '<link>'$base_url^$barf_base_uri'</link>'
+	echo '<description><![CDATA['$"blogDesc']]></description>'
+	echo '<generator><![CDATA[barf]]></generator>'
+	echo '<lastBuildDate>'
+	ndate -m `{date `{mtime $barf_root/$"barf_dir/src | awk '{print $1}'}}	# rfc2822 last time channel content changed.
+	echo -n '</lastBuildDate>'
+	echo '<language>en-us</language>'
+	get_post_list
+	for(i in `{seq 1 $#posts}){
+		a_id=$posts($i)
+		a_dir=$barf_root/$"barf_dir/src/$a_id
+		echo '<item>'
+		echo '<guid isPermaLink="true">'$base_url^$barf_base_uri'?id='$"a_id'</guid>'
+		date=`{ndate -m `{cat $a_dir/date}}
+		echo '<pubDate>'$"date'</pubDate>'
+		title=`{cat $a_dir/title}
+		if(~ $title '')
+			ntitle=($siteTitle $"a_id)
+		if not
+			ntitle=$title
+		echo '<title>'$"ntitle'</title>'
+		echo '<link>'$base_url^$barf_base_uri'?id='$"a_id'</link>'
+		echo '<description><![CDATA['
+		if(~ $obarf_type image){
+			if(! ~ $#a_link 0)
+				link=$"a_link
+			if not
+				link=$base_url^$barf_base_uri'?id='$"a_id
+			echo '<p>source: <a href="'$"link'">link</a></p>'
+		}
+		a_tags=`{ls -p $a_dir/tags}
+		if(! ~ $#a_tags 0){
+			echo '<p>tags: '
+			print_tags
+			echo '</p>'
+			echo '<p>'
+		}
+		# begin ugly if statements
+		if(~ $obarf_type paste)
+			echo '<pre>'
+		if(! ~ $obarf_type image)
+		cat $a_dir/body
+		if(~ $obarf_type paste)
+			echo '</pre>'
+		if(~ $obarf_type image)
+			print_img
+		echo '</p>]]></description></item>'
+	}
+	echo '</channel></rss>'
+}
--- /dev/null
+++ b/lib/url
@@ -1,0 +1,52 @@
+fn display_url{
+	if(~ $#logged_user 0)
+		a='<a href="'$base_url^$barf_base_uri'login">login</a>'
+	if not
+		a='<a href="'$base_url^$barf_base_uri'?a_func=edit_form">add</a>'
+	echo '<div>
+	<span id="add">'$"a'</span>
+	<span id="search">
+	<form method="get" action="/">
+	<input type="text" name="tags" size="28">
+	<input type="submit" value="search">
+	</form>
+	</span>
+	</div>
+	</div>
+	<div id="list">
+	<table id="post_table">
+	<tbody>
+	<tr id="blank">
+	<th style="display: none;">&nbsp;</th>
+	<th style="display: none;">&nbsp;</th>
+	<th style="display: none;">&nbsp;</th>'
+	if(check_user && ! ~ $#logged_user 0)
+		echo '<th style="display: none;">&nbsp;</th>'
+	echo '</tr>'
+	get_post_list
+	for(i in `{seq 1 $#posts}){
+		a_id=$posts($i)
+		a_dir=$barf_root/$"barf_dir/src/$a_id
+		echo '<tr>
+		<td id="post_title">'
+		print_title
+		echo '</td>
+		<td id="post_tags">'
+		print_tags
+		echo '</td>
+		<td id="post_date">'
+		cat $a_dir/date
+		echo '</td>'
+		if(check_user && ! ~ $#logged_user 0){
+			echo '<td id="post_edit">'
+			print_edit
+			echo '</td>'
+		}
+		echo '</tr>'
+	}
+	echo '</tbody>
+	</table>'
+	display_prevnext
+	echo '<br><br><br><br>
+	</div>'
+}
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,10 @@
+WERC=/usr/sl/www/werc
+PLAN9=$WERC/sites/plan9.stanleylieber.com
+
+web:V:
+	src=`{basename `{pwd}}
+	rm -rf $PLAN9/werc/apps/$src
+	cd $WERC/apps
+	tar zcvf $PLAN9/werc/apps/$src.tgz $src
+	cd $PLAN9/werc/apps
+	tar zxvf $src.tgz
--- /dev/null
+++ b/pub/1995.css
@@ -1,0 +1,344 @@
+/* 1995 */
+
+body {
+  color: black;
+  background-color: silver;
+  font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif;
+  font-size: 84%;  /* Enables font size scaling in MSIE */
+  margin: 0;
+  padding: 0;
+}
+
+
+/* # Header # */
+.superHeader {
+  color: black;
+  background-color: silver;
+  height: 1.6em;
+}
+
+.superHeader img { vertical-align: bottom; }
+
+.superHeader a {
+  color: blue;
+  background-color: transparent;
+  font-size: 91%;
+  margin: 0;
+  padding: 0 0.5ex 0 0.25ex;
+  text-decoration: underline; }
+}
+
+a { text-decoration: underline; }
+a:hover { text-decoration: underline; }
+
+.superHeader div {
+  position: absolute;
+  top: 0.40ex;
+}
+
+.superHeader .left { left: 0.4em; }
+.superHeader .right { right: 0.4em; }
+
+.midHeader {
+  color: black;
+  background-color: silver;
+  border: solid 0 black;
+  border-width: 1px 0;
+}
+
+.headerTitle {
+  color: black;
+  font-size: 233%;
+  font-weight: normal;
+  margin: 0 0 0 4mm;
+  padding: 0.25ex 0;
+}
+#headerSubTitle {
+  font-size: 50%;
+  font-style: italic;
+  margin-left: 1em;
+}
+
+.headerTitle a { color: black; }
+.headerTitle a:hover { text-decoration: none; }
+
+.subHeader {
+  display: none;
+  color: white;
+  background-color: rgb(0,51,153);
+  margin: 0;
+  padding: 1ex 1ex 1ex 1.5mm;
+}
+
+.subHeader a {
+  color: white;
+  background-color: transparent;
+  font-weight: bold;
+  margin: 0;
+  padding: 0 0.75ex 0 0.5ex;
+}  
+
+.superHeader .highlight, .subHeader .highlight {
+  color: rgb(253,160,91);
+  background-color: transparent;
+}
+
+
+/* # Side # */
+#side-bar {
+  width: 16em;
+  float: left;
+  clear: left;
+  border-right: 1px solid black;
+}
+
+#side-bar div {
+  border-bottom: 1px solid black;
+}
+
+.sideBarTitle {
+  font-weight: bold;
+  margin: 0 0 0.5em 2mm;
+  padding: 1em 0 0 0;
+}
+
+#side-bar ul {
+  list-style-type: none;
+  list-style-position: outside;
+  margin: 0;
+  padding: 0 0 0.3em 0;
+}
+
+li ul {
+  padding-left: 0.6em !important;
+}
+
+#side-bar li {
+  margin: 0;
+  padding: 0.1ex 0;  /* Circumvents a rendering bug (?) in MSIE 6.0  XXX should move to iehacks.css, this causes an ugly gap */
+}
+
+#side-bar a {
+  color: black;
+  background-color: transparent;
+  margin: 0;
+  padding: 0.25em 1ex 0.25em 2mm;
+  display: block;
+  text-transform: capitalize;
+  font-weight: bold!important;
+  font-size: 102%;
+  border-left: blue solid 0.2em;
+}
+
+.thisPage, .thisPage a {
+  color: black!important;
+  background-color: white;
+  padding-left: 5mm;
+}
+
+#side-bar a:hover {
+  color: white;
+  background-color: blue;
+  border-left: black solid 0.2em;
+  text-decoration: none;
+}
+
+.sideBarText {
+  line-height: 1.5em;
+  margin: 0 0 1em 0;
+  padding: 0 1.5ex 0 2.5mm;
+  display: block;
+}
+
+#side-bar .sideBarText a {
+  margin: 0;
+  padding: 0;
+  display: inline;
+}
+
+#side-bar .sideBarText a:hover {
+  color: black;
+  background-color: transparent;
+  text-decoration: none;
+}
+
+
+/* # Main Copy # */
+#main-copy {
+  max-width: 70em;
+  color: black;
+  background-color: transparent;
+  text-align: justify;
+  line-height: 1.5em;
+  margin: 0em 0 0 16em;
+  padding: 0.5mm 5mm 5mm 5mm;
+  border-left: 1px solid black;
+}
+
+#bodyText {
+  margin: 0 0 0 15.5em;
+  padding: 2mm 5mm 2mm 5mm;
+}
+
+#main-copy p {
+  margin: 1em 1ex 1em 1ex !important; /* Need !important so troff-generated pages don't look totally squezed */
+  padding: 0;
+}
+
+#main-copy a {
+  color: blue;
+  background-color: transparent;
+  text-decoration: underline;
+}
+
+#main-copy a:hover {
+  color: blue;
+  background-color: transparent;
+  text-decoration: underline;
+}
+
+#main-copy h1, #main-copy h2 {
+  color: black;
+  background-color: transparent;
+  font-size: 145.5%;
+  font-weight: bold;
+  margin: 2em 0 0 0;
+  padding: 0.5ex 0 0.5ex 0.6ex;
+  border-bottom: 2px solid black;
+}
+
+#main-copy h2 {
+  font-size: 115.5%;
+  border-bottom: 1px solid black;
+}
+
+#main-copy .topOfPage {
+  color: black;
+  background-color: transparent;
+  font-size: 91%;
+  font-weight: bold;
+  text-decoration: none;
+  margin: 3ex 1ex 0 0;
+  padding: 0;
+  float: right;
+}
+
+dl {
+  margin: 1em 1ex 2em 1ex;
+  padding: 0;
+}
+
+dt {
+  font-weight: bold;
+  margin: 0 0 0 0;
+  padding: 0;
+}
+
+dd {
+  margin: 0 0 2em 2em;
+  padding: 0;
+}
+
+
+/* # Footer # */
+#footer {
+  color: black;
+  background-color: silver;
+  padding: 1em;
+  clear: both;
+  border-color: black;
+  border-width: 1px 0;
+}
+
+#footer .left {
+  text-align: left;
+  line-height: 1.55em;
+  float: left;
+  clear: left;
+}
+
+#footer .right {
+  text-align: right;
+  line-height: 1.45em;
+}
+
+#footer a {
+  color: blue;
+  background-color: transparent;
+}
+
+
+/* GENERAL */
+
+table {
+	background-color: transparent;
+	padding: 0px;
+	border: 0px;
+	border-collapse: collapse;
+}
+
+td {
+	padding: 10px;
+	border-width: 1px;
+	border-style: solid;
+	border-collapse: collapse;
+	border-color: #000000;
+	background: silver;
+}
+
+tr {
+	border-width: 1px;
+	border-style: solid;
+	border-collapse: collapse;
+	border-color: #000000;
+}
+hr {
+  border-width: 0px 0px 0.1em 0px;
+  border-color: black;
+}
+
+acronym, .titleTip {
+  border-bottom: 1px solid black;
+  cursor: help;
+  margin: 0;
+  padding: 0 0 0.4px 0;
+}
+
+pre {
+  margin-left: 2em; 
+  font-size: 1.2em;
+}
+
+blockquote {
+  border-left: 1px solid blue;
+  font-style: italic;
+}
+
+.smallCaps {
+  font-size: 110%;
+  font-variant: small-caps;
+}
+
+.doNotDisplay { display: none; }
+
+
+.notify_errors,
+.notify_notes,
+.notify_success { padding: .8em; margin-bottom: 1em; border: 2px solid black; }
+ 
+.notify_errors { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; }
+.notify_notes { background: #FFF6BF; color: #514721; border-color: #FFD324; }
+.notify_success { background: #E6EFC2; color: #264409; border-color: #C6D880; }
+.notify_errors a { color: #8a1f11; }
+.notify_notes a { color: #514721; }
+.notify_success a { color: #264409; }
+
+
+/* # Page/Handler specific # */
+h1.dir-list-head, ul.dir-list {
+  text-transform: capitalize;
+  font-weight: bold;
+}
+ul.sitemap-list a {
+  text-transform: capitalize;
+}
--- /dev/null
+++ b/pub/1oct1993.css
@@ -1,0 +1,63 @@
+/* 1oct1993 */
+body {
+	color: #FFFFFF;
+	background-color: #000000;
+	font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
+	font-size: 84%;  /* Enables font size scaling in MSIE */
+	margin: 0;
+	padding: 0;
+}
+a { text-decoration: none; color: #00ADEF; }
+a:hover { color: #00ADEF; text-decoration: none; }
+li:hover { color: #00ADEF; text-decoration: none; }
+li a { color: #00ADEF }
+li a:hover { color: #00ADEF; text-decoration: none; }
+li ul { padding-left: 0.6em !important; }
+h1 { font-size: 10pt; font-weight: normal; }
+h2 { font-size: 9pt; font-weight: normal; }
+input , textarea, select, option { background-color: #00ADEF; border: none; }
+table { border: none; }
+tr { background-color: transparent; }
+th {
+	background-color: transparent;
+	border: none;
+	 text-align: center;
+}
+td {
+	background-color: transparent;
+	border: none;
+}
+
+hr {
+	border-width: 0px 0px 0.1em 0px;
+	border-color: transparent;
+}
+pre, code, blockquote {
+	font-family: Courier, 'Lucida Console','Courier New', Serif;
+	margin-left: 2em; 
+	font-size: 1.2em;
+}
+blockquote {
+	border-left: none;
+	font-style: none;
+	background-color: #00ADEF;
+}
+#header { flex-basis: 100%; }
+#header tr { background-color: transparent; }
+#center {
+	width: 500px;
+	margin-left: auto;
+	margin-right: auto;
+}
+#center h1 { font-size 9pt; }
+#footer {
+	font-size: 8pt;
+	background-color: #000000;
+	color: #00ADEF;
+	margin-left: auto;
+	margin-right: auto;
+}
+#footer a { color: #00ADEF; text-decoration: none; }
+#footer a:hover { color: #00ADEF; text-decoration: none; }
+#footer table {  font-size: 8pt; }
+#footer tr { background-color: transparent; }
--- /dev/null
+++ b/pub/flamesgif.css
@@ -1,0 +1,77 @@
+/* flamesgif.com */
+body {
+	color: black;
+	background-color: silver;
+	font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
+	font-size: 84%;  /* Enables font size scaling in MSIE */
+	margin: 0;
+	padding: 0;
+}
+a { text-decoration: none; color: blue; }
+a:hover { color: purple;}
+blockquote {
+	border-left: none;
+	font-style: none;
+	background-color: silver;
+}
+li:hover { color: purple }
+li a { color: blue }
+li a:hover { color: purple; }
+h1 { font-size: 10pt; }
+h2, h3, h1, h4 { color : blue; }
+hr {
+	border-width: 0px 0px 0.1em 0px;
+	border-color: transparent;
+}
+input , textarea, select, option { background-color: blue; border: none; }
+pre, code, blockquote {
+	font-family: Courier, 'Lucida Console','Courier New', Serif;
+	margin-left: 2em; 
+	font-size: 1.2em;
+}
+table { border: none; }
+th {
+	background-color: transparent;
+	border: none;
+	 text-align: center;
+}
+td {
+	background-color: transparent;
+	border: none;
+}
+ul { list-style: none; padding-left: 0px; margin: 0px }
+#center {
+	width: 600px;
+	margin-left: auto;
+	margin-right: auto;
+}
+#center h1 { font-size 9pt; }
+#footer {
+	font-size: 8pt;
+	background-color: silver;
+	color: blue;
+	margin-left: auto;
+	margin-right: auto;
+}
+#footer a { color: blue; text-decoration: none; }
+#footer a:hover { color: purple; text-decoration: none; }
+#footer table {  font-size: 8pt; }
+#right {
+	float: right;
+	position: absolute;
+	top: 210px;
+	right: 1px;
+	width: 25%;
+	height: 100%;
+	list-style: none;
+}
+#sidebar {
+	position: relative;
+	z-index: 100;
+	width: 95%;
+	top: 10px;
+	right: 10px;
+	left: 10px;
+	margin: 2px;
+	background: silver;
+}
--- /dev/null
+++ b/pub/img.css
@@ -1,0 +1,53 @@
+/* img.stanleylieber.com */
+body { display: flex; flex-wrap: wrap; font-family: sans; }
+header { flex-basis: 99%; flex-shrink: 0; padding-left: 1em; padding-bottom: 1em; }
+article { flex-basis: 99%; padding: 0; }
+footer { flex-basis: 99%; flex-shrink: 0; }
+header nav { display: flex; justify-content: space-between; }
+footer { display: flex; justify-content: space-between; }
+
+body { margin:0; padding: 0; font-size: 10pt; font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; background-color: #000000; color: #FFFFFF; }
+a { text-decoration: none; color: #FFFFFF; background-color: #000000;  font-weight: bold; }
+a:hover { text-decoration: none; background-color: #FFFFFF; color: #000000; }
+
+/* header and top bar */
+header h3 { padding-bottom: 2px; }
+header a img { vertical-align: bottom; padding-top: 1em; }
+
+/* main copy */
+article { padding-left: 1em; padding-right: 1em; }
+article nav { padding-bottom: 2px; }
+article div { padding-top: 2px; padding-bottom: 2px; }
+article h1, article h2, article h3, article h4, article h5, article h6, article h7, article h8 {
+	font-weight: bold; margin: 0; padding-bottom: 2px;
+}
+article a img { vertical-align: bottom; }
+article img { max-width: 100%!important; }
+article iframe { max-width: 100%!important; }
+article video { max-width: 100%!important; }
+article fieldset { color: #FFFFFF; border-color: #FFFFFF; }
+article legend { color: #FFFFFF; border-color: #FFFFFF; }
+
+/* footer */
+footer > nav { margin-left: auto; padding: 1em; }
+
+/* fixed-width fonts */
+pre, code { white-space: pre-wrap!important; }
+pre, code, blockquote {
+	max-width: 100%!important;
+	font-family: Courier, 'Lucida Console','Courier New', Serif;
+}
+
+/* input */
+input, textarea, select, option {
+	font-family: Sans-Serif; 
+	font-size: 100%;
+	padding: 2px;
+	border-top: solid 1px #FFFFFF;
+	border-bottom: solid 1px #FFFFFF;
+	border-left: solid 1px #FFFFFF;
+	border-right: solid 1px #FFFFFF;
+	background-color: #000000;
+	color: #FFFFFF;
+	margin: 2px;
+}
--- /dev/null
+++ b/pub/inri.css
@@ -1,0 +1,417 @@
+/* inri.net */
+body {
+	font-family :'Lucida Sans Unicode','Lucida Sans', 'Trebuchet MS', 'Lucida Grande', 'Bitstream Sans Vera', Verdana, Arial, Tahoma, Helvetica, Sans-Serif;
+	font-style : normal;
+	padding: 2px 2em;
+	line-height: 1.5em;
+	font-size: 70%;
+	background: #FFF;
+	color: #111;
+}
+
+
+/* # Header # */
+.superHeader {
+  color: white;
+  background-color: gray;
+  height: 1.6em;
+}
+
+.superHeader img { vertical-align: bottom; }
+
+.superHeader a {
+  color: white;
+  background-color: transparent;
+  font-size: 91%;
+  margin: 0;
+  padding: 0 0.5ex 0 0.25ex;
+}
+
+a { text-decoration: none; }
+a:hover { text-decoration: underline; }
+
+.superHeader div {
+  position: absolute;
+  top: 0.40ex;
+}
+
+.superHeader .left { left: 0.4em; }
+.superHeader .right { right: 0.4em; }
+
+.midHeader {
+  color: gray;
+  background-color: gray;
+  background-color: #ff6d06;
+  border: solid 0 black;
+  border-width: 2px 0;
+}
+
+.headerTitle {
+  color: black;
+  font-size: 233%;
+  font-weight: normal;
+  margin: 0 0 0 4mm;
+  padding: 0.25ex 0;
+}
+#headerSubTitle {
+  font-size: 50%;
+  font-style: italic;
+  margin-left: 1em;
+}
+
+.headerTitle a { color: black; }
+.headerTitle a:hover { text-decoration: none; }
+
+.subHeader {
+  display: none;
+  color: white;
+  background-color: gray;
+  margin: 0;
+  padding: 1ex 1ex 1ex 1.5mm;
+}
+
+.subHeader a {
+  color: white;
+  background-color: transparent;
+  font-weight: bold;
+  margin: 0;
+  padding: 0 0.75ex 0 0.5ex;
+}  
+
+.superHeader .highlight, .subHeader .highlight {
+  color: gray;
+  background-color: transparent;
+}
+
+
+/* # Side # */
+#side-bar {
+  width: 16em;
+  float: left;
+  clear: left;
+  border-right: 1px solid white;
+}
+
+#side-bar div {
+  border-bottom: 1px solid white;
+}
+
+.sideBarTitle {
+  font-weight: bold;
+  margin: 0 0 0.5em 2mm;
+  padding: 1em 0 0 0;
+}
+
+#side-bar ul {
+  list-style-type: none;
+  list-style-position: outside;
+  margin: 0;
+  padding: 0 0 0.3em 0;
+}
+
+li ul {
+  padding-left: 0.6em !important;
+}
+
+#side-bar li {
+  margin: 0;
+  padding: 0.1ex 0;  /* Circumvents a rendering bug (?) in MSIE 6.0  XXX should move to iehacks.css, this causes an ugly gap */
+}
+
+#side-bar a {
+  color: gray;
+  background-color: transparent;
+  margin: 0;
+  padding: 0.25em 1ex 0.25em 2mm;
+  display: block;
+  text-transform: capitalize;
+  font-weight: bold!important;
+  font-size: 102%;
+  border-left: white solid 0.2em;
+}
+
+.thisPage, .thisPage a {
+  color: black!important;
+  background-color: white;
+  padding-left: 5mm;
+}
+
+#side-bar a:hover {
+  color: black;
+  background-color: gray;
+  border-left: gray solid 0.2em;
+  text-decoration: none;
+}
+
+.sideBarText {
+  line-height: 1.5em;
+  margin: 0 0 1em 0;
+  padding: 0 1.5ex 0 2.5mm;
+  display: block;
+}
+
+#side-bar .sideBarText a {
+  margin: 0;
+  padding: 0;
+  display: inline;
+}
+
+#side-bar .sideBarText a:hover {
+  color: gray;
+  background-color: transparent;
+  text-decoration: none;
+}
+
+
+/* # Main Copy # */
+#main-copy {
+  max-width: 70em;
+  color: black;
+  background-color: transparent;
+  text-align: justify;
+  line-height: 1.5em;
+  margin: 0em 0 0 16em;
+  padding: 0.5mm 5mm 5mm 5mm;
+  border-left: 1px solid white;
+}
+
+#bodyText {
+  margin: 0 0 0 15.5em;
+  padding: 2mm 5mm 2mm 5mm;
+}
+
+#main-copy p {
+  margin: 1em 1ex 1em 1ex !important; /* Need !important so troff-generated pages don't look totally squezed */
+  padding: 0;
+}
+
+#main-copy a {
+  color: gray;
+  background-color: transparent;
+}
+
+#main-copy a:hover {
+  color:  gray;
+}
+
+#main-copy h1, #main-copy h2 {
+  color: gray;
+  background-color: transparent;
+  font-size: 145.5%;
+  font-weight: bold;
+  margin: 2em 0 0 0;
+  padding: 0.5ex 0 0.5ex 0.6ex;
+  border-bottom: 2px solid gray;
+}
+
+#main-copy h2 {
+  font-size: 115.5%;
+  border-bottom: 1px solid gray;
+}
+
+#main-copy .topOfPage {
+  color: gray;
+  background-color: transparent;
+  font-size: 91%;
+  font-weight: bold;
+  text-decoration: none;
+  margin: 3ex 1ex 0 0;
+  padding: 0;
+  float: right;
+}
+
+#post {
+	position: relative;
+	left: 23%;
+	width: 76%;
+	padding-top: 25px;
+	padding-bottom: 25px;
+}
+
+#post tr { background-color: transparent; }
+
+#center {
+	position: absolute;
+	top: 210px;
+	left: 1%;
+	width: 65%;
+	height: 100%;
+}
+#center h1 { font-size 8pt; font-family :'Lucida Sans Unicode','Lucida Sans', 'Trebuchet MS', 'Lucida Grande', 'Bitstream Sans Vera', Verdana, Arial, Tahoma, Helvetica, Sans-Serif; }
+
+a { text-decoration: none; color: #000000; }
+a:hover { color: #111;}
+li:hover { color: #111 }
+li a { color: #000000 }
+li a:hover { color: #111; }
+ul { list-style: none; padding-left: 0px; margin: 0px }
+
+h1 { font-size: 8pt; font-weight: normal; }
+h2 { font-size : 140%; }
+h3 { font-size: 120%; }
+h4 { font-size: 100%; }
+h2, h3, h1, h4 {
+	font-family: Georgia,'Trebuchet MS', 'Lucida Sans',  'Lucida Grande', 'Bitstream Sans Vera', Verdana, Arial, Tahoma, Helvetica, Sans-Serif;
+	color : #000000; 
+	margin: 0px 0px;
+	padding: 2px 0px;
+	clear: both;
+}
+
+input , textarea, select, option { background-color: #eee; border: none; }
+
+dl {
+  margin: 1em 1ex 2em 1ex;
+  padding: 0;
+}
+
+dt {
+  font-weight: bold;
+  margin: 0 0 0 0;
+  padding: 0;
+}
+
+dd {
+  margin: 0 0 2em 2em;
+  padding: 0;
+}
+
+#right {
+	float: right;
+	position: absolute;
+	top: 210px;
+	right: 1px;
+	width: 34%;
+	height: 100%;
+	list-style: none;
+}
+
+/* sidebar */
+#sidebar {
+	position: relative;
+	z-index: 100;
+	width: 95%;
+	top: 10px;
+	right: 10px;
+	left: 10px;
+	margin: 2px;
+	background: #FFFFFF;
+}
+#sidebar h2 {
+	margin: 5px 0px 0px;
+	padding: 4px 0px;
+	font-size:100%;
+}
+#sidebar li { font-size: 8.5pt; }
+#sidebar ul { margin: 2px; }
+
+/*searchform*/
+#searchform label { font-weight:bold; }
+#searchform input { width: 20%; }
+#searchform input.submit { width: 16%; }
+
+#top {
+	float: top;
+	position: absolute;
+	top: 0px;
+	left: 0px;
+	right: 0px;
+	height: 10%;
+	width: 100%
+	overflow: auto;
+}
+
+
+/* # Footer # */
+#footer {
+  font-size: 8pt;
+  background-color: white;
+  color: black;
+}
+#footer a { color: gray; text-decoration: none; }
+#footer a:hover { color: #111; text-decoration: none; }
+#footer table {  font-size: 8pt; }
+
+#footer .left {
+  text-align: left;
+  line-height: 1.55em;
+  float: left;
+  clear: left;
+}
+
+#footer .right {
+  text-align: right;
+  line-height: 1.45em;
+}
+
+/* GENERAL */
+
+table {
+  background-color: transparent;
+  border: none;
+}
+tr {
+  background-color: transparent;
+  border: none;
+}
+th {
+  background-color: transparent;
+  border: none;
+  text-align: center;
+}
+td {
+  background-color: transparent;
+  border: none;
+}
+
+hr {
+  border-width: 0px 0px 0.1em 0px;
+  border-color: transparent;
+}
+
+acronym, .titleTip {
+  border-bottom: 1px solid #ddd;
+  cursor: help;
+  margin: 0;
+  padding: 0 0 0.4px 0;
+}
+
+pre {
+  margin-left: 2em; 
+  font-size: 1.2em;
+}
+
+blockquote {
+  border-left: none;
+  font-style: none;
+  background-color: silver;
+}
+
+.smallCaps {
+  font-size: 110%;
+  font-variant: small-caps;
+}
+
+.doNotDisplay { display: none; }
+
+
+.notify_errors,
+.notify_notes,
+.notify_success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; }
+ 
+.notify_errors { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; }
+.notify_notes { background: #FFF6BF; color: #514721; border-color: #FFD324; }
+.notify_success { background: #E6EFC2; color: #264409; border-color: #C6D880; }
+.notify_errors a { color: #8a1f11; }
+.notify_notes a { color: #514721; }
+.notify_success a { color: #264409; }
+
+
+/* # Page/Handler specific # */
+h1.dir-list-head, ul.dir-list {
+  text-transform: capitalize;
+  font-weight: bold;
+}
+ul.sitemap-list a {
+  text-transform: capitalize;
+}
--- /dev/null
+++ b/pub/massivefictions.css
@@ -1,0 +1,62 @@
+/* mf */
+body {
+	color: #a6a6a6;
+	background-color: #626060;
+	font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
+	font-size: 84%;  /* Enables font size scaling in MSIE */
+	margin: 0;
+	padding: 0;
+}
+a { text-decoration: none; color: #a6a6a6; }
+a:hover { background-color: #a6a6a6; color: #626060; text-decoration: none; }
+a img { display: block; border: 0 none; }
+li:hover { background-color: #a6a6a6; color: #626060; text-decoration: none; }
+li a { color: #a6a6a6 }
+li a:hover { background-color: #a6a6a6; color: #626060; text-decoration: none; }
+li ul { padding-left: 0.6em !important; }
+h1 { font-size: 10pt; font-weight: normal; }
+h2 { font-size: 9pt; font-weight: normal; }
+input , textarea, select, option { background-color: #a6a6a6; border: none; }
+table { border: none; background-color: transparent; }
+th {
+	background-color: transparent;
+	border: none;
+	 text-align: center;
+}
+tr:nth-child(odd) { background-color: transparent; }
+td {
+	background-color: transparent;
+	border: none;
+}
+hr {
+	border-width: 0px 0px 0.1em 0px;
+	border-color: transparent;
+}
+pre, code, blockquote {
+	font-family: Courier, 'Lucida Console','Courier New', Serif;
+	margin-left: 2em; 
+	font-size: 1.2em;
+}
+blockquote {
+	border-left: none;
+	font-style: none;
+	background-color: #a6a6a6;
+}
+#header {
+	margin-left: auto;
+	margin-right: auto;
+}
+#center {
+	width: 500px;
+	margin-left: auto;
+	margin-right: auto;
+}
+#center h1 { font-size 9pt; }
+#footer {
+	font-size: 8pt;
+	background-color: #626060;
+	color: #a6a6a6;
+}
+#footer a { color: #a6a6a6; text-decoration: none; }
+#footer a:hover { color: #626060; text-decoration: none; }
+#footer table {  font-size: 8pt; }
--- /dev/null
+++ b/pub/okturing.css
@@ -1,0 +1,58 @@
+/* okturing.com */
+body { display: flex; flex-wrap: wrap; font-family: sans; }
+header { flex-basis: 100%; flex-shrink: 0; }
+article { flex-basis: 100%; padding: 1em; }
+footer { flex-basis: 100%; flex-shrink: 0; }
+header nav { display: flex; justify-content: space-between; }
+nav a, header a { text-decoration: none ; color: inherit; }
+header h1 span { margin-left: 1em; font-size: 50%; font-style: italic; }
+body > nav { flex-basis: content; padding-right: 1vw; min-width: 16em; }
+nav ul { display: flex; flex-direction: column; list-style-type: none; list-style-position: outside; padding-left: 0;  }
+nav li ul { padding-left: 0.6em }
+footer { display: flex; justify-content: space-between; }
+
+/* cut here to leave vanity behind */
+
+body { margin:0; padding: 0; font-size: 84%; font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif; background-color: #FFFFFF; color: #000000; }
+a:hover { text-decoration: none; background-color: #FFFFFF; color: #000000; }
+
+/* header and top bar */
+header nav { background-color: #FFFFFF; color: #000000; padding: 0em; border-bottom: 2px solid #FFFFFF; font-size: 91%; }
+header h1 { background-color: #FFFFFF; color: #000000; margin: 0; border-bottom: 2px solid #FFFFFF; font-weight: normal; padding: 0.25ex; font-size: 233%; }
+
+/* sidebar */
+body > nav { border-right: 1px solid #FFFFFF; padding: 0;  } 
+body > nav > div { border-bottom: 1px solid #FFFFFF; } 
+body > nav > div a { background-color: #00ff00; color: #000000; display: block; text-transform: capitalize; font-weight: bold; padding: 0.25em 1ex 0.25em 2mm; font-size: 102%} 
+body > nav > div a:hover { color: #FFFFFF; background-color: #000000 border-left: #FFFFFF solid 0.2em; text-decoration: none; }
+body > nav > div p { font-weight: bold; margin: 0 0 0.5em 2mm; padding: 1em 0 0 0; }
+
+/* main copy */
+article { padding: 1em;  }
+article h1, article h2 { color: #000000; font-weight: bold; margin: 2em 0 0 0; border-bottom: 2px solid #FFFFFF; }
+article h3, article h4, article h5 { #000000; font-weight: bold; margin: 2em 0 0 0; }
+article h6, article h7, article h8 { color: #000000; font-weight: bold; margin: 2em 0 0 0; }
+article a { background-color: #FFFFFF; color: #000000; text-decoration: none; }
+article a:hover { text-decoration: none; background-color: #000000; color: #FFFFFF; }
+article a img { display: block; border: 0 none; }
+
+/* footer */
+footer { color: #000000; background-color: #FFFFFF; }
+footer a { background-color: #FFFFFF; color: #000000; }
+footer div { padding: 1em; }
+
+input, textarea, select, option {
+	font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
+	font-size:100%;
+	padding: 2px;
+	background : #eee;
+	color : #111; 
+	border: 1px solid #fff;
+	margin: 2px;
+}
+
+pre, code, blockquote {
+	white-space: pre-wrap;
+	padding-left: 2em;
+	font-family: Courier, 'Lucida Console','Courier New', Serif;
+}
--- /dev/null
+++ b/pub/osx.css
@@ -1,0 +1,345 @@
+/* osx.stanleylieber.com */
+
+body {
+font-family :Helvetica, Verdana, Arial, Sans-Serif;
+font-style : normal;
+padding: 2px 2em;
+line-height: 1.5em;
+font-size: 70%;
+background: #FFF;
+color: #111;
+}
+
+/* font styles */
+a { text-decoration: none; color: #000000; }
+a:hover { background: #7600FC; color: #fff; }
+li:hover { color: #000000; }
+li a { color: #000000; }
+li a:hover { background: #7600FC; color: #fff; }
+ul { list-style: none; padding-left: 0px; margin: 0px }
+p {
+font-size : 100%; 
+font-style : normal; 
+padding: 0px;
+} 
+h2 {
+font-size : 140%; 
+}
+h3 {
+font-size: 120%;
+}
+h4 {
+font-size: 100%;
+}
+h2, h3, h1, h4 {
+font-family: Helvetica, Verdana, Arial, Sans-Serif;
+color : #000000; 
+margin: 0px 0px;
+padding: 2px 0px;
+clear: both;
+}
+/* end font styles */
+
+hr {
+border: 1px solid #fff;
+} 
+
+blockquote, code {
+background : #eee;
+padding: 6px;
+border-left: 3px solid #eee;
+}
+
+code, pre {
+font-family: Courier, 'Lucida Console','Courier New', Sans-Serif;
+}
+
+#admin_banner {
+position: relative;
+text-align: center;
+}
+
+#admin_body {
+position: relative;
+top: 100px;
+left: 10px;
+width: 90%;
+}
+
+#admin_frames {
+height: 100%;
+float: top;
+
+/* for ie */
+margin: 0; 
+overflow: auto;
+/* end for ie */
+
+}
+
+#admin_index_body {
+position: relative;
+top: 100px;
+margin-left: auto;
+margin-right: auto;
+}
+
+
+#admin_menu {
+position: relative;
+left: 10px;
+width: 90%;
+text-align: left;
+}
+
+#admin_table {
+margin-left: auto;
+margin-right: auto;
+width: 90%;
+border-collapse: collapse;
+border-color: #111;
+font-family: sans-serif;
+font-size: 9pt;
+}
+
+#admin_table td {
+vertical-align: middle;
+text-align: center;
+}
+
+#admin_table th {
+background: #111;
+color: gray;
+}
+
+#bottom { 
+float: bottom;
+position: absolute;
+bottom: 10px;
+}
+
+#button input.submit {
+background: #111;
+color: gray;
+border-top: solid 1px #111;
+border-bottom: solid 1px #111;
+border-left: solid 1px #111;
+border-right: solid 1px #111;
+width: 15%;
+}
+
+#center {
+position: absolute;
+top: 155px;
+left: 1%;
+width: 65%;
+height: 100%;
+}
+
+#divider {
+background: #111;
+height: 1px;
+}
+
+/*forms*/
+input , textarea, select, option {
+font-family : Helvetica, Verdana, Arial, Sans-Serif; 
+font-size:100%;
+padding: 2px;
+background : #eee;
+color : #111; 
+border: 1px solid #fff;
+margin: 2px;
+}
+fieldset, legend {
+background:transparent;
+color : #111; 
+border: none;
+padding: 5px;
+}
+label, legend {
+font-weight:normal;
+}
+
+#header {
+float: top;
+position: absolute;
+top: 0px;
+left: 17%;
+height: 100%;
+font-size: 24pt;
+background: #7600FC;
+height: 50px;
+}
+
+#header a {
+background: #7600FC;
+color: #fff;
+}
+
+#left {
+float: left;
+position: absolute;
+top: 0px;
+left: 10%;
+width: 15%;
+height: 100%;
+list-style: none;
+overflow: auto;
+}
+
+#meta {
+font-size: 8pt;
+}
+
+#page_frames {
+width: 100%;
+float: left;
+
+/* for ie */
+margin: 0; 
+overflow: auto;
+/* end for ie */
+
+}
+
+#page_category {
+position: relative;
+text-align: center;
+}
+
+#page_list {
+text-align: right;
+font-size: 9pt;
+}
+
+#page_login {
+position: relative;
+text-align: right;
+font-size: 8pt;
+}
+
+#page_upload {
+background: #111; color: #444; font-weight: bold
+}
+
+#post {
+position: relative;
+left: 13%;
+width: 86%;
+padding-bottom: 100px;
+}
+
+#post_body {
+position: relative;
+top: 10px;
+bottom: 10px;
+left: 10px;;
+}
+
+#post_date {
+font-size: 8pt;
+}
+
+#post_meta {
+margin-left: 2px;
+color: #111;
+font-size: 8pt;
+}
+
+#post_tags {
+font-size: 8pt;
+}
+
+#post_thumb {
+margin-top: 5px;
+margin-bottom: 5px;
+}
+ 
+#post_title {
+border: 1px;
+line-height: 1.5em;
+}
+
+#post_title a {
+background: red;
+color: #fff;
+}
+
+#post_title a:hover {
+background: #7600FC;
+color: #fff;
+}
+
+#post_title h2 {
+font-weight: 100;
+}
+
+#registration_body {
+left: 10px;
+text-align: left;
+}
+
+#right {
+float: right;
+position: absolute;
+top: 150px;
+right: 1%;
+width: 33%;
+height: 100%;
+list-style: none;
+}
+
+#rss {
+margin-left: auto;
+margin-right: auto;
+text-align: center;
+font-size: 8pt;
+}
+
+/* sidebar */
+#sidebar {
+position: relative;
+z-index: 100;
+width: 90%;
+top: 10px;
+right: 10px;
+left: 10px;
+margin: 2px;
+background: #FFFFFF;
+}
+#sidebar h2 {
+margin: 5px 0px 0px;
+padding: 4px 0px;
+font-size:100%;
+}
+#sidebar ul {
+margin: 2px;
+}
+
+/*searchform*/
+#searchform label {
+font-weight:bold;
+}
+#searchform input#s {
+width: 40%;
+}
+#searchform input.submit {
+width: 16%;
+}
+
+#top {
+float: top;
+position: absolute;
+top: 0px;
+left: 0px;
+right: 0px;
+height: 10%;
+width: 100%
+overflow: auto;
+}
+
+.warning {
+color: #111;
+font-weight: bold;
+}
--- /dev/null
+++ b/pub/other.css
@@ -1,0 +1,67 @@
+/* other */
+body {
+	color: blue;
+	background-color: white;
+	font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
+	font-size: 84%;  /* Enables font size scaling in MSIE */
+	margin: 0;
+	padding: 0;
+}
+a { text-decoration: none; color: blue; }
+a:hover { color: purple; background-color: white; text-decoration: none; }
+li:hover { color: purple; background-color: white; text-decoration: none; }
+li a { color: blue; }
+li a:hover { color: purple; background-color: white; text-decoration: none; }
+h1 { font-size: 10pt; font-weight: normal; }
+h2 { font-size: 9pt; font-weight: normal; }
+input , textarea, select, option { background-color: #eee; border: none; }
+li ul {
+	padding-left: 0.6em !important;
+}
+table { border: none; background-color: transparent; }
+th {
+	background-color: transparent;
+	border: none;
+	 text-align: center;
+}
+tr:nth-child(odd) { background-color: transparent; }
+td {
+	background-color: transparent;
+	border: none;
+}
+hr {
+	border-width: 0px 0px 0.1em 0px;
+	border-color: transparent;
+}
+pre, code, blockquote {
+	Courier, 'Lucida Console','Courier New', Serif;
+	margin-left: 2em; 
+	font-size: 1.2em;
+}
+blockquote {
+	border-left: none;
+	font-style: none;
+	background-color: #eee;
+}
+#center {
+	width: 500px;
+	margin-left: auto;
+	margin-right: auto;
+	line-height: 0;
+}
+/* #center p {
+	line-height: 1;
+	-webkit-margin-before: 0px;
+	-webkit-margin-after: 0px;
+} */
+#footer {
+	font-size: 8pt;
+	background-color: white;
+	color: blue;
+	margin-left: auto;
+	margin-right: auto;
+}
+#footer a { color: blue; text-decoration: none; }
+#footer a:hover { color: purple; background-color: white; text-decoration: none; }
+#footer table {  font-size: 8pt; }
+#text { line-height: 1; }
--- /dev/null
+++ b/pub/read.css
@@ -1,0 +1,29 @@
+/* black */
+header { flex-basis: 99%; flex-shrink: 0; padding-left: 1em; padding-bottom: 1em; }
+header h3 { padding-bottom: 2px; }
+header a img { vertical-align: bottom; padding-top: 1em; }
+body { font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; background-color: #000000; color: #FFFFFF; }
+a { text-decoration: none; color: #FFFFFF; background-color: #000000;  font-weight: bold; }
+a:hover { text-decoration: none; background-color: #FFFFFF; color: #000000; }
+/* footer */
+footer > nav { margin-left: auto; padding: 1em; }
+
+/* fixed-width fonts */
+pre, code { white-space: pre-wrap!important; }
+pre, code, blockquote {
+	max-width: 100%!important;
+	font-family: Courier, 'Lucida Console','Courier New', Serif;
+}
+/* input */
+input, textarea, select, option {
+	font-family: Sans-Serif; 
+	font-size: 100%;
+	padding: 2px;
+	border-top: solid 1px #FFFFFF;
+	border-bottom: solid 1px #FFFFFF;
+	border-left: solid 1px #FFFFFF;
+	border-right: solid 1px #FFFFFF;
+	background-color: #000000;
+	color: #FFFFFF;
+	margin: 2px;
+}
--- /dev/null
+++ b/pub/stanleylieber.css
@@ -1,0 +1,64 @@
+/* nothing */
+body {
+	display: flex;
+	flex-wrap: wrap;
+	color: black;
+	background-color: white;
+	font-family: 'Lucida Sans Unicode', 'Lucida Sans', 'Lucida Grande', 'Bitstream Sans Vera', Sans-Serif;
+	font-size: 84%;  /* Enables font size scaling in MSIE */
+	margin: 0;
+	padding: 0;
+}
+header, article, footer { flex-basis: 100%; }
+a { text-decoration: none; color: gray; }
+a:hover { color: #111; text-decoration: none; }
+a img { display: block; border: 0 none; }
+li:hover { color: #111; text-decoration: none; }
+li a { color: gray }
+li a:hover { color: #111; text-decoration: none; }
+li ul { padding-left: 0.6em !important; }
+h1 { font-size: 10pt; font-weight: normal; }
+h2 { font-size: 9pt; font-weight: normal; }
+input , textarea, select, option { background-color: gray; border: none; }
+table { border: none; background-color: transparent; }
+th {
+	background-color: transparent;
+	border: none;
+	 text-align: center;
+}
+tr:nth-child(odd) { background-color: transparent; }
+td {
+	background-color: transparent;
+	border: none;
+}
+
+hr {
+	border-width: 0px 0px 0.1em 0px;
+	border-color: transparent;
+}
+pre, code, blockquote {
+	font-family: Courier, 'Lucida Console','Courier New', Serif;
+	margin-left: 2em; 
+	font-size: 1.2em;
+}
+blockquote {
+	border-left: none;
+	font-style: none;
+	background-color: gray;
+}
+#center {
+	width: 500px;
+	margin-left: auto;
+	margin-right: auto;
+}
+#center h1 { font-size 9pt; }
+#footer {
+	font-size: 8pt;
+	background-color: white;
+	color: gray;
+	margin-left: auto;
+	margin-right: auto;
+}
+#footer a { color: gray; text-decoration: none; }
+#footer a:hover { color: #111; text-decoration: none; }
+#footer table {  font-size: 8pt; }
--- /dev/null
+++ b/pub/url.css
@@ -1,0 +1,195 @@
+/* url.stanleylieber.com */
+
+body {
+	font-family: Vera, Helvetica, Verdana, Arial, Sans-Serif;
+	font-style: normal;
+	padding: 2px 2em;
+	line-height: 1.5em;
+	font-size: 70%;
+	background: #FFFFFF;
+	color: #000000;
+}
+
+a { text-decoration: none; color: #000000; }
+a:hover { background: #EEEEEE;}
+li:hover { background: #EEEEEE; }
+li a:hover { background: #EEEEEE; }
+ul { list-style: none; }
+
+p {
+	font-size : 100%; 
+	font-style : normal; 
+	padding: 0px;
+} 
+
+h2 { font-size : 140%; }
+h3 { font-size: 120%; }
+h4 { font-size: 100%; }
+h2, h3, h1, h4 {
+	margin: 0px 0px;
+	padding: 2px 0px;
+	clear: both;
+}
+
+hr { border: 1px solid #fff; }
+
+input {
+	background-color: #EEEEEE;
+}
+
+code, pre { font-family: Courier, 'Lucida Console','Courier New', Sans-Serif; }
+blockquote, code {
+	background : #eee;
+	padding: 6px;
+	border-left: 3px solid #eee;
+}
+
+td {
+	padding: 10px;
+	border-width: 1px;
+	border-style: solid;
+	border-collapse: collapse;
+	border-color: #000000;
+	background: #FFFFFF;
+}
+
+textarea {
+	height: 300px;
+	background-color: #EEEEEE;
+}
+
+tr {
+	border-width: 1px;
+	border-style: solid;
+	border-collapse: collapse;
+	border-color: #000000;
+}
+
+#add {
+	position: relative;
+	top: 65px;
+	left: 9%;
+	font-size: 10pt;
+}
+
+#blank {
+	border-width: 1px;
+	border-style: solid;
+	border-collapse: collapse;
+	border-color: #FFFFFF;
+}
+
+#bottom { 
+	float: bottom;
+	position: absolute;
+	bottom: 0px;
+	left: 0px;
+	right: 0px;
+	width: 100%;
+}
+
+#center {
+	position: relative;
+	margin-left: auto;
+	margin-right: auto;
+	top: 130px;
+	width: 90%;
+	height: 100%;
+}
+
+#edit {
+	width: 750px;
+	font-size: 10pt;
+}
+
+#footer {
+	position: relative;
+	margin-left: auto;
+	margin-right: auto;
+	bottom: 100px;
+}
+
+#header {
+	position: relative;
+	margin-left: auto;
+	margin-right: auto;
+	top: 40px;
+	width: 83%;
+}
+
+#logo { font-size: 40pt; color: #DDDDDD; }
+#logo a { font-size: 40pt; color: #CCCCCC; }
+#logo a:hover { background: #EEEEEE;}
+
+#list {
+	position: relative;
+	margin-left: auto;
+	margin-right: auto;
+	top: 90px;
+	width: 90%;
+	height: 100%;
+}
+
+#meta { font-size: 8pt; }
+
+#page_list {
+	margin: 20px;
+	text-align: right;
+	font-size: 9pt;
+}
+
+#post {
+	position: relative;
+	padding: 20px;
+}
+
+#post_meta { text-align: center; }
+
+#post_date {
+	width: 200px;
+	text-align: center;
+	font-size: 8pt;
+}
+
+#post_edit {
+	width: 100px;
+	text-align: center;
+	font-size: 8pt;
+}
+
+#post_table {
+	position: relative;
+	margin-left: auto;
+	margin-right: auto;
+	padding: 0px;
+	width: 100%;
+	border-collapse: collapse;
+}
+
+#post_tags {
+	text-align: left;
+	font-size: 8pt;
+}
+
+#post_title {
+	text-align: left;
+	font-size: 10pt;
+}
+
+#search {
+	position: absolute;
+	top: 90px;
+	right: 9%;
+	font-size: 10pt;
+}
+
+#top {
+	float: top;
+	position: absolute;
+	top: 0px;
+	left: 0px;
+	right: 0px;
+	height: 100px;
+	width: 100%;
+}
+
--- /dev/null
+++ b/src/1/body
@@ -1,0 +1,1 @@
+Trust, but verify.
--- /dev/null
+++ b/src/1/date
@@ -1,0 +1,1 @@
+Thu Aug 25 18:35:52 CDT 2011
--- /dev/null
+++ b/src/1/link
@@ -1,0 +1,1 @@
+http://plan9.stanleylieber.com/9front
--- /dev/null
+++ b/src/1/title
@@ -1,0 +1,1 @@
+This is a BULGE demo post.
--- /dev/null
+++ b/tags
@@ -1,0 +1,3 @@
+1/tags/theory
+1/tags/random
+1/tags/demo